From 5004f181bf1550e83bcf2a33a6e951109af11985 Mon Sep 17 00:00:00 2001 From: Consolatis <35009135+Consolatis@users.noreply.github.com> Date: Sun, 9 Feb 2025 20:54:12 +0100 Subject: [PATCH] protocols/ext-workspace: use output tracker --- include/protocols/ext-workspace-internal.h | 25 --- src/protocols/ext-workspace/ext-workspace.c | 62 ++++++- src/protocols/ext-workspace/meson.build | 1 - src/protocols/ext-workspace/output.c | 174 -------------------- 4 files changed, 58 insertions(+), 204 deletions(-) delete mode 100644 include/protocols/ext-workspace-internal.h delete mode 100644 src/protocols/ext-workspace/output.c diff --git a/include/protocols/ext-workspace-internal.h b/include/protocols/ext-workspace-internal.h deleted file mode 100644 index c5e7575f..00000000 --- a/include/protocols/ext-workspace-internal.h +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef LABWC_PROTOCOLS_EXT_WORKSPACES_INTERNAL_H -#define LABWC_PROTOCOLS_EXT_WORKSPACES_INTERNAL_H - -struct wl_resource; -struct lab_ext_workspace_group; -struct lab_ext_workspace_manager; - -enum pending_ext_workspaces_change { - /* group events */ - WS_PENDING_WS_CREATE = 1 << 0, - - /* ws events*/ - WS_PENDING_WS_ACTIVATE = 1 << 1, - WS_PENDING_WS_DEACTIVATE = 1 << 2, - WS_PENDING_WS_REMOVE = 1 << 3, - WS_PENDING_WS_ASSIGN = 1 << 4, -}; - -void ext_group_output_send_initial_state(struct lab_ext_workspace_group *group, - struct wl_resource *group_resource); - -void ext_manager_schedule_done_event(struct lab_ext_workspace_manager *manager); - -#endif /* LABWC_PROTOCOLS_EXT_WORKSPACES_INTERNAL_H */ diff --git a/src/protocols/ext-workspace/ext-workspace.c b/src/protocols/ext-workspace/ext-workspace.c index 92032375..03858c78 100644 --- a/src/protocols/ext-workspace/ext-workspace.c +++ b/src/protocols/ext-workspace/ext-workspace.c @@ -7,7 +7,7 @@ #include "common/list.h" #include "ext-workspace-v1-protocol.h" #include "protocols/ext-workspace.h" -#include "protocols/ext-workspace-internal.h" +#include "protocols/output-tracker.h" #include "protocols/transaction-addon.h" /* @@ -32,6 +32,17 @@ */ #define WS_STATE_INVALID 0xffffffff +enum pending_ext_workspaces_change { + /* group events */ + WS_PENDING_WS_CREATE = 1 << 0, + + /* ws events*/ + WS_PENDING_WS_ACTIVATE = 1 << 1, + WS_PENDING_WS_DEACTIVATE = 1 << 2, + WS_PENDING_WS_REMOVE = 1 << 3, + WS_PENDING_WS_ASSIGN = 1 << 4, +}; + struct ws_create_workspace_event { char *name; struct { @@ -39,6 +50,8 @@ struct ws_create_workspace_event { } on; }; +static void ext_manager_schedule_done_event(struct lab_ext_workspace_manager *manager); + /* Workspace */ static void workspace_handle_destroy(struct wl_client *client, struct wl_resource *resource) @@ -278,7 +291,7 @@ group_send_state(struct lab_ext_workspace_group *group, struct wl_resource *reso ext_workspace_group_handle_v1_send_capabilities( resource, group->capabilities); - ext_group_output_send_initial_state(group, resource); + output_tracker_send_initial_state_to_resource(group, resource); } /* Manager itself */ @@ -453,8 +466,7 @@ manager_idle_send_done(void *data) manager->idle_source = NULL; } -/* Internal API */ -void +static void ext_manager_schedule_done_event(struct lab_ext_workspace_manager *manager) { if (manager->idle_source) { @@ -467,6 +479,31 @@ ext_manager_schedule_done_event(struct lab_ext_workspace_manager *manager) manager->event_loop, manager_idle_send_done, manager); } +/* Output tracker */ +static void +handle_output_tracker_send_done(void *object, struct wl_client *client) +{ + struct lab_ext_workspace_group *group = object; + if (!client) { + ext_manager_schedule_done_event(group->manager); + return; + } + + struct wl_resource *manager_resource; + struct wl_list *manager_resources = &group->manager->resources; + wl_resource_for_each(manager_resource, manager_resources) { + if (wl_resource_get_client(manager_resource) == client) { + ext_workspace_manager_v1_send_done(manager_resource); + } + } +} + +static const struct output_tracker_impl output_tracker_impl = { + .send_output_enter = ext_workspace_group_handle_v1_send_output_enter, + .send_output_leave = ext_workspace_group_handle_v1_send_output_leave, + .send_done = handle_output_tracker_send_done, +}; + static void send_group_workspace_event(struct lab_ext_workspace_group *group, struct lab_ext_workspace *workspace, @@ -546,12 +583,29 @@ lab_ext_workspace_group_create(struct lab_ext_workspace_manager *manager) return group; } +void +lab_ext_workspace_group_output_enter(struct lab_ext_workspace_group *group, + struct wlr_output *wlr_output) +{ + output_tracker_enter(group, &group->resources, wlr_output, &output_tracker_impl); +} + +void +lab_ext_workspace_group_output_leave(struct lab_ext_workspace_group *group, + struct wlr_output *wlr_output) +{ + output_tracker_leave(group, wlr_output); +} + void lab_ext_workspace_group_destroy(struct lab_ext_workspace_group *group) { assert(group); wl_signal_emit_mutable(&group->events.destroy, NULL); + /* Ensure output leave events are sent and tracker resources are destroyed */ + output_tracker_destroy(group); + struct lab_ext_workspace *workspace; wl_list_for_each(workspace, &group->manager->workspaces, link) { if (workspace->group == group) { diff --git a/src/protocols/ext-workspace/meson.build b/src/protocols/ext-workspace/meson.build index e781d13a..b21a17c3 100644 --- a/src/protocols/ext-workspace/meson.build +++ b/src/protocols/ext-workspace/meson.build @@ -1,4 +1,3 @@ labwc_sources += files( 'ext-workspace.c', - 'output.c', ) diff --git a/src/protocols/ext-workspace/output.c b/src/protocols/ext-workspace/output.c deleted file mode 100644 index 0d6a2a44..00000000 --- a/src/protocols/ext-workspace/output.c +++ /dev/null @@ -1,174 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -#include -#include -#include -#include "common/mem.h" -#include "ext-workspace-v1-protocol.h" -#include "protocols/ext-workspace.h" -#include "protocols/ext-workspace-internal.h" - -struct group_output { - struct wlr_output *wlr_output; - struct lab_ext_workspace_group *group; - struct { - struct wl_listener group_destroy; - struct wl_listener output_bind; - struct wl_listener output_destroy; - } on; - - struct wl_list link; -}; - -/* Internal helpers */ -static void -group_output_send_event(struct wl_list *group_resources, struct wl_list *output_resources, - void (*notifier)(struct wl_resource *group, struct wl_resource *output)) -{ - struct wl_client *client; - struct wl_resource *group_resource, *output_resource; - wl_resource_for_each(group_resource, group_resources) { - client = wl_resource_get_client(group_resource); - wl_resource_for_each(output_resource, output_resources) { - if (wl_resource_get_client(output_resource) == client) { - notifier(group_resource, output_resource); - } - } - } -} - -static void -group_output_destroy(struct group_output *group_output) -{ - group_output_send_event( - &group_output->group->resources, - &group_output->wlr_output->resources, - ext_workspace_group_handle_v1_send_output_leave); - - ext_manager_schedule_done_event(group_output->group->manager); - - wl_list_remove(&group_output->link); - wl_list_remove(&group_output->on.group_destroy.link); - wl_list_remove(&group_output->on.output_bind.link); - wl_list_remove(&group_output->on.output_destroy.link); - free(group_output); -} - -/* Event handlers */ -static void -handle_output_bind(struct wl_listener *listener, void *data) -{ - struct group_output *group_output = - wl_container_of(listener, group_output, on.output_bind); - - struct wlr_output_event_bind *event = data; - struct wl_client *client = wl_resource_get_client(event->resource); - - bool sent = false; - struct wl_resource *group_resource; - wl_resource_for_each(group_resource, &group_output->group->resources) { - if (wl_resource_get_client(group_resource) == client) { - ext_workspace_group_handle_v1_send_output_enter( - group_resource, event->resource); - sent = true; - } - } - if (!sent) { - return; - } - - struct wl_resource *manager_resource; - struct wl_list *manager_resources = &group_output->group->manager->resources; - wl_resource_for_each(manager_resource, manager_resources) { - if (wl_resource_get_client(manager_resource) == client) { - ext_workspace_manager_v1_send_done(manager_resource); - } - } -} - -static void -handle_output_destroy(struct wl_listener *listener, void *data) -{ - struct group_output *group_output = - wl_container_of(listener, group_output, on.output_destroy); - group_output_destroy(group_output); -} - -static void -handle_group_destroy(struct wl_listener *listener, void *data) -{ - struct group_output *group_output = - wl_container_of(listener, group_output, on.group_destroy); - group_output_destroy(group_output); -} - -/* Internal API*/ -void -ext_group_output_send_initial_state(struct lab_ext_workspace_group *group, - struct wl_resource *group_resource) -{ - struct group_output *group_output; - struct wl_resource *output_resource; - struct wl_client *client = wl_resource_get_client(group_resource); - wl_list_for_each(group_output, &group->outputs, link) { - wl_resource_for_each(output_resource, &group_output->wlr_output->resources) { - if (wl_resource_get_client(output_resource) == client) { - ext_workspace_group_handle_v1_send_output_enter( - group_resource, output_resource); - } - } - } -} - -/* Public API */ -void -lab_ext_workspace_group_output_enter(struct lab_ext_workspace_group *group, - struct wlr_output *wlr_output) -{ - struct group_output *group_output; - wl_list_for_each(group_output, &group->outputs, link) { - if (group_output->wlr_output == wlr_output) { - return; - } - } - group_output = znew(*group_output); - group_output->wlr_output = wlr_output; - group_output->group = group; - - group_output->on.group_destroy.notify = handle_group_destroy; - wl_signal_add(&group->events.destroy, &group_output->on.group_destroy); - - group_output->on.output_bind.notify = handle_output_bind; - wl_signal_add(&wlr_output->events.bind, &group_output->on.output_bind); - - group_output->on.output_destroy.notify = handle_output_destroy; - wl_signal_add(&wlr_output->events.destroy, &group_output->on.output_destroy); - - wl_list_insert(&group->outputs, &group_output->link); - - group_output_send_event( - &group_output->group->resources, - &group_output->wlr_output->resources, - ext_workspace_group_handle_v1_send_output_enter); - - ext_manager_schedule_done_event(group->manager); -} - -void -lab_ext_workspace_group_output_leave(struct lab_ext_workspace_group *group, - struct wlr_output *wlr_output) -{ - struct group_output *tmp; - struct group_output *group_output = NULL; - wl_list_for_each(tmp, &group->outputs, link) { - if (tmp->wlr_output == wlr_output) { - group_output = tmp; - break; - } - } - if (!group_output) { - wlr_log(WLR_ERROR, "output %s was never entered", wlr_output->name); - return; - } - - group_output_destroy(group_output); -}