workspaces: add config option for initial workspace selection
Some checks failed
labwc.github.io / notify (push) Has been cancelled

This commit is contained in:
Cameron Scott McCreery 2025-12-22 16:17:43 -05:00 committed by GitHub
parent c9b088e343
commit 64aec6ff5d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 64 additions and 29 deletions

View file

@ -575,6 +575,11 @@ extending outward from the snapped edge.
is 1. The number attribute is optional. If the number attribute is is 1. The number attribute is optional. If the number attribute is
specified, names.name is not required. specified, names.name is not required.
*<desktops><initial>*
Define the initial starting workspace. This must match one of the names
defined in <names> or must be an index equal to or lower than <number>.
If not set, the first workspace is used.
*<desktops><popupTime>* *<desktops><popupTime>*
Define the timeout after which to hide the workspace OSD. Define the timeout after which to hide the workspace OSD.
A setting of 0 disables the OSD. Default is 1000 ms. A setting of 0 disables the OSD. Default is 1000 ms.

View file

@ -175,6 +175,7 @@
Workspaces can be configured like this: Workspaces can be configured like this:
<desktops> <desktops>
<popupTime>1000</popupTime> <popupTime>1000</popupTime>
<initial>Workspace 1</initial>
<names> <names>
<name>Workspace 1</name> <name>Workspace 1</name>
<name>Workspace 2</name> <name>Workspace 2</name>

View file

