From 4aab5f8bb0a24ef15d8cb0622405d417ca01fe01 Mon Sep 17 00:00:00 2001 From: Ilia Bozhinov Date: Tue, 23 Feb 2021 21:24:19 +0100 Subject: [PATCH] update to newest zext-workspace --- examples/{wlr-workspace.c => ext-workspace.c} | 120 +++++++++++------- examples/meson.build | 4 +- include/wlr/types/wlr_ext_workspace_v1.h | 8 ++ types/wlr_ext_workspace_v1.c | 39 +++++- 4 files changed, 120 insertions(+), 51 deletions(-) rename examples/{wlr-workspace.c => ext-workspace.c} (69%) diff --git a/examples/wlr-workspace.c b/examples/ext-workspace.c similarity index 69% rename from examples/wlr-workspace.c rename to examples/ext-workspace.c index eab65a28c..1e1544dd1 100644 --- a/examples/wlr-workspace.c +++ b/examples/ext-workspace.c @@ -5,18 +5,22 @@ #include #include #include -#include "wlr-workspace-unstable-v1-client-protocol.h" +#include "ext-workspace-unstable-v1-client-protocol.h" -#define WLR_WORKSPACE_VERSION 1 +#define WLR_EXT_WORKSPACE_VERSION 1 /** * Usage: - * 1. wlr-workspace + * 1. ext-workspace * List all workspace groups and their workspaces - * 2. wlr-workspace -w X + * 2. ext-workspace -w X * Focus workspace with name X - * 3. wlr-workspace -m + * 3. ext-workspace -m * Continuously monitor for changes and print new state. + * 4. ext-workspace -c X + * Create a new workspace with name hint X in some workspace group + * 5. ext-workspace -r X + * Request removal of workspace X */ enum workspace_state_field { @@ -44,7 +48,7 @@ static void copy_state(struct workspace_state *current, struct workspace_v1 { struct wl_list link; - struct zwlr_workspace_handle_v1 *handle; + struct zext_workspace_handle_v1 *handle; struct workspace_state current, pending; }; @@ -70,45 +74,44 @@ static uint32_t array_to_state(struct wl_array *array) { uint32_t state = 0; uint32_t *entry; wl_array_for_each(entry, array) { - if (*entry == ZWLR_WORKSPACE_HANDLE_V1_STATE_ACTIVE) + if (*entry == ZEXT_WORKSPACE_HANDLE_V1_STATE_ACTIVE) state |= WORKSPACE_FOCUSED; } return state; } - static void workspace_handle_name(void *data, - struct zwlr_workspace_handle_v1 *workspace_handle_v1, + struct zext_workspace_handle_v1 *workspace_handle_v1, const char *name) { struct workspace_v1 *workspace = (struct workspace_v1*) - zwlr_workspace_handle_v1_get_user_data(workspace_handle_v1); + zext_workspace_handle_v1_get_user_data(workspace_handle_v1); free(workspace->pending.name); workspace->pending.name = strdup(name); } static void workspace_handle_coordinates(void *data, - struct zwlr_workspace_handle_v1 *workspace_handle, + struct zext_workspace_handle_v1 *workspace_handle, struct wl_array *coordinates) { struct workspace_v1 *workspace = (struct workspace_v1*) - zwlr_workspace_handle_v1_get_user_data(workspace_handle); + zext_workspace_handle_v1_get_user_data(workspace_handle); wl_array_copy(&workspace->pending.coordinates, coordinates); } static void workspace_handle_state(void *data, - struct zwlr_workspace_handle_v1 *workspace_handle, + struct zext_workspace_handle_v1 *workspace_handle, struct wl_array *state) { struct workspace_v1 *workspace = (struct workspace_v1*) - zwlr_workspace_handle_v1_get_user_data(workspace_handle); + zext_workspace_handle_v1_get_user_data(workspace_handle); workspace->pending.state = array_to_state(state); } static void workspace_handle_remove(void *data, - struct zwlr_workspace_handle_v1 *workspace_handle) { + struct zext_workspace_handle_v1 *workspace_handle) { struct workspace_v1 *workspace = (struct workspace_v1*) - zwlr_workspace_handle_v1_get_user_data(workspace_handle); - zwlr_workspace_handle_v1_destroy(workspace_handle); + zext_workspace_handle_v1_get_user_data(workspace_handle); + zext_workspace_handle_v1_destroy(workspace_handle); wl_list_remove(&workspace->link); free(workspace->current.name); @@ -118,7 +121,7 @@ static void workspace_handle_remove(void *data, free(workspace); } -static const struct zwlr_workspace_handle_v1_listener workspace_listener = { +static const struct zext_workspace_handle_v1_listener workspace_listener = { .name = workspace_handle_name, .coordinates = workspace_handle_coordinates, .state = workspace_handle_state, @@ -128,33 +131,34 @@ static const struct zwlr_workspace_handle_v1_listener workspace_listener = { struct group_v1 { struct wl_list link; + struct zext_workspace_group_handle_v1 *handle; int32_t id; struct wl_list workspaces; }; static void group_handle_output_enter(void *data, - struct zwlr_workspace_group_handle_v1 *group_handle, + struct zext_workspace_group_handle_v1 *group_handle, struct wl_output *output) { struct group_v1 *group = (struct group_v1*) - zwlr_workspace_group_handle_v1_get_user_data(group_handle); + zext_workspace_group_handle_v1_get_user_data(group_handle); printf("Group %d output_enter %u\n", group->id, (uint32_t)(size_t)wl_output_get_user_data(output)); } static void group_handle_output_leave(void *data, - struct zwlr_workspace_group_handle_v1 *group_handle, + struct zext_workspace_group_handle_v1 *group_handle, struct wl_output *output) { struct group_v1 *group = (struct group_v1*) - zwlr_workspace_group_handle_v1_get_user_data(group_handle); + zext_workspace_group_handle_v1_get_user_data(group_handle); printf("Group %d output_leave %u\n", group->id, (uint32_t)(size_t)wl_output_get_user_data(output)); } static void group_handle_workspace(void *data, - struct zwlr_workspace_group_handle_v1 *group_handle, - struct zwlr_workspace_handle_v1 *workspace_handle) { + struct zext_workspace_group_handle_v1 *group_handle, + struct zext_workspace_handle_v1 *workspace_handle) { struct group_v1 *group = (struct group_v1*) - zwlr_workspace_group_handle_v1_get_user_data(group_handle); + zext_workspace_group_handle_v1_get_user_data(group_handle); struct workspace_v1 *workspace = (struct workspace_v1*) calloc(1, sizeof(struct workspace_v1)); @@ -163,15 +167,15 @@ static void group_handle_workspace(void *data, wl_array_init(&workspace->current.coordinates); workspace->handle = workspace_handle; - zwlr_workspace_handle_v1_add_listener(workspace_handle, + zext_workspace_handle_v1_add_listener(workspace_handle, &workspace_listener, NULL); - zwlr_workspace_handle_v1_set_user_data(workspace_handle, workspace); + zext_workspace_handle_v1_set_user_data(workspace_handle, workspace); } static void group_handle_remove(void *data, - struct zwlr_workspace_group_handle_v1 *group_handle) { + struct zext_workspace_group_handle_v1 *group_handle) { struct group_v1 *group = (struct group_v1*) - zwlr_workspace_group_handle_v1_get_user_data(group_handle); + zext_workspace_group_handle_v1_get_user_data(group_handle); wl_list_remove(&group->link); if (!wl_list_empty(&group->workspaces)) { printf("Compositor bug! Group destroyed before its workspaces.\n"); @@ -180,33 +184,34 @@ static void group_handle_remove(void *data, free(group); } -static const struct zwlr_workspace_group_handle_v1_listener group_listener = { +static const struct zext_workspace_group_handle_v1_listener group_listener = { .output_enter = group_handle_output_enter, .output_leave = group_handle_output_leave, .workspace = group_handle_workspace, .remove = group_handle_remove, }; -static struct zwlr_workspace_manager_v1 *workspace_manager = NULL; +static struct zext_workspace_manager_v1 *workspace_manager = NULL; static struct wl_list group_list; static int32_t last_group_id = 0; static void workspace_manager_handle_workspace_group(void *data, - struct zwlr_workspace_manager_v1 *zwlr_workspace_manager_v1, - struct zwlr_workspace_group_handle_v1 *workspace_group) { + struct zext_workspace_manager_v1 *zext_workspace_manager_v1, + struct zext_workspace_group_handle_v1 *workspace_group) { struct group_v1 *group = (struct group_v1*) calloc(1, sizeof(struct group_v1)); group->id = last_group_id++; + group->handle = workspace_group; wl_list_init(&group->workspaces); wl_list_insert(&group_list, &group->link); - zwlr_workspace_group_handle_v1_add_listener(workspace_group, + zext_workspace_group_handle_v1_add_listener(workspace_group, &group_listener, NULL); - zwlr_workspace_group_handle_v1_set_user_data(workspace_group, group); + zext_workspace_group_handle_v1_set_user_data(workspace_group, group); } static void workspace_manager_handle_done(void *data, - struct zwlr_workspace_manager_v1 *zwlr_workspace_manager_v1) { + struct zext_workspace_manager_v1 *zext_workspace_manager_v1) { printf("*** Workspace configuration ***\n"); struct group_v1 *group; @@ -221,11 +226,11 @@ static void workspace_manager_handle_done(void *data, } static void workspace_manager_handle_finished(void *data, - struct zwlr_workspace_manager_v1 *zwlr_workspace_manager_v1) { - zwlr_workspace_manager_v1_destroy(zwlr_workspace_manager_v1); + struct zext_workspace_manager_v1 *zext_workspace_manager_v1) { + zext_workspace_manager_v1_destroy(zext_workspace_manager_v1); } -static const struct zwlr_workspace_manager_v1_listener workspace_manager_impl = { +static const struct zext_workspace_manager_v1_listener workspace_manager_impl = { .workspace_group = workspace_manager_handle_workspace_group, .done = workspace_manager_handle_done, .finished = workspace_manager_handle_finished, @@ -239,12 +244,12 @@ static void handle_global(void *data, struct wl_registry *registry, &wl_output_interface, version); wl_output_set_user_data(output, (void*)(size_t)name); // assign some ID to the output } else if (strcmp(interface, - zwlr_workspace_manager_v1_interface.name) == 0) { + zext_workspace_manager_v1_interface.name) == 0) { workspace_manager = wl_registry_bind(registry, name, - &zwlr_workspace_manager_v1_interface, WLR_WORKSPACE_VERSION); + &zext_workspace_manager_v1_interface, WLR_EXT_WORKSPACE_VERSION); wl_list_init(&group_list); - zwlr_workspace_manager_v1_add_listener(workspace_manager, + zext_workspace_manager_v1_add_listener(workspace_manager, &workspace_manager_impl, NULL); } } @@ -278,11 +283,19 @@ static struct workspace_v1 *workspace_by_name_or_bail(const char *name) { int main(int argc, char **argv) { int c; - char *focus_name = NULL; + char *focus_name = NULL; + char *create_name = NULL; + char *remove_name = NULL; bool monitor = false; - while ((c = getopt(argc, argv, "w:m")) != -1) { + while ((c = getopt(argc, argv, "c:r:w:m")) != -1) { switch (c) { + case 'c': + create_name = strdup(optarg); + break; + case 'r': + remove_name = strdup(optarg); + break; case 'w': focus_name = strdup(optarg); break; @@ -319,11 +332,24 @@ int main(int argc, char **argv) { wl_list_for_each(group, &group_list, link) { wl_list_for_each(workspace, &group->workspaces, link) { - zwlr_workspace_handle_v1_deactivate(workspace->handle); + zext_workspace_handle_v1_deactivate(workspace->handle); } } - zwlr_workspace_handle_v1_activate(focus->handle); - zwlr_workspace_manager_v1_commit(workspace_manager); + zext_workspace_handle_v1_activate(focus->handle); + zext_workspace_manager_v1_commit(workspace_manager); + } + + if (create_name != NULL) { + struct group_v1 *group; + wl_list_for_each(group, &group_list, link) { + zext_workspace_group_handle_v1_create_workspace(group->handle, create_name); + break; + } + } + + if (remove_name != NULL) { + struct workspace_v1 *remove = workspace_by_name_or_bail(remove_name); + zext_workspace_handle_v1_remove(remove->handle); } wl_display_flush(display); diff --git a/examples/meson.build b/examples/meson.build index e3d113fda..07ce91f5c 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -185,8 +185,8 @@ clients = { 'input-method-unstable-v2', ], }, - 'wlr-workspace': { - 'src': 'wlr-workspace.c', + 'ext-workspace': { + 'src': 'ext-workspace.c', 'dep': [wlroots], 'proto': ['ext-workspace-unstable-v1'], }, diff --git a/include/wlr/types/wlr_ext_workspace_v1.h b/include/wlr/types/wlr_ext_workspace_v1.h index b412cae6a..2ce74810b 100644 --- a/include/wlr/types/wlr_ext_workspace_v1.h +++ b/include/wlr/types/wlr_ext_workspace_v1.h @@ -40,12 +40,19 @@ struct wlr_ext_workspace_group_handle_v1 { struct wlr_ext_workspace_manager_v1 *manager; struct { + // wlr_ext_workspace_group_handle_v1_create_workspace_event + struct wl_signal create_workspace_request; struct wl_signal destroy; } events; void *data; }; +struct wlr_ext_workspace_group_handle_v1_create_workspace_event { + struct wlr_ext_workspace_group_handle_v1 *workspace_group; + const char *name; +}; + struct wlr_ext_workspace_group_handle_v1_output { struct wl_list link; // wlr_ext_workspace_group_handle_v1::outputs struct wl_listener output_destroy; @@ -77,6 +84,7 @@ struct wlr_ext_workspace_handle_v1 { struct wl_array coordinates; struct { + struct wl_signal remove_request; struct wl_signal destroy; } events; diff --git a/types/wlr_ext_workspace_v1.c b/types/wlr_ext_workspace_v1.c index a5febefec..352e7d8b4 100644 --- a/types/wlr_ext_workspace_v1.c +++ b/types/wlr_ext_workspace_v1.c @@ -33,6 +33,8 @@ static void workspace_manager_update_idle_source( } static const struct zext_workspace_handle_v1_interface workspace_handle_impl; +static const struct zext_workspace_group_handle_v1_interface workspace_group_impl; + static struct wlr_ext_workspace_handle_v1 *workspace_from_resource( struct wl_resource *resource) { assert(wl_resource_instance_of(resource, @@ -41,6 +43,14 @@ static struct wlr_ext_workspace_handle_v1 *workspace_from_resource( return wl_resource_get_user_data(resource); } +static struct wlr_ext_workspace_group_handle_v1 *workspace_group_from_resource( + struct wl_resource *resource) { + assert(wl_resource_instance_of(resource, + &zext_workspace_group_handle_v1_interface, + &workspace_group_impl)); + return wl_resource_get_user_data(resource); +} + static void workspace_handle_destroy(struct wl_client *client, struct wl_resource *resource) { wl_resource_destroy(resource); @@ -56,6 +66,16 @@ static void workspace_handle_activate(struct wl_client *client, workspace->pending |= WLR_EXT_WORKSPACE_HANDLE_V1_STATE_ACTIVE; } +static void workspace_handle_remove(struct wl_client *client, + struct wl_resource *resource) { + struct wlr_ext_workspace_handle_v1 *workspace = workspace_from_resource(resource); + if (!workspace) { + return; + } + + wlr_signal_emit_safe(&workspace->events.remove_request, NULL); +} + static void workspace_handle_deactivate(struct wl_client *client, struct wl_resource *resource) { struct wlr_ext_workspace_handle_v1 *workspace = workspace_from_resource(resource); @@ -123,6 +143,7 @@ static const struct zext_workspace_handle_v1_interface workspace_handle_impl = { .destroy = workspace_handle_destroy, .activate = workspace_handle_activate, .deactivate = workspace_handle_deactivate, + .remove = workspace_handle_remove, }; void wlr_ext_workspace_handle_v1_set_name(struct wlr_ext_workspace_handle_v1 *workspace, @@ -240,6 +261,7 @@ struct wlr_ext_workspace_handle_v1 *wlr_ext_workspace_handle_v1_create( wl_list_insert(&group->workspaces, &workspace->link); wl_array_init(&workspace->coordinates); wl_list_init(&workspace->resources); + wl_signal_init(&workspace->events.remove_request); wl_signal_init(&workspace->events.destroy); struct wl_resource *tmp, *group_resource; @@ -274,13 +296,25 @@ void wlr_ext_workspace_handle_v1_destroy( free(workspace->name); } +static void workspace_group_handle_handle_create_workspace(struct wl_client *client, + struct wl_resource *resource, const char *arg) { + struct wlr_ext_workspace_group_handle_v1 *group = + workspace_group_from_resource(resource); + + struct wlr_ext_workspace_group_handle_v1_create_workspace_event event; + event.workspace_group = group; + event.name = arg; + wlr_signal_emit_safe(&group->events.create_workspace_request, &event); +} + static void workspace_group_handle_handle_destroy(struct wl_client *client, struct wl_resource *resource) { wl_resource_destroy(resource); } -const struct zext_workspace_group_handle_v1_interface workspace_group_impl = { - .destroy = workspace_group_handle_handle_destroy, +static const struct zext_workspace_group_handle_v1_interface workspace_group_impl = { + .create_workspace = workspace_group_handle_handle_create_workspace, + .destroy = workspace_group_handle_handle_destroy, }; static void workspace_group_resource_destroy(struct wl_resource *resource) { @@ -428,6 +462,7 @@ struct wlr_ext_workspace_group_handle_v1 *wlr_ext_workspace_group_handle_v1_crea wl_list_init(&group->outputs); wl_list_init(&group->resources); wl_list_init(&group->workspaces); + wl_signal_init(&group->events.create_workspace_request); wl_signal_init(&group->events.destroy); struct wl_resource *tmp, *manager_resource;