From b9a2e4ba4c92cd4c19f8cf5ed7e6603731eca9ab Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 21 Nov 2018 10:59:11 +0100 Subject: gtk-primary-selection: support multiple devices When a client was creating multiple data devices for the same seat, we were only creating one resource. This is a protocol error. Instead, create one offer per data device. This commit also makes offers inert when their source is destroyed. Fixes part of https://github.com/swaywm/wlroots/issues/1041 Supersedes https://github.com/swaywm/wlroots/pull/1113 --- include/wlr/types/wlr_primary_selection.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/wlr') diff --git a/include/wlr/types/wlr_primary_selection.h b/include/wlr/types/wlr_primary_selection.h index f33f6368..c11e2fab 100644 --- a/include/wlr/types/wlr_primary_selection.h +++ b/include/wlr/types/wlr_primary_selection.h @@ -24,8 +24,6 @@ struct wlr_primary_selection_device_manager { void *data; }; -struct wlr_primary_selection_offer; - struct wlr_primary_selection_source { // source metadata struct wl_array mime_types; @@ -36,7 +34,6 @@ struct wlr_primary_selection_source { void (*cancel)(struct wlr_primary_selection_source *source); // source status - struct wlr_primary_selection_offer *offer; struct wlr_seat_client *seat_client; struct { -- cgit v1.2.3 From eaafd65a12d6b15cc8e503ef6e9e99a65bd1e791 Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 21 Nov 2018 11:15:35 +0100 Subject: gtk-primary-selection: track resources --- include/wlr/types/wlr_primary_selection.h | 1 + types/wlr_primary_selection.c | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) (limited to 'include/wlr') diff --git a/include/wlr/types/wlr_primary_selection.h b/include/wlr/types/wlr_primary_selection.h index c11e2fab..192bfc02 100644 --- a/include/wlr/types/wlr_primary_selection.h +++ b/include/wlr/types/wlr_primary_selection.h @@ -14,6 +14,7 @@ struct wlr_primary_selection_device_manager { struct wl_global *global; + struct wl_list resources; struct wl_listener display_destroy; diff --git a/types/wlr_primary_selection.c b/types/wlr_primary_selection.c index 0539773b..74312540 100644 --- a/types/wlr_primary_selection.c +++ b/types/wlr_primary_selection.c @@ -212,6 +212,7 @@ void wlr_seat_set_primary_selection(struct wlr_seat *seat, return; } + // TODO: make all offers inert if (seat->primary_selection_source) { wl_list_remove(&seat->primary_selection_source_destroy.link); seat->primary_selection_source->cancel(seat->primary_selection_source); @@ -349,12 +350,17 @@ static void device_manager_handle_destroy(struct wl_client *client, } static const struct gtk_primary_selection_device_manager_interface -device_manager_impl = { + device_manager_impl = { .create_source = device_manager_handle_create_source, .get_device = device_manager_handle_get_device, .destroy = device_manager_handle_destroy, }; +static void device_manager_handle_resource_destroy( + struct wl_resource *resource) { + wl_list_remove(wl_resource_get_link(resource)); +} + static void primary_selection_device_manager_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id) { @@ -367,7 +373,9 @@ static void primary_selection_device_manager_bind(struct wl_client *client, return; } wl_resource_set_implementation(resource, &device_manager_impl, manager, - NULL); + device_manager_handle_resource_destroy); + + wl_list_insert(&manager->resources, wl_resource_get_link(resource)); } static void handle_display_destroy(struct wl_listener *listener, void *data) { @@ -392,6 +400,7 @@ struct wlr_primary_selection_device_manager * return NULL; } + wl_list_init(&manager->resources); wl_signal_init(&manager->events.destroy); manager->display_destroy.notify = handle_display_destroy; @@ -407,7 +416,10 @@ void wlr_primary_selection_device_manager_destroy( } wlr_signal_emit_safe(&manager->events.destroy, manager); wl_list_remove(&manager->display_destroy.link); - // TODO: free resources + struct wl_resource *resource, *resource_tmp; + wl_resource_for_each_safe(resource, resource_tmp, &manager->resources) { + wl_resource_destroy(resource); + } wl_global_destroy(manager->global); free(manager); } -- cgit v1.2.3