@ -168,6 +168,7 @@ struct rcxml {
struct { struct {
int popuptime; int popuptime;
int min_nr_workspaces; int min_nr_workspaces;
char *initial_workspace_name;
char *prefix; char *prefix;
struct wl_list workspaces; /* struct workspace.link */ struct wl_list workspaces; /* struct workspace.link */
} workspace_config; } workspace_config;

View file

@ -1308,6 +1308,8 @@ entry(xmlNode *node, char *nodename, char *content)
wl_list_append(&rc.workspace_config.workspaces, &workspace->link); wl_list_append(&rc.workspace_config.workspaces, &workspace->link);
} else if (!strcasecmp(nodename, "popupTime.desktops")) { } else if (!strcasecmp(nodename, "popupTime.desktops")) {
rc.workspace_config.popuptime = atoi(content); rc.workspace_config.popuptime = atoi(content);
} else if (!strcasecmp(nodename, "initial.desktops")) {
xstrdup_replace(rc.workspace_config.initial_workspace_name, content);
} else if (!strcasecmp(nodename, "number.desktops")) { } else if (!strcasecmp(nodename, "number.desktops")) {
rc.workspace_config.min_nr_workspaces = MAX(1, atoi(content)); rc.workspace_config.min_nr_workspaces = MAX(1, atoi(content));
} else if (!strcasecmp(nodename, "popupShow.resize")) { } else if (!strcasecmp(nodename, "popupShow.resize")) {
@ -1963,6 +1965,7 @@ rcxml_finish(void)
zfree(rc.icon_theme_name); zfree(rc.icon_theme_name);
zfree(rc.fallback_app_icon_name); zfree(rc.fallback_app_icon_name);
zfree(rc.workspace_config.prefix); zfree(rc.workspace_config.prefix);
zfree(rc.workspace_config.initial_workspace_name);
zfree(rc.tablet.output_name); zfree(rc.tablet.output_name);
zfree(rc.window_switcher.osd.thumbnail_label_format); zfree(rc.window_switcher.osd.thumbnail_label_format);

View file

@ -182,6 +182,33 @@ _osd_update(struct server *server)
} }
} }
static struct workspace *
workspace_find_by_name(struct server *server, const char *name)
{
struct workspace *workspace;
/* by index */
size_t parsed_index = parse_workspace_index(name);
if (parsed_index) {
size_t index = 0;
wl_list_for_each(workspace, &server->workspaces.all, link) {
if (parsed_index == ++index) {
return workspace;
}
}
}
/* by name */
wl_list_for_each(workspace, &server->workspaces.all, link) {
if (!strcmp(workspace->name, name)) {
return workspace;
}
}
wlr_log(WLR_ERROR, "Workspace '%s' not found", name);
return NULL;
}
/* cosmic workspace handlers */ /* cosmic workspace handlers */
static void static void
handle_cosmic_workspace_activate(struct wl_listener *listener, void *data) handle_cosmic_workspace_activate(struct wl_listener *listener, void *data)
@ -209,18 +236,11 @@ add_workspace(struct server *server, const char *name)
workspace->name = xstrdup(name); workspace->name = xstrdup(name);
workspace->tree = wlr_scene_tree_create(server->view_tree); workspace->tree = wlr_scene_tree_create(server->view_tree);
wl_list_append(&server->workspaces.all, &workspace->link); wl_list_append(&server->workspaces.all, &workspace->link);
if (!server->workspaces.current) { wlr_scene_node_set_enabled(&workspace->tree->node, false);
server->workspaces.current = workspace;
} else {
wlr_scene_node_set_enabled(&workspace->tree->node, false);
}
bool active = server->workspaces.current == workspace;
/* cosmic */ /* cosmic */
workspace->cosmic_workspace = lab_cosmic_workspace_create(server->workspaces.cosmic_group); workspace->cosmic_workspace = lab_cosmic_workspace_create(server->workspaces.cosmic_group);
lab_cosmic_workspace_set_name(workspace->cosmic_workspace, name); lab_cosmic_workspace_set_name(workspace->cosmic_workspace, name);
lab_cosmic_workspace_set_active(workspace->cosmic_workspace, active);
workspace->on_cosmic.activate.notify = handle_cosmic_workspace_activate; workspace->on_cosmic.activate.notify = handle_cosmic_workspace_activate;
wl_signal_add(&workspace->cosmic_workspace->events.activate, wl_signal_add(&workspace->cosmic_workspace->events.activate,
@ -231,7 +251,6 @@ add_workspace(struct server *server, const char *name)
server->workspaces.ext_manager, /*id*/ NULL); server->workspaces.ext_manager, /*id*/ NULL);
lab_ext_workspace_assign_to_group(workspace->ext_workspace, server->workspaces.ext_group); lab_ext_workspace_assign_to_group(workspace->ext_workspace, server->workspaces.ext_group);
lab_ext_workspace_set_name(workspace->ext_workspace, name); lab_ext_workspace_set_name(workspace->ext_workspace, name);
lab_ext_workspace_set_active(workspace->ext_workspace, active);
workspace->on_ext.activate.notify = handle_ext_workspace_activate; workspace->on_ext.activate.notify = handle_ext_workspace_activate;
wl_signal_add(&workspace->ext_workspace->events.activate, wl_signal_add(&workspace->ext_workspace->events.activate,
@ -398,6 +417,27 @@ workspaces_init(struct server *server)
wl_list_for_each(conf, &rc.workspace_config.workspaces, link) { wl_list_for_each(conf, &rc.workspace_config.workspaces, link) {
add_workspace(server, conf->name); add_workspace(server, conf->name);
} }
/*
* After adding workspaces, check if there is an initial workspace
* selected and set that as the initial workspace.
*/
char *initial_name = rc.workspace_config.initial_workspace_name;
struct workspace *initial = NULL;
struct workspace *first = wl_container_of(
server->workspaces.all.next, first, link);
if (initial_name) {
initial = workspace_find_by_name(server, initial_name);
}
if (!initial) {
initial = first;
}
server->workspaces.current = initial;
wlr_scene_node_set_enabled(&initial->tree->node, true);
lab_cosmic_workspace_set_active(initial->cosmic_workspace, true);
lab_ext_workspace_set_active(initial->ext_workspace, true);
} }
/* /*
@ -507,21 +547,13 @@ workspaces_find(struct workspace *anchor, const char *name, bool wrap)
if (!name) { if (!name) {
return NULL; return NULL;
} }
size_t index = 0; struct server *server = anchor->server;
struct workspace *target; struct wl_list *workspaces = &server->workspaces.all;
size_t wants_index = parse_workspace_index(name);
struct wl_list *workspaces = &anchor->server->workspaces.all;
if (wants_index) { if (!strcasecmp(name, "current")) {
wl_list_for_each(target, workspaces, link) {
if (wants_index == ++index) {
return target;
}
}
} else if (!strcasecmp(name, "current")) {
return anchor; return anchor;
} else if (!strcasecmp(name, "last")) { } else if (!strcasecmp(name, "last")) {
return anchor->server->workspaces.last; return server->workspaces.last;
} else if (!strcasecmp(name, "left")) { } else if (!strcasecmp(name, "left")) {
return get_prev(anchor, workspaces, wrap); return get_prev(anchor, workspaces, wrap);
} else if (!strcasecmp(name, "right")) { } else if (!strcasecmp(name, "right")) {
@ -530,15 +562,8 @@ workspaces_find(struct workspace *anchor, const char *name, bool wrap)
return get_prev_occupied(anchor, workspaces, wrap); return get_prev_occupied(anchor, workspaces, wrap);
} else if (!strcasecmp(name, "right-occupied")) { } else if (!strcasecmp(name, "right-occupied")) {
return get_next_occupied(anchor, workspaces, wrap); return get_next_occupied(anchor, workspaces, wrap);
} else {
wl_list_for_each(target, workspaces, link) {
if (!strcasecmp(target->name, name)) {
return target;
}
}
} }
wlr_log(WLR_ERROR, "Workspace '%s' not found", name); return workspace_find_by_name(server, name);
return NULL;
} }
static void static void