From 06dd3423a19768b1b33f7a78167b222fa6380ec9 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Sat, 13 Dec 2025 09:50:36 +0800 Subject: [PATCH] opt: optimize ws module --- src/ext-protocol/ext-workspace.h | 4 +- src/ext-protocol/wlr_ext_workspace_v1.c | 478 +++++++++++++----------- src/ext-protocol/wlr_ext_workspace_v1.h | 58 ++- src/mango.c | 1 - 4 files changed, 285 insertions(+), 256 deletions(-) diff --git a/src/ext-protocol/ext-workspace.h b/src/ext-protocol/ext-workspace.h index d4e0e51..8ff53cc 100644 --- a/src/ext-protocol/ext-workspace.h +++ b/src/ext-protocol/ext-workspace.h @@ -1,8 +1,8 @@ #include "wlr_ext_workspace_v1.h" #define EXT_WORKSPACE_ENABLE_CAPS \ - WLR_EXT_WORKSPACE_HANDLE_V1_CAP_ACTIVATE | \ - WLR_EXT_WORKSPACE_HANDLE_V1_CAP_DEACTIVATE + EXT_WORKSPACE_HANDLE_V1_WORKSPACE_CAPABILITIES_ACTIVATE | \ + EXT_WORKSPACE_HANDLE_V1_WORKSPACE_CAPABILITIES_DEACTIVATE typedef struct Monitor Monitor; diff --git a/src/ext-protocol/wlr_ext_workspace_v1.c b/src/ext-protocol/wlr_ext_workspace_v1.c index 3f80e9f..2d781b3 100644 --- a/src/ext-protocol/wlr_ext_workspace_v1.c +++ b/src/ext-protocol/wlr_ext_workspace_v1.c @@ -29,7 +29,7 @@ struct wlr_ext_workspace_v1_request { // ACTIVATE / DEACTIVATE / ASSIGN / REMOVE struct wlr_ext_workspace_handle_v1 *workspace; - struct wl_list link; // wlr_ext_workspace_manager_client_v1.requests + struct wl_list link; // wlr_ext_workspace_manager_v1_resource.requests }; struct wlr_ext_workspace_v1_group_output { @@ -41,33 +41,40 @@ struct wlr_ext_workspace_v1_group_output { }; // These structs wrap wl_resource of each interface to access the request queue -// (wlr_ext_workspace_manager_client_v1.requests) assigned per manager resource +// (wlr_ext_workspace_manager_v1_resource.requests) assigned per manager +// resource -struct wlr_ext_workspace_manager_client_v1 { +struct wlr_ext_workspace_manager_v1_resource { struct wl_resource *resource; struct wlr_ext_workspace_manager_v1 *manager; - struct wl_list requests; // wlr_ext_workspace_v1_request.link - struct wl_list link; // wlr_ext_workspace_manager_v1.clients + struct wl_list requests; // wlr_ext_workspace_v1_request.link + struct wl_list workspace_resources; // wlr_ext_workspace_v1_resource.link + struct wl_list group_resources; // wlr_ext_workspace_group_v1_resource.link + struct wl_list link; // wlr_ext_workspace_manager_v1.resources }; -struct wlr_ext_workspace_group_client_v1 { +struct wlr_ext_workspace_group_v1_resource { struct wl_resource *resource; struct wlr_ext_workspace_group_handle_v1 *group; - struct wlr_ext_workspace_manager_client_v1 *manager; - struct wl_list link; // wlr_ext_workspace_group_v1.clients + struct wlr_ext_workspace_manager_v1_resource *manager; + struct wl_list link; // wlr_ext_workspace_group_v1.resources + struct wl_list + manager_resource_link; // wlr_ext_workspace_manager_v1_resource.group_resources }; -struct wlr_ext_workspace_client_v1 { +struct wlr_ext_workspace_v1_resource { struct wl_resource *resource; struct wlr_ext_workspace_handle_v1 *workspace; - struct wlr_ext_workspace_manager_client_v1 *manager; - struct wl_list link; // wlr_ext_workspace_v1.clients + struct wlr_ext_workspace_manager_v1_resource *manager; + struct wl_list link; // wlr_ext_workspace_v1.resources + struct wl_list + manager_resource_link; // wlr_ext_workspace_manager_v1_resource.workspace_resources }; static const struct ext_workspace_group_handle_v1_interface group_impl; -static struct wlr_ext_workspace_group_client_v1 * -group_client_from_resource(struct wl_resource *resource) { +static struct wlr_ext_workspace_group_v1_resource * +group_resource_from_resource(struct wl_resource *resource) { assert(wl_resource_instance_of( resource, &ext_workspace_group_handle_v1_interface, &group_impl)); return wl_resource_get_user_data(resource); @@ -75,8 +82,8 @@ group_client_from_resource(struct wl_resource *resource) { static const struct ext_workspace_handle_v1_interface workspace_impl; -static struct wlr_ext_workspace_client_v1 * -workspace_client_from_resource(struct wl_resource *resource) { +static struct wlr_ext_workspace_v1_resource * +workspace_resource_from_resource(struct wl_resource *resource) { assert(wl_resource_instance_of(resource, &ext_workspace_handle_v1_interface, &workspace_impl)); return wl_resource_get_user_data(resource); @@ -84,8 +91,8 @@ workspace_client_from_resource(struct wl_resource *resource) { static const struct ext_workspace_manager_v1_interface manager_impl; -static struct wlr_ext_workspace_manager_client_v1 * -manager_client_from_resource(struct wl_resource *resource) { +static struct wlr_ext_workspace_manager_v1_resource * +manager_resource_from_resource(struct wl_resource *resource) { assert(wl_resource_instance_of( resource, &ext_workspace_manager_v1_interface, &manager_impl)); return wl_resource_get_user_data(resource); @@ -98,9 +105,9 @@ static void workspace_handle_destroy(struct wl_client *client, static void workspace_handle_activate(struct wl_client *client, struct wl_resource *workspace_resource) { - struct wlr_ext_workspace_client_v1 *workspace = - workspace_client_from_resource(workspace_resource); - if (!workspace) { + struct wlr_ext_workspace_v1_resource *workspace_res = + workspace_resource_from_resource(workspace_resource); + if (!workspace_res) { return; } @@ -110,16 +117,16 @@ static void workspace_handle_activate(struct wl_client *client, return; } req->type = WLR_EXT_WORKSPACE_V1_REQUEST_ACTIVATE; - req->workspace = workspace->workspace; - wl_list_insert(workspace->manager->requests.prev, &req->link); + req->workspace = workspace_res->workspace; + wl_list_insert(workspace_res->manager->requests.prev, &req->link); } static void workspace_handle_deactivate(struct wl_client *client, struct wl_resource *workspace_resource) { - struct wlr_ext_workspace_client_v1 *workspace = - workspace_client_from_resource(workspace_resource); - if (!workspace) { + struct wlr_ext_workspace_v1_resource *workspace_res = + workspace_resource_from_resource(workspace_resource); + if (!workspace_res) { return; } @@ -129,18 +136,18 @@ workspace_handle_deactivate(struct wl_client *client, return; } req->type = WLR_EXT_WORKSPACE_V1_REQUEST_DEACTIVATE; - req->workspace = workspace->workspace; - wl_list_insert(workspace->manager->requests.prev, &req->link); + req->workspace = workspace_res->workspace; + wl_list_insert(workspace_res->manager->requests.prev, &req->link); } static void workspace_handle_assign(struct wl_client *client, struct wl_resource *workspace_resource, struct wl_resource *group_resource) { - struct wlr_ext_workspace_client_v1 *workspace = - workspace_client_from_resource(workspace_resource); - struct wlr_ext_workspace_group_client_v1 *group = - group_client_from_resource(group_resource); - if (!workspace || !group) { + struct wlr_ext_workspace_v1_resource *workspace_res = + workspace_resource_from_resource(workspace_resource); + struct wlr_ext_workspace_group_v1_resource *group_res = + group_resource_from_resource(group_resource); + if (!workspace_res || !group_res) { return; } @@ -150,16 +157,16 @@ static void workspace_handle_assign(struct wl_client *client, return; } req->type = WLR_EXT_WORKSPACE_V1_REQUEST_ASSIGN; - req->group = group->group; - req->workspace = workspace->workspace; - wl_list_insert(workspace->manager->requests.prev, &req->link); + req->group = group_res->group; + req->workspace = workspace_res->workspace; + wl_list_insert(workspace_res->manager->requests.prev, &req->link); } static void workspace_handle_remove(struct wl_client *client, struct wl_resource *workspace_resource) { - struct wlr_ext_workspace_client_v1 *workspace = - workspace_client_from_resource(workspace_resource); - if (!workspace) { + struct wlr_ext_workspace_v1_resource *workspace_res = + workspace_resource_from_resource(workspace_resource); + if (!workspace_res) { return; } @@ -169,8 +176,8 @@ static void workspace_handle_remove(struct wl_client *client, return; } req->type = WLR_EXT_WORKSPACE_V1_REQUEST_REMOVE; - req->workspace = workspace->workspace; - wl_list_insert(workspace->manager->requests.prev, &req->link); + req->workspace = workspace_res->workspace; + wl_list_insert(workspace_res->manager->requests.prev, &req->link); } static const struct ext_workspace_handle_v1_interface workspace_impl = { @@ -184,9 +191,9 @@ static const struct ext_workspace_handle_v1_interface workspace_impl = { static void group_handle_create_workspace(struct wl_client *client, struct wl_resource *group_resource, const char *name) { - struct wlr_ext_workspace_group_client_v1 *group = - group_client_from_resource(group_resource); - if (!group) { + struct wlr_ext_workspace_group_v1_resource *group_res = + group_resource_from_resource(group_resource); + if (!group_res) { return; } @@ -195,9 +202,15 @@ static void group_handle_create_workspace(struct wl_client *client, wl_resource_post_no_memory(group_resource); return; } + req->name = strdup(name); + if (!req->name) { + free(req); + wl_resource_post_no_memory(group_resource); + return; + } req->type = WLR_EXT_WORKSPACE_V1_REQUEST_CREATE_WORKSPACE; - req->group = group->group; - wl_list_insert(group->manager->requests.prev, &req->link); + req->group = group_res->group; + wl_list_insert(group_res->manager->requests.prev, &req->link); } static void group_handle_destroy(struct wl_client *client, @@ -210,89 +223,94 @@ static const struct ext_workspace_group_handle_v1_interface group_impl = { .destroy = group_handle_destroy, }; -static void -destroy_workspace_client(struct wlr_ext_workspace_client_v1 *workspace_client) { - wl_list_remove(&workspace_client->link); - wl_resource_set_user_data(workspace_client->resource, NULL); - free(workspace_client); +static void destroy_workspace_resource( + struct wlr_ext_workspace_v1_resource *workspace_res) { + wl_list_remove(&workspace_res->link); + wl_list_remove(&workspace_res->manager_resource_link); + wl_resource_set_user_data(workspace_res->resource, NULL); + free(workspace_res); } static void workspace_resource_destroy(struct wl_resource *resource) { - struct wlr_ext_workspace_client_v1 *workspace_client = - workspace_client_from_resource(resource); - if (workspace_client) { - destroy_workspace_client(workspace_client); + struct wlr_ext_workspace_v1_resource *workspace_res = + workspace_resource_from_resource(resource); + if (workspace_res) { + destroy_workspace_resource(workspace_res); } } -static struct wlr_ext_workspace_client_v1 *create_workspace_client( +static struct wlr_ext_workspace_v1_resource *create_workspace_resource( struct wlr_ext_workspace_handle_v1 *workspace, - struct wlr_ext_workspace_manager_client_v1 *manager_client) { - struct wlr_ext_workspace_client_v1 *workspace_client = - calloc(1, sizeof(*workspace_client)); - if (!workspace_client) { + struct wlr_ext_workspace_manager_v1_resource *manager_res) { + struct wlr_ext_workspace_v1_resource *workspace_res = + calloc(1, sizeof(*workspace_res)); + if (!workspace_res) { return NULL; } - struct wl_client *client = wl_resource_get_client(manager_client->resource); - workspace_client->resource = wl_resource_create( - client, &ext_workspace_handle_v1_interface, - wl_resource_get_version(manager_client->resource), 0); - if (!workspace_client->resource) { - free(workspace_client); + struct wl_client *client = wl_resource_get_client(manager_res->resource); + workspace_res->resource = + wl_resource_create(client, &ext_workspace_handle_v1_interface, + wl_resource_get_version(manager_res->resource), 0); + if (!workspace_res->resource) { + free(workspace_res); return NULL; } - wl_resource_set_implementation(workspace_client->resource, &workspace_impl, - workspace_client, - workspace_resource_destroy); + wl_resource_set_implementation(workspace_res->resource, &workspace_impl, + workspace_res, workspace_resource_destroy); - workspace_client->workspace = workspace; - workspace_client->manager = manager_client; - wl_list_insert(&workspace->clients, &workspace_client->link); + workspace_res->workspace = workspace; + workspace_res->manager = manager_res; + wl_list_insert(&workspace->resources, &workspace_res->link); + wl_list_insert(&manager_res->workspace_resources, + &workspace_res->manager_resource_link); - return workspace_client; + return workspace_res; } static void -destroy_group_client(struct wlr_ext_workspace_group_client_v1 *group_client) { - wl_list_remove(&group_client->link); - wl_resource_set_user_data(group_client->resource, NULL); - free(group_client); +destroy_group_resource(struct wlr_ext_workspace_group_v1_resource *group_res) { + wl_list_remove(&group_res->link); + wl_list_remove(&group_res->manager_resource_link); + wl_resource_set_user_data(group_res->resource, NULL); + free(group_res); } static void group_handle_resource_destroy(struct wl_resource *resource) { - struct wlr_ext_workspace_group_client_v1 *group_client = - group_client_from_resource(resource); - if (group_client) { - destroy_group_client(group_client); + struct wlr_ext_workspace_group_v1_resource *group_res = + group_resource_from_resource(resource); + if (group_res) { + destroy_group_resource(group_res); } } -static struct wlr_ext_workspace_group_client_v1 *create_group_client( +static struct wlr_ext_workspace_group_v1_resource *create_group_resource( struct wlr_ext_workspace_group_handle_v1 *group, - struct wlr_ext_workspace_manager_client_v1 *manager_client) { - struct wlr_ext_workspace_group_client_v1 *group_client = - calloc(1, sizeof(*group_client)); - if (!group_client) { + struct wlr_ext_workspace_manager_v1_resource *manager_res) { + struct wlr_ext_workspace_group_v1_resource *group_res = + calloc(1, sizeof(*group_res)); + if (!group_res) { return NULL; } - struct wl_client *client = wl_resource_get_client(manager_client->resource); - uint32_t version = wl_resource_get_version(manager_client->resource); - group_client->resource = wl_resource_create( + struct wl_client *client = wl_resource_get_client(manager_res->resource); + uint32_t version = wl_resource_get_version(manager_res->resource); + group_res->resource = wl_resource_create( client, &ext_workspace_group_handle_v1_interface, version, 0); - if (group_client->resource == NULL) { - free(group_client); + if (group_res->resource == NULL) { + free(group_res); return NULL; } - wl_resource_set_implementation(group_client->resource, &group_impl, - group_client, group_handle_resource_destroy); + wl_resource_set_implementation(group_res->resource, &group_impl, group_res, + group_handle_resource_destroy); - group_client->group = group; - group_client->manager = manager_client; - wl_list_insert(&group->clients, &group_client->link); + group_res->group = group; + group_res->manager = manager_res; + wl_list_insert(&group->resources, &group_res->link); + wl_list_insert(&manager_res->group_resources, + &group_res->manager_resource_link); - return group_client; + return group_res; } static void destroy_request(struct wlr_ext_workspace_v1_request *req) { @@ -303,18 +321,22 @@ static void destroy_request(struct wlr_ext_workspace_v1_request *req) { static void manager_handle_commit(struct wl_client *client, struct wl_resource *resource) { - struct wlr_ext_workspace_manager_client_v1 *manager = - manager_client_from_resource(resource); - if (!manager) { + struct wlr_ext_workspace_manager_v1_resource *manager_res = + manager_resource_from_resource(resource); + if (!manager_res) { return; } struct wlr_ext_workspace_v1_request *req, *tmp; - wl_list_for_each_safe(req, tmp, &manager->requests, link) { + wl_list_for_each_safe(req, tmp, &manager_res->requests, link) { switch (req->type) { - case WLR_EXT_WORKSPACE_V1_REQUEST_CREATE_WORKSPACE: + case WLR_EXT_WORKSPACE_V1_REQUEST_CREATE_WORKSPACE:; + struct wlr_ext_workspace_group_handle_v1_create_workspace_event + event = { + .name = req->name, + }; wl_signal_emit_mutable(&req->group->events.create_workspace, - req->name); + &event); break; case WLR_EXT_WORKSPACE_V1_REQUEST_ACTIVATE: wl_signal_emit_mutable(&req->workspace->events.activate, NULL); @@ -323,13 +345,11 @@ static void manager_handle_commit(struct wl_client *client, wl_signal_emit_mutable(&req->workspace->events.deactivate, NULL); break; case WLR_EXT_WORKSPACE_V1_REQUEST_ASSIGN: - wl_signal_emit_mutable(&req->workspace->events.assign, &req->group); + wl_signal_emit_mutable(&req->workspace->events.assign, req->group); break; case WLR_EXT_WORKSPACE_V1_REQUEST_REMOVE: wl_signal_emit_mutable(&req->workspace->events.remove, NULL); break; - default: - abort(); } destroy_request(req); } @@ -338,9 +358,9 @@ static void manager_handle_commit(struct wl_client *client, static void handle_idle(void *data) { struct wlr_ext_workspace_manager_v1 *manager = data; - struct wlr_ext_workspace_manager_client_v1 *manager_client; - wl_list_for_each(manager_client, &manager->clients, link) { - ext_workspace_manager_v1_send_done(manager_client->resource); + struct wlr_ext_workspace_manager_v1_resource *manager_res; + wl_list_for_each(manager_res, &manager->resources, link) { + ext_workspace_manager_v1_send_done(manager_res->resource); } manager->idle_source = NULL; } @@ -354,9 +374,9 @@ manager_schedule_done(struct wlr_ext_workspace_manager_v1 *manager) { } static void -workspace_send_details(struct wlr_ext_workspace_client_v1 *workspace_client) { - struct wlr_ext_workspace_handle_v1 *workspace = workspace_client->workspace; - struct wl_resource *resource = workspace_client->resource; +workspace_send_details(struct wlr_ext_workspace_v1_resource *workspace_res) { + struct wlr_ext_workspace_handle_v1 *workspace = workspace_res->workspace; + struct wl_resource *resource = workspace_res->resource; ext_workspace_handle_v1_send_capabilities(resource, workspace->caps); if (workspace->coordinates.size > 0) { @@ -384,29 +404,41 @@ static const struct ext_workspace_manager_v1_interface manager_impl = { .stop = manager_handle_stop, }; -static void destroy_manager_client( - struct wlr_ext_workspace_manager_client_v1 *manager_client) { +static void destroy_manager_resource( + struct wlr_ext_workspace_manager_v1_resource *manager_res) { struct wlr_ext_workspace_v1_request *req, *tmp; - wl_list_for_each_safe(req, tmp, &manager_client->requests, link) { + wl_list_for_each_safe(req, tmp, &manager_res->requests, link) { destroy_request(req); } - wl_list_remove(&manager_client->link); - wl_resource_set_user_data(manager_client->resource, NULL); - free(manager_client); + struct wlr_ext_workspace_v1_resource *workspace_res, *tmp2; + wl_list_for_each_safe(workspace_res, tmp2, + &manager_res->workspace_resources, + manager_resource_link) { + destroy_workspace_resource(workspace_res); + } + struct wlr_ext_workspace_group_v1_resource *group_res, *tmp3; + wl_list_for_each_safe(group_res, tmp3, &manager_res->group_resources, + manager_resource_link) { + destroy_group_resource(group_res); + } + + wl_list_remove(&manager_res->link); + wl_resource_set_user_data(manager_res->resource, NULL); + free(manager_res); } static void manager_resource_destroy(struct wl_resource *resource) { - struct wlr_ext_workspace_manager_client_v1 *manager_client = - manager_client_from_resource(resource); - if (manager_client) { - destroy_manager_client(manager_client); + struct wlr_ext_workspace_manager_v1_resource *manager_res = + manager_resource_from_resource(resource); + if (manager_res) { + destroy_manager_resource(manager_res); } } static void -group_send_details(struct wlr_ext_workspace_group_client_v1 *group_client) { - struct wlr_ext_workspace_group_handle_v1 *group = group_client->group; - struct wl_resource *resource = group_client->resource; +group_send_details(struct wlr_ext_workspace_group_v1_resource *group_res) { + struct wlr_ext_workspace_group_handle_v1 *group = group_res->group; + struct wl_resource *resource = group_res->resource; struct wl_client *client = wl_resource_get_client(resource); ext_workspace_group_handle_v1_send_capabilities(resource, group->caps); @@ -430,65 +462,67 @@ static void manager_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id) { struct wlr_ext_workspace_manager_v1 *manager = data; - struct wlr_ext_workspace_manager_client_v1 *manager_client = - calloc(1, sizeof(*manager_client)); - if (!manager_client) { + struct wlr_ext_workspace_manager_v1_resource *manager_res = + calloc(1, sizeof(*manager_res)); + if (!manager_res) { wl_client_post_no_memory(client); return; } - manager_client->manager = manager; - wl_list_init(&manager_client->requests); - wl_list_insert(&manager->clients, &manager_client->link); + manager_res->manager = manager; + wl_list_init(&manager_res->requests); + wl_list_init(&manager_res->workspace_resources); + wl_list_init(&manager_res->group_resources); - manager_client->resource = wl_resource_create( + manager_res->resource = wl_resource_create( client, &ext_workspace_manager_v1_interface, version, id); - if (!manager_client->resource) { - free(manager_client); + if (!manager_res->resource) { + free(manager_res); wl_client_post_no_memory(client); return; } - wl_resource_set_implementation(manager_client->resource, &manager_impl, - manager_client, manager_resource_destroy); + wl_resource_set_implementation(manager_res->resource, &manager_impl, + manager_res, manager_resource_destroy); + wl_list_insert(&manager->resources, &manager_res->link); struct wlr_ext_workspace_group_handle_v1 *group; wl_list_for_each(group, &manager->groups, link) { - struct wlr_ext_workspace_group_client_v1 *group_client = - create_group_client(group, manager_client); - if (!group_client) { - wl_resource_post_no_memory(manager_client->resource); + struct wlr_ext_workspace_group_v1_resource *group_res = + create_group_resource(group, manager_res); + if (!group_res) { + wl_resource_post_no_memory(manager_res->resource); continue; } - ext_workspace_manager_v1_send_workspace_group(manager_client->resource, - group_client->resource); - group_send_details(group_client); + ext_workspace_manager_v1_send_workspace_group(manager_res->resource, + group_res->resource); + group_send_details(group_res); } struct wlr_ext_workspace_handle_v1 *workspace; wl_list_for_each(workspace, &manager->workspaces, link) { - struct wlr_ext_workspace_client_v1 *workspace_client = - create_workspace_client(workspace, manager_client); - if (!workspace) { - wl_client_post_no_memory(client); + struct wlr_ext_workspace_v1_resource *workspace_res = + create_workspace_resource(workspace, manager_res); + if (!workspace_res) { + wl_resource_post_no_memory(manager_res->resource); continue; } - ext_workspace_manager_v1_send_workspace(manager_client->resource, - workspace_client->resource); - workspace_send_details(workspace_client); + ext_workspace_manager_v1_send_workspace(manager_res->resource, + workspace_res->resource); + workspace_send_details(workspace_res); if (!workspace->group) { continue; } - struct wlr_ext_workspace_group_client_v1 *group_client; - wl_list_for_each(group_client, &workspace->group->clients, link) { - if (group_client->manager == manager_client) { + struct wlr_ext_workspace_group_v1_resource *group_res; + wl_list_for_each(group_res, &workspace->group->resources, link) { + if (group_res->manager == manager_res) { ext_workspace_group_handle_v1_send_workspace_enter( - group_client->resource, workspace_client->resource); + group_res->resource, workspace_res->resource); } } } - manager_schedule_done(manager); + ext_workspace_manager_v1_send_done(manager_res->resource); } static void manager_handle_display_destroy(struct wl_listener *listener, @@ -509,9 +543,9 @@ static void manager_handle_display_destroy(struct wl_listener *listener, wlr_ext_workspace_handle_v1_destroy(workspace); } - struct wlr_ext_workspace_manager_client_v1 *manager_client, *tmp3; - wl_list_for_each_safe(manager_client, tmp3, &manager->clients, link) { - destroy_manager_client(manager_client); + struct wlr_ext_workspace_manager_v1_resource *manager_res, *tmp3; + wl_list_for_each_safe(manager_res, tmp3, &manager->resources, link) { + destroy_manager_resource(manager_res); } if (manager->idle_source) { @@ -548,7 +582,7 @@ wlr_ext_workspace_manager_v1_create(struct wl_display *display, wl_list_init(&manager->groups); wl_list_init(&manager->workspaces); - wl_list_init(&manager->clients); + wl_list_init(&manager->resources); wl_signal_init(&manager->events.destroy); return manager; @@ -566,22 +600,22 @@ wlr_ext_workspace_group_handle_v1_create( group->caps = caps; wl_list_init(&group->outputs); - wl_list_init(&group->clients); + wl_list_init(&group->resources); wl_signal_init(&group->events.create_workspace); wl_signal_init(&group->events.destroy); wl_list_insert(manager->groups.prev, &group->link); - struct wlr_ext_workspace_manager_client_v1 *manager_client; - wl_list_for_each(manager_client, &manager->clients, link) { - struct wlr_ext_workspace_group_client_v1 *group_client = - create_group_client(group, manager_client); - if (!group_client) { + struct wlr_ext_workspace_manager_v1_resource *manager_res; + wl_list_for_each(manager_res, &manager->resources, link) { + struct wlr_ext_workspace_group_v1_resource *group_res = + create_group_resource(group, manager_res); + if (!group_res) { continue; } - ext_workspace_manager_v1_send_workspace_group(manager_client->resource, - group_client->resource); - group_send_details(group_client); + ext_workspace_manager_v1_send_workspace_group(manager_res->resource, + group_res->resource); + group_send_details(group_res); } manager_schedule_done(manager); @@ -594,19 +628,19 @@ workspace_send_group(struct wlr_ext_workspace_handle_v1 *workspace, struct wlr_ext_workspace_group_handle_v1 *group, bool enter) { - struct wlr_ext_workspace_client_v1 *workspace_client; - wl_list_for_each(workspace_client, &workspace->clients, link) { - struct wlr_ext_workspace_group_client_v1 *group_client; - wl_list_for_each(group_client, &group->clients, link) { - if (group_client->manager != workspace_client->manager) { + struct wlr_ext_workspace_v1_resource *workspace_res; + wl_list_for_each(workspace_res, &workspace->resources, link) { + struct wlr_ext_workspace_group_v1_resource *group_res; + wl_list_for_each(group_res, &group->resources, link) { + if (group_res->manager != workspace_res->manager) { continue; } if (enter) { ext_workspace_group_handle_v1_send_workspace_enter( - group_client->resource, workspace_client->resource); + group_res->resource, workspace_res->resource); } else { ext_workspace_group_handle_v1_send_workspace_leave( - group_client->resource, workspace_client->resource); + group_res->resource, workspace_res->resource); } } } @@ -625,10 +659,9 @@ destroy_group_output(struct wlr_ext_workspace_v1_group_output *group_output) { static void group_send_output(struct wlr_ext_workspace_group_handle_v1 *group, struct wlr_output *output, bool enter) { - struct wlr_ext_workspace_group_client_v1 *group_client; - wl_list_for_each(group_client, &group->clients, link) { - struct wl_client *client = - wl_resource_get_client(group_client->resource); + struct wlr_ext_workspace_group_v1_resource *group_res; + wl_list_for_each(group_res, &group->resources, link) { + struct wl_client *client = wl_resource_get_client(group_res->resource); struct wl_resource *output_resource; wl_resource_for_each(output_resource, &output->resources) { @@ -637,10 +670,10 @@ static void group_send_output(struct wlr_ext_workspace_group_handle_v1 *group, } if (enter) { ext_workspace_group_handle_v1_send_output_enter( - group_client->resource, output_resource); + group_res->resource, output_resource); } else { ext_workspace_group_handle_v1_send_output_leave( - group_client->resource, output_resource); + group_res->resource, output_resource); } } } @@ -650,6 +683,10 @@ static void group_send_output(struct wlr_ext_workspace_group_handle_v1 *group, void wlr_ext_workspace_group_handle_v1_destroy( struct wlr_ext_workspace_group_handle_v1 *group) { + if (!group) { + return; + } + wl_signal_emit_mutable(&group->events.destroy, NULL); assert(wl_list_empty(&group->events.create_workspace.listener_list)); @@ -663,16 +700,16 @@ void wlr_ext_workspace_group_handle_v1_destroy( } } - struct wlr_ext_workspace_group_client_v1 *group_client, *tmp; - wl_list_for_each_safe(group_client, tmp, &group->clients, link) { - ext_workspace_group_handle_v1_send_removed(group_client->resource); - destroy_group_client(group_client); + struct wlr_ext_workspace_group_v1_resource *group_res, *tmp; + wl_list_for_each_safe(group_res, tmp, &group->resources, link) { + ext_workspace_group_handle_v1_send_removed(group_res->resource); + destroy_group_resource(group_res); } - struct wlr_ext_workspace_manager_client_v1 *manager_client; - wl_list_for_each(manager_client, &group->manager->clients, link) { + struct wlr_ext_workspace_manager_v1_resource *manager_res; + wl_list_for_each(manager_res, &group->manager->resources, link) { struct wlr_ext_workspace_v1_request *req, *tmp2; - wl_list_for_each_safe(req, tmp2, &manager_client->requests, link) { + wl_list_for_each_safe(req, tmp2, &manager_res->requests, link) { if (req->group == group) { destroy_request(req); } @@ -697,11 +734,11 @@ static void handle_output_bind(struct wl_listener *listener, void *data) { struct wlr_output_event_bind *event = data; struct wl_client *client = wl_resource_get_client(event->resource); - struct wlr_ext_workspace_group_client_v1 *group_client; - wl_list_for_each(group_client, &group_output->group->clients, link) { - if (wl_resource_get_client(group_client->resource) == client) { - ext_workspace_group_handle_v1_send_output_enter( - group_client->resource, event->resource); + struct wlr_ext_workspace_group_v1_resource *group_res; + wl_list_for_each(group_res, &group_output->group->resources, link) { + if (wl_resource_get_client(group_res->resource) == client) { + ext_workspace_group_handle_v1_send_output_enter(group_res->resource, + event->resource); } } @@ -778,11 +815,12 @@ wlr_ext_workspace_handle_v1_create(struct wlr_ext_workspace_manager_v1 *manager, if (id) { workspace->id = strdup(id); if (!workspace->id) { + free(workspace); return NULL; } } - wl_list_init(&workspace->clients); + wl_list_init(&workspace->resources); wl_array_init(&workspace->coordinates); wl_signal_init(&workspace->events.activate); wl_signal_init(&workspace->events.deactivate); @@ -792,16 +830,16 @@ wlr_ext_workspace_handle_v1_create(struct wlr_ext_workspace_manager_v1 *manager, wl_list_insert(&manager->workspaces, &workspace->link); - struct wlr_ext_workspace_manager_client_v1 *manager_client; - wl_list_for_each(manager_client, &manager->clients, link) { - struct wlr_ext_workspace_client_v1 *workspace_client = - create_workspace_client(workspace, manager_client); - if (!workspace_client) { + struct wlr_ext_workspace_manager_v1_resource *manager_res; + wl_list_for_each(manager_res, &manager->resources, link) { + struct wlr_ext_workspace_v1_resource *workspace_res = + create_workspace_resource(workspace, manager_res); + if (!workspace_res) { continue; } - ext_workspace_manager_v1_send_workspace(manager_client->resource, - workspace_client->resource); - workspace_send_details(workspace_client); + ext_workspace_manager_v1_send_workspace(manager_res->resource, + workspace_res->resource); + workspace_send_details(workspace_res); } manager_schedule_done(manager); @@ -811,6 +849,10 @@ wlr_ext_workspace_handle_v1_create(struct wlr_ext_workspace_manager_v1 *manager, void wlr_ext_workspace_handle_v1_destroy( struct wlr_ext_workspace_handle_v1 *workspace) { + if (!workspace) { + return; + } + wl_signal_emit_mutable(&workspace->events.destroy, NULL); assert(wl_list_empty(&workspace->events.activate.listener_list)); @@ -823,16 +865,16 @@ void wlr_ext_workspace_handle_v1_destroy( workspace_send_group(workspace, workspace->group, false); } - struct wlr_ext_workspace_client_v1 *workspace_client, *tmp; - wl_list_for_each_safe(workspace_client, tmp, &workspace->clients, link) { - ext_workspace_handle_v1_send_removed(workspace_client->resource); - destroy_workspace_client(workspace_client); + struct wlr_ext_workspace_v1_resource *workspace_res, *tmp; + wl_list_for_each_safe(workspace_res, tmp, &workspace->resources, link) { + ext_workspace_handle_v1_send_removed(workspace_res->resource); + destroy_workspace_resource(workspace_res); } - struct wlr_ext_workspace_manager_client_v1 *manager_client; - wl_list_for_each(manager_client, &workspace->manager->clients, link) { + struct wlr_ext_workspace_manager_v1_resource *manager_res; + wl_list_for_each(manager_res, &workspace->manager->resources, link) { struct wlr_ext_workspace_v1_request *req, *tmp2; - wl_list_for_each_safe(req, tmp2, &manager_client->requests, link) { + wl_list_for_each_safe(req, tmp2, &manager_res->requests, link) { if (req->workspace == workspace) { destroy_request(req); } @@ -856,7 +898,7 @@ void wlr_ext_workspace_handle_v1_set_group( } if (workspace->group) { - workspace_send_group(workspace, group, false); + workspace_send_group(workspace, workspace->group, false); } workspace->group = group; if (group) { @@ -878,9 +920,9 @@ void wlr_ext_workspace_handle_v1_set_name( return; } - struct wlr_ext_workspace_client_v1 *workspace_client; - wl_list_for_each(workspace_client, &workspace->clients, link) { - ext_workspace_handle_v1_send_name(workspace_client->resource, + struct wlr_ext_workspace_v1_resource *workspace_res; + wl_list_for_each(workspace_res, &workspace->resources, link) { + ext_workspace_handle_v1_send_name(workspace_res->resource, workspace->name); } @@ -905,9 +947,9 @@ void wlr_ext_workspace_handle_v1_set_coordinates( wl_array_init(&workspace->coordinates); wl_array_copy(&workspace->coordinates, coordinates); - struct wlr_ext_workspace_client_v1 *workspace_client; - wl_list_for_each(workspace_client, &workspace->clients, link) { - ext_workspace_handle_v1_send_coordinates(workspace_client->resource, + struct wlr_ext_workspace_v1_resource *workspace_res; + wl_list_for_each(workspace_res, &workspace->resources, link) { + ext_workspace_handle_v1_send_coordinates(workspace_res->resource, &workspace->coordinates); } @@ -927,9 +969,9 @@ static void workspace_set_state(struct wlr_ext_workspace_handle_v1 *workspace, return; } - struct wlr_ext_workspace_client_v1 *workspace_client; - wl_list_for_each(workspace_client, &workspace->clients, link) { - ext_workspace_handle_v1_send_state(workspace_client->resource, + struct wlr_ext_workspace_v1_resource *workspace_res; + wl_list_for_each(workspace_res, &workspace->resources, link) { + ext_workspace_handle_v1_send_state(workspace_res->resource, workspace->state); } diff --git a/src/ext-protocol/wlr_ext_workspace_v1.h b/src/ext-protocol/wlr_ext_workspace_v1.h index e1d285b..a2a733b 100644 --- a/src/ext-protocol/wlr_ext_workspace_v1.h +++ b/src/ext-protocol/wlr_ext_workspace_v1.h @@ -2,32 +2,11 @@ // TODO: remove this file // refer: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/5115 -/* - * This an unstable interface of wlroots. No guarantees are made regarding the - * future consistency of this API. - */ -#ifndef WLR_USE_UNSTABLE -#error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features" -#endif - -#ifndef WLR_TYPES_WLR_EXT_WORKSPACE_V1_H -#define WLR_TYPES_WLR_EXT_WORKSPACE_V1_H - +#include #include struct wlr_output; -enum wlr_ext_workspace_group_handle_v1_cap { - WLR_EXT_WORKSPACE_GROUP_HANDLE_V1_CAP_CREATE_WORKSPACE = 1 << 0, -}; - -enum wlr_ext_workspace_handle_v1_cap { - WLR_EXT_WORKSPACE_HANDLE_V1_CAP_ACTIVATE = 1 << 0, - WLR_EXT_WORKSPACE_HANDLE_V1_CAP_DEACTIVATE = 1 << 1, - WLR_EXT_WORKSPACE_HANDLE_V1_CAP_REMOVE = 1 << 2, - WLR_EXT_WORKSPACE_HANDLE_V1_CAP_ASSIGN = 1 << 3, -}; - struct wlr_ext_workspace_manager_v1 { struct wl_global *global; struct wl_list groups; // wlr_ext_workspace_group_handle_v1.link @@ -37,24 +16,33 @@ struct wlr_ext_workspace_manager_v1 { struct wl_signal destroy; } events; - struct wl_list clients; // wlr_ext_workspace_manager_client_v1.link - struct wl_event_source *idle_source; - struct wl_event_loop *event_loop; - struct wl_listener display_destroy; + struct { + struct wl_list resources; // wlr_ext_workspace_manager_v1_resource.link + struct wl_event_source *idle_source; + struct wl_event_loop *event_loop; + struct wl_listener display_destroy; + }; +}; + +struct wlr_ext_workspace_group_handle_v1_create_workspace_event { + const char *name; }; struct wlr_ext_workspace_group_handle_v1 { struct wlr_ext_workspace_manager_v1 *manager; - uint32_t caps; // wlr_ext_workspace_group_handle_v1_cap + uint32_t caps; // ext_workspace_group_handle_v1_group_capabilities struct { - struct wl_signal create_workspace; // const char * + struct wl_signal + create_workspace; // wlr_ext_workspace_group_handle_v1_create_workspace_event struct wl_signal destroy; } events; struct wl_list link; // wlr_ext_workspace_manager_v1.groups - struct wl_list outputs; // wlr_ext_workspace_v1_group_output.link - struct wl_list clients; // wlr_ext_workspace_manager_client_v1.link + struct { + struct wl_list outputs; // wlr_ext_workspace_v1_group_output.link + struct wl_list resources; // wlr_ext_workspace_manager_v1_resource.link + }; }; struct wlr_ext_workspace_handle_v1 { @@ -63,7 +51,7 @@ struct wlr_ext_workspace_handle_v1 { char *id; char *name; struct wl_array coordinates; - uint32_t caps; // wlr_ext_workspace_handle_v1_cap + uint32_t caps; // ext_workspace_handle_v1_workspace_capabilities uint32_t state; // ext_workspace_handle_v1_state struct { @@ -74,9 +62,11 @@ struct wlr_ext_workspace_handle_v1 { struct wl_signal destroy; } events; - struct wl_list link; // wlr_ext_workspace_manager_v1.workspaces; + struct wl_list link; // wlr_ext_workspace_manager_v1.workspaces - struct wl_list clients; + struct { + struct wl_list resources; // wlr_ext_workspace_v1_resource.link + }; }; struct wlr_ext_workspace_manager_v1 * @@ -114,5 +104,3 @@ void wlr_ext_workspace_handle_v1_set_urgent( struct wlr_ext_workspace_handle_v1 *workspace, bool enabled); void wlr_ext_workspace_handle_v1_set_hidden( struct wlr_ext_workspace_handle_v1 *workspace, bool enabled); - -#endif diff --git a/src/mango.c b/src/mango.c index ae84091..1bd2c1f 100644 --- a/src/mango.c +++ b/src/mango.c @@ -3442,7 +3442,6 @@ keybinding(uint32_t state, bool locked, uint32_t mods, xkb_keysym_t sym, isbreak = k->func(&k->arg); - if (isbreak) break; }