From 3177667609d8996aac13e7a2553e9b11b4c31c4d Mon Sep 17 00:00:00 2001 From: Maik Broemme Date: Wed, 22 Oct 2025 18:25:45 +0200 Subject: [PATCH] ext-workspace: add workspace_enter/leave notifications --- include/protocols/ext-workspace.h | 9 ++++ src/protocols/ext-workspace/ext-workspace.c | 53 +++++++++++++++++++++ src/workspaces.c | 15 ++++++ 3 files changed, 77 insertions(+) diff --git a/include/protocols/ext-workspace.h b/include/protocols/ext-workspace.h index cc422ac5..72948474 100644 --- a/include/protocols/ext-workspace.h +++ b/include/protocols/ext-workspace.h @@ -106,4 +106,13 @@ void lab_ext_workspace_set_coordinates(struct lab_ext_workspace *workspace, void lab_ext_workspace_destroy(struct lab_ext_workspace *workspace); +/* Notify clients that a workspace has entered/left the currently bound output group. + * This emits workspace_enter/leave for all clients that have both the group and the + * workspace bound, mirroring the initial-state emission. + */ +void lab_ext_workspace_group_workspace_enter(struct lab_ext_workspace_group *group, + struct lab_ext_workspace *workspace); +void lab_ext_workspace_group_workspace_leave(struct lab_ext_workspace_group *group, + struct lab_ext_workspace *workspace); + #endif /* LABWC_PROTOCOLS_EXT_WORKSPACES_H */ diff --git a/src/protocols/ext-workspace/ext-workspace.c b/src/protocols/ext-workspace/ext-workspace.c index 30875811..88537e90 100644 --- a/src/protocols/ext-workspace/ext-workspace.c +++ b/src/protocols/ext-workspace/ext-workspace.c @@ -760,3 +760,56 @@ lab_ext_workspace_destroy(struct lab_ext_workspace *workspace) zfree(workspace->name); free(workspace); } + +void +lab_ext_workspace_group_workspace_enter(struct lab_ext_workspace_group *group, + struct lab_ext_workspace *workspace) +{ + if (!group || !workspace) { + return; + } + + /* Verbose logging for debugging: print workspace name on enter */ + wlr_log(WLR_DEBUG, "ext-workspace: enter name='%s'", workspace->name); + + /* For each manager/group resource pair belonging to the same client, + * emit workspace_enter with the matching workspace resource. + */ + struct wl_resource *group_resource; + wl_resource_for_each(group_resource, &group->resources) { + struct wl_client *client = wl_resource_get_client(group_resource); + struct wl_resource *ws_resource; + wl_resource_for_each(ws_resource, &workspace->resources) { + if (wl_resource_get_client(ws_resource) == client) { + ext_workspace_group_handle_v1_send_workspace_enter( + group_resource, ws_resource); + } + } + } + ext_manager_schedule_done_event(group->manager); +} + +void +lab_ext_workspace_group_workspace_leave(struct lab_ext_workspace_group *group, + struct lab_ext_workspace *workspace) +{ + if (!group || !workspace) { + return; + } + + /* Verbose logging for debugging: print workspace name on leave */ + wlr_log(WLR_DEBUG, "ext-workspace: leave name='%s'", workspace->name); + + struct wl_resource *group_resource; + wl_resource_for_each(group_resource, &group->resources) { + struct wl_client *client = wl_resource_get_client(group_resource); + struct wl_resource *ws_resource; + wl_resource_for_each(ws_resource, &workspace->resources) { + if (wl_resource_get_client(ws_resource) == client) { + ext_workspace_group_handle_v1_send_workspace_leave( + group_resource, ws_resource); + } + } + } + ext_manager_schedule_done_event(group->manager); +} diff --git a/src/workspaces.c b/src/workspaces.c index 43f19b18..ace0ee81 100644 --- a/src/workspaces.c +++ b/src/workspaces.c @@ -237,6 +237,12 @@ add_workspace(struct server *server, const char *name) lab_ext_workspace_set_name(workspace->ext_workspace, name); lab_ext_workspace_set_active(workspace->ext_workspace, active); + /* Notify ext-workspace listeners for active workspace only */ + if (active) { + lab_ext_workspace_group_workspace_enter( + server->workspaces.ext_group, workspace->ext_workspace); + } + workspace->on_ext.activate.notify = handle_ext_workspace_activate; wl_signal_add(&workspace->ext_workspace->events.activate, &workspace->on_ext.activate); @@ -427,6 +433,10 @@ workspaces_switch_to(struct workspace *target, bool update_focus) lab_ext_workspace_set_active( server->workspaces.current->ext_workspace, false); + /* Notify ext-workspace listeners */ + lab_ext_workspace_group_workspace_leave( + server->workspaces.ext_group, server->workspaces.current->ext_workspace); + /* Move Omnipresent views to new workspace */ struct view *view; enum lab_view_criteria criteria = @@ -482,6 +492,11 @@ workspaces_switch_to(struct workspace *target, bool update_focus) desktop_update_top_layer_visibility(server); lab_cosmic_workspace_set_active(target->cosmic_workspace, true); + + /* Notify ext-workspace listeners */ + lab_ext_workspace_group_workspace_enter( + server->workspaces.ext_group, target->ext_workspace); + lab_ext_workspace_set_active(target->ext_workspace, true); }