primary-selection: introduce wlr_primary_selection_source
This is a common interface that can be used for all primary selection protocols, as discussed in [1]. A new function wlr_seat_set_primary_selection is added to set the primary selection for all protocols. The seat now owns again the source, and resets the selection to NULL when destroyed. [1]: https://github.com/swaywm/wlroots/issues/1367#issuecomment-442403454
This commit is contained in:
		
							parent
							
								
									658b590567
								
							
						
					
					
						commit
						9f0720c03a
					
				|  | @ -23,6 +23,7 @@ install_headers( | ||||||
| 	'wlr_output.h', | 	'wlr_output.h', | ||||||
| 	'wlr_pointer.h', | 	'wlr_pointer.h', | ||||||
| 	'wlr_presentation_time.h', | 	'wlr_presentation_time.h', | ||||||
|  | 	'wlr_primary_selection.h', | ||||||
| 	'wlr_region.h', | 	'wlr_region.h', | ||||||
| 	'wlr_screencopy_v1.h', | 	'wlr_screencopy_v1.h', | ||||||
| 	'wlr_screenshooter.h', | 	'wlr_screenshooter.h', | ||||||
|  |  | ||||||
|  | @ -35,37 +35,11 @@ struct wlr_gtk_primary_selection_device { | ||||||
| 	struct wl_list link; // wlr_gtk_primary_selection_device_manager::devices
 | 	struct wl_list link; // wlr_gtk_primary_selection_device_manager::devices
 | ||||||
| 	struct wl_list resources; // wl_resource_get_link
 | 	struct wl_list resources; // wl_resource_get_link
 | ||||||
| 
 | 
 | ||||||
| 	struct wlr_gtk_primary_selection_source *source; |  | ||||||
| 	struct wl_list offers; // wl_resource_get_link
 | 	struct wl_list offers; // wl_resource_get_link
 | ||||||
| 
 | 
 | ||||||
| 	struct wl_listener seat_destroy; | 	struct wl_listener seat_destroy; | ||||||
| 	struct wl_listener seat_focus_change; | 	struct wl_listener seat_focus_change; | ||||||
| 	struct wl_listener source_destroy; | 	struct wl_listener seat_primary_selection; | ||||||
| 
 |  | ||||||
| 	void *data; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * A data source implementation. Only the `send` function is mandatory. |  | ||||||
|  */ |  | ||||||
| struct wlr_gtk_primary_selection_source_impl { |  | ||||||
| 	void (*send)(struct wlr_gtk_primary_selection_source *source, |  | ||||||
| 		const char *mime_type, int fd); |  | ||||||
| 	void (*destroy)(struct wlr_gtk_primary_selection_source *source); |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| /**
 |  | ||||||
|  * A source is the sending side of a selection. |  | ||||||
|  */ |  | ||||||
| struct wlr_gtk_primary_selection_source { |  | ||||||
| 	const struct wlr_gtk_primary_selection_source_impl *impl; |  | ||||||
| 
 |  | ||||||
| 	// source metadata
 |  | ||||||
| 	struct wl_array mime_types; |  | ||||||
| 
 |  | ||||||
| 	struct { |  | ||||||
| 		struct wl_signal destroy; |  | ||||||
| 	} events; |  | ||||||
| 
 | 
 | ||||||
| 	void *data; | 	void *data; | ||||||
| }; | }; | ||||||
|  | @ -75,18 +49,4 @@ struct wlr_gtk_primary_selection_device_manager * | ||||||
| void wlr_gtk_primary_selection_device_manager_destroy( | void wlr_gtk_primary_selection_device_manager_destroy( | ||||||
| 	struct wlr_gtk_primary_selection_device_manager *manager); | 	struct wlr_gtk_primary_selection_device_manager *manager); | ||||||
| 
 | 
 | ||||||
| void wlr_gtk_primary_selection_device_manager_set_selection( |  | ||||||
| 	struct wlr_gtk_primary_selection_device_manager *manager, |  | ||||||
| 	struct wlr_seat *seat, |  | ||||||
| 	struct wlr_gtk_primary_selection_source *source); |  | ||||||
| 
 |  | ||||||
| void wlr_gtk_primary_selection_source_init( |  | ||||||
| 	struct wlr_gtk_primary_selection_source *source, |  | ||||||
| 	const struct wlr_gtk_primary_selection_source_impl *impl); |  | ||||||
| void wlr_gtk_primary_selection_source_destroy( |  | ||||||
| 	struct wlr_gtk_primary_selection_source *source); |  | ||||||
| void wlr_gtk_primary_selection_source_send( |  | ||||||
| 	struct wlr_gtk_primary_selection_source *source, const char *mime_type, |  | ||||||
| 	int fd); |  | ||||||
| 
 |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | @ -0,0 +1,54 @@ | ||||||
|  | /*
 | ||||||
|  |  * 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_PRIMARY_SELECTION_H | ||||||
|  | #define WLR_TYPES_WLR_PRIMARY_SELECTION_H | ||||||
|  | 
 | ||||||
|  | #include <wayland-server.h> | ||||||
|  | #include <wlr/types/wlr_seat.h> | ||||||
|  | 
 | ||||||
|  | struct wlr_primary_selection_source; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * A data source implementation. Only the `send` function is mandatory. | ||||||
|  |  */ | ||||||
|  | struct wlr_primary_selection_source_impl { | ||||||
|  | 	void (*send)(struct wlr_primary_selection_source *source, | ||||||
|  | 		const char *mime_type, int fd); | ||||||
|  | 	void (*destroy)(struct wlr_primary_selection_source *source); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  * A source is the sending side of a selection. | ||||||
|  |  */ | ||||||
|  | struct wlr_primary_selection_source { | ||||||
|  | 	const struct wlr_primary_selection_source_impl *impl; | ||||||
|  | 
 | ||||||
|  | 	// source metadata
 | ||||||
|  | 	struct wl_array mime_types; | ||||||
|  | 
 | ||||||
|  | 	struct { | ||||||
|  | 		struct wl_signal destroy; | ||||||
|  | 	} events; | ||||||
|  | 
 | ||||||
|  | 	void *data; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | void wlr_primary_selection_source_init( | ||||||
|  | 	struct wlr_primary_selection_source *source, | ||||||
|  | 	const struct wlr_primary_selection_source_impl *impl); | ||||||
|  | void wlr_primary_selection_source_destroy( | ||||||
|  | 	struct wlr_primary_selection_source *source); | ||||||
|  | void wlr_primary_selection_source_send( | ||||||
|  | 	struct wlr_primary_selection_source *source, const char *mime_type, | ||||||
|  | 	int fd); | ||||||
|  | 
 | ||||||
|  | void wlr_seat_set_primary_selection(struct wlr_seat *seat, | ||||||
|  | 	struct wlr_primary_selection_source *source); | ||||||
|  | 
 | ||||||
|  | #endif | ||||||
|  | @ -184,6 +184,8 @@ struct wlr_seat_touch_state { | ||||||
| 	struct wlr_seat_touch_grab *default_grab; | 	struct wlr_seat_touch_grab *default_grab; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | struct wlr_primary_selection_source; | ||||||
|  | 
 | ||||||
| struct wlr_seat { | struct wlr_seat { | ||||||
| 	struct wl_global *global; | 	struct wl_global *global; | ||||||
| 	struct wl_display *display; | 	struct wl_display *display; | ||||||
|  | @ -197,8 +199,7 @@ struct wlr_seat { | ||||||
| 	struct wlr_data_source *selection_source; | 	struct wlr_data_source *selection_source; | ||||||
| 	uint32_t selection_serial; | 	uint32_t selection_serial; | ||||||
| 
 | 
 | ||||||
| 	// not owned by the seat
 | 	struct wlr_primary_selection_source *primary_selection_source; | ||||||
| 	struct wlr_gtk_primary_selection_source *primary_selection_source; |  | ||||||
| 
 | 
 | ||||||
| 	// `drag` goes away before `drag_source`, when the implicit grab ends
 | 	// `drag` goes away before `drag_source`, when the implicit grab ends
 | ||||||
| 	struct wlr_drag *drag; | 	struct wlr_drag *drag; | ||||||
|  | @ -211,6 +212,7 @@ struct wlr_seat { | ||||||
| 
 | 
 | ||||||
| 	struct wl_listener display_destroy; | 	struct wl_listener display_destroy; | ||||||
| 	struct wl_listener selection_source_destroy; | 	struct wl_listener selection_source_destroy; | ||||||
|  | 	struct wl_listener primary_selection_source_destroy; | ||||||
| 	struct wl_listener drag_source_destroy; | 	struct wl_listener drag_source_destroy; | ||||||
| 
 | 
 | ||||||
| 	struct { | 	struct { | ||||||
|  |  | ||||||
|  | @ -43,7 +43,6 @@ struct wlr_xwayland { | ||||||
| 	struct wl_display *wl_display; | 	struct wl_display *wl_display; | ||||||
| 	struct wlr_compositor *compositor; | 	struct wlr_compositor *compositor; | ||||||
| 	struct wlr_seat *seat; | 	struct wlr_seat *seat; | ||||||
| 	struct wlr_gtk_primary_selection_device_manager *gtk_primary_selection; |  | ||||||
| 
 | 
 | ||||||
| 	struct { | 	struct { | ||||||
| 		struct wl_signal ready; | 		struct wl_signal ready; | ||||||
|  | @ -226,10 +225,6 @@ void wlr_xwayland_surface_set_fullscreen(struct wlr_xwayland_surface *surface, | ||||||
| void wlr_xwayland_set_seat(struct wlr_xwayland *xwayland, | void wlr_xwayland_set_seat(struct wlr_xwayland *xwayland, | ||||||
| 	struct wlr_seat *seat); | 	struct wlr_seat *seat); | ||||||
| 
 | 
 | ||||||
| void wlr_xwayland_set_gtk_primary_selection_device_manager( |  | ||||||
| 	struct wlr_xwayland *xwayland, |  | ||||||
| 	struct wlr_gtk_primary_selection_device_manager *manager); |  | ||||||
| 
 |  | ||||||
| bool wlr_surface_is_xwayland_surface(struct wlr_surface *surface); | bool wlr_surface_is_xwayland_surface(struct wlr_surface *surface); | ||||||
| 
 | 
 | ||||||
| struct wlr_xwayland_surface *wlr_xwayland_surface_from_wlr_surface( | struct wlr_xwayland_surface *wlr_xwayland_surface_from_wlr_surface( | ||||||
|  |  | ||||||
|  | @ -7,6 +7,8 @@ | ||||||
| 
 | 
 | ||||||
| #define XDND_VERSION 5 | #define XDND_VERSION 5 | ||||||
| 
 | 
 | ||||||
|  | struct wlr_primary_selection_source; | ||||||
|  | 
 | ||||||
| struct wlr_xwm_selection; | struct wlr_xwm_selection; | ||||||
| 
 | 
 | ||||||
| struct wlr_xwm_selection_transfer { | struct wlr_xwm_selection_transfer { | ||||||
|  | @ -62,7 +64,7 @@ int xwm_handle_xfixes_selection_notify(struct wlr_xwm *xwm, | ||||||
| 	xcb_xfixes_selection_notify_event_t *event); | 	xcb_xfixes_selection_notify_event_t *event); | ||||||
| bool data_source_is_xwayland(struct wlr_data_source *wlr_source); | bool data_source_is_xwayland(struct wlr_data_source *wlr_source); | ||||||
| bool primary_selection_source_is_xwayland( | bool primary_selection_source_is_xwayland( | ||||||
| 	struct wlr_gtk_primary_selection_source *wlr_source); | 	struct wlr_primary_selection_source *wlr_source); | ||||||
| 
 | 
 | ||||||
| void xwm_seat_handle_start_drag(struct wlr_xwm *xwm, struct wlr_drag *drag); | void xwm_seat_handle_start_drag(struct wlr_xwm *xwm, struct wlr_drag *drag); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -957,16 +957,8 @@ struct roots_desktop *desktop_create(struct roots_server *server, | ||||||
| 		WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT); | 		WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT); | ||||||
| 	desktop->idle = wlr_idle_create(server->wl_display); | 	desktop->idle = wlr_idle_create(server->wl_display); | ||||||
| 	desktop->idle_inhibit = wlr_idle_inhibit_v1_create(server->wl_display); | 	desktop->idle_inhibit = wlr_idle_inhibit_v1_create(server->wl_display); | ||||||
| 
 |  | ||||||
| 	desktop->primary_selection_device_manager = | 	desktop->primary_selection_device_manager = | ||||||
| 		wlr_gtk_primary_selection_device_manager_create(server->wl_display); | 		wlr_gtk_primary_selection_device_manager_create(server->wl_display); | ||||||
| #if WLR_HAS_XWAYLAND |  | ||||||
| 	if (desktop->xwayland != NULL) { |  | ||||||
| 		wlr_xwayland_set_gtk_primary_selection_device_manager( |  | ||||||
| 			desktop->xwayland, desktop->primary_selection_device_manager); |  | ||||||
| 	} |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| 	desktop->input_inhibit = | 	desktop->input_inhibit = | ||||||
| 		wlr_input_inhibit_manager_create(server->wl_display); | 		wlr_input_inhibit_manager_create(server->wl_display); | ||||||
| 	desktop->input_inhibit_activate.notify = input_inhibit_activate; | 	desktop->input_inhibit_activate.notify = input_inhibit_activate; | ||||||
|  |  | ||||||
|  | @ -30,6 +30,7 @@ lib_wlr_types = static_library( | ||||||
| 		'wlr_export_dmabuf_v1.c', | 		'wlr_export_dmabuf_v1.c', | ||||||
| 		'wlr_gamma_control_v1.c', | 		'wlr_gamma_control_v1.c', | ||||||
| 		'wlr_gamma_control.c', | 		'wlr_gamma_control.c', | ||||||
|  | 		'wlr_gtk_primary_selection.c', | ||||||
| 		'wlr_idle_inhibit_v1.c', | 		'wlr_idle_inhibit_v1.c', | ||||||
| 		'wlr_idle.c', | 		'wlr_idle.c', | ||||||
| 		'wlr_input_device.c', | 		'wlr_input_device.c', | ||||||
|  | @ -46,7 +47,7 @@ lib_wlr_types = static_library( | ||||||
| 		'wlr_pointer_constraints_v1.c', | 		'wlr_pointer_constraints_v1.c', | ||||||
| 		'wlr_pointer.c', | 		'wlr_pointer.c', | ||||||
| 		'wlr_presentation_time.c', | 		'wlr_presentation_time.c', | ||||||
| 		'wlr_gtk_primary_selection.c', | 		'wlr_primary_selection.c', | ||||||
| 		'wlr_region.c', | 		'wlr_region.c', | ||||||
| 		'wlr_screencopy_v1.c', | 		'wlr_screencopy_v1.c', | ||||||
| 		'wlr_screenshooter.c', | 		'wlr_screenshooter.c', | ||||||
|  |  | ||||||
|  | @ -6,6 +6,7 @@ | ||||||
| #include <wayland-server.h> | #include <wayland-server.h> | ||||||
| #include <wlr/types/wlr_data_device.h> | #include <wlr/types/wlr_data_device.h> | ||||||
| #include <wlr/types/wlr_input_device.h> | #include <wlr/types/wlr_input_device.h> | ||||||
|  | #include <wlr/types/wlr_primary_selection.h> | ||||||
| #include <wlr/types/wlr_seat.h> | #include <wlr/types/wlr_seat.h> | ||||||
| #include <wlr/util/log.h> | #include <wlr/util/log.h> | ||||||
| #include "types/wlr_seat.h" | #include "types/wlr_seat.h" | ||||||
|  | @ -162,6 +163,8 @@ void wlr_seat_destroy(struct wlr_seat *seat) { | ||||||
| 		seat->selection_source = NULL; | 		seat->selection_source = NULL; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	wlr_seat_set_primary_selection(seat, NULL); | ||||||
|  | 
 | ||||||
| 	struct wlr_seat_client *client, *tmp; | 	struct wlr_seat_client *client, *tmp; | ||||||
| 	wl_list_for_each_safe(client, tmp, &seat->clients, link) { | 	wl_list_for_each_safe(client, tmp, &seat->clients, link) { | ||||||
| 		struct wl_resource *resource, *next; | 		struct wl_resource *resource, *next; | ||||||
|  |  | ||||||
|  | @ -4,6 +4,7 @@ | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include <wlr/types/wlr_gtk_primary_selection.h> | #include <wlr/types/wlr_gtk_primary_selection.h> | ||||||
|  | #include <wlr/types/wlr_primary_selection.h> | ||||||
| #include <wlr/types/wlr_seat.h> | #include <wlr/types/wlr_seat.h> | ||||||
| #include <wlr/util/log.h> | #include <wlr/util/log.h> | ||||||
| #include "gtk-primary-selection-protocol.h" | #include "gtk-primary-selection-protocol.h" | ||||||
|  | @ -24,12 +25,13 @@ static void offer_handle_receive(struct wl_client *client, | ||||||
| 		struct wl_resource *resource, const char *mime_type, int32_t fd) { | 		struct wl_resource *resource, const char *mime_type, int32_t fd) { | ||||||
| 	struct wlr_gtk_primary_selection_device *device = | 	struct wlr_gtk_primary_selection_device *device = | ||||||
| 		device_from_offer_resource(resource); | 		device_from_offer_resource(resource); | ||||||
| 	if (device == NULL || device->source == NULL) { | 	if (device == NULL || device->seat->primary_selection_source == NULL) { | ||||||
| 		close(fd); | 		close(fd); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	wlr_gtk_primary_selection_source_send(device->source, mime_type, fd); | 	wlr_primary_selection_source_send(device->seat->primary_selection_source, | ||||||
|  | 		mime_type, fd); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void offer_handle_destroy(struct wl_client *client, | static void offer_handle_destroy(struct wl_client *client, | ||||||
|  | @ -50,7 +52,7 @@ static struct wlr_gtk_primary_selection_device *device_from_resource( | ||||||
| 	struct wl_resource *resource); | 	struct wl_resource *resource); | ||||||
| 
 | 
 | ||||||
| static void create_offer(struct wl_resource *device_resource, | static void create_offer(struct wl_resource *device_resource, | ||||||
| 		struct wlr_gtk_primary_selection_source *source) { | 		struct wlr_primary_selection_source *source) { | ||||||
| 	struct wlr_gtk_primary_selection_device *device = | 	struct wlr_gtk_primary_selection_device *device = | ||||||
| 		device_from_resource(device_resource); | 		device_from_resource(device_resource); | ||||||
| 	assert(device != NULL); | 	assert(device != NULL); | ||||||
|  | @ -93,12 +95,12 @@ static void destroy_offer(struct wl_resource *resource) { | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| struct client_data_source { | struct client_data_source { | ||||||
| 	struct wlr_gtk_primary_selection_source source; | 	struct wlr_primary_selection_source source; | ||||||
| 	struct wl_resource *resource; | 	struct wl_resource *resource; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static void client_source_send( | static void client_source_send( | ||||||
| 		struct wlr_gtk_primary_selection_source *wlr_source, | 		struct wlr_primary_selection_source *wlr_source, | ||||||
| 		const char *mime_type, int fd) { | 		const char *mime_type, int fd) { | ||||||
| 	struct client_data_source *source = (struct client_data_source *)wlr_source; | 	struct client_data_source *source = (struct client_data_source *)wlr_source; | ||||||
| 	gtk_primary_selection_source_send_send(source->resource, mime_type, fd); | 	gtk_primary_selection_source_send_send(source->resource, mime_type, fd); | ||||||
|  | @ -106,7 +108,7 @@ static void client_source_send( | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void client_source_destroy( | static void client_source_destroy( | ||||||
| 		struct wlr_gtk_primary_selection_source *wlr_source) { | 		struct wlr_primary_selection_source *wlr_source) { | ||||||
| 	struct client_data_source *source = (struct client_data_source *)wlr_source; | 	struct client_data_source *source = (struct client_data_source *)wlr_source; | ||||||
| 	gtk_primary_selection_source_send_cancelled(source->resource); | 	gtk_primary_selection_source_send_cancelled(source->resource); | ||||||
| 	// Make the source resource inert
 | 	// Make the source resource inert
 | ||||||
|  | @ -114,7 +116,7 @@ static void client_source_destroy( | ||||||
| 	free(source); | 	free(source); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const struct wlr_gtk_primary_selection_source_impl client_source_impl = { | static const struct wlr_primary_selection_source_impl client_source_impl = { | ||||||
| 	.send = client_source_send, | 	.send = client_source_send, | ||||||
| 	.destroy = client_source_destroy, | 	.destroy = client_source_destroy, | ||||||
| }; | }; | ||||||
|  | @ -136,16 +138,20 @@ static void source_handle_offer(struct wl_client *client, | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	char **p = wl_array_add(&source->source.mime_types, sizeof(*p)); | 	char *dup_mime_type = strdup(mime_type); | ||||||
| 	if (p) { | 	if (dup_mime_type == NULL) { | ||||||
| 		*p = strdup(mime_type); |  | ||||||
| 	} |  | ||||||
| 	if (p == NULL || *p == NULL) { |  | ||||||
| 		if (p) { |  | ||||||
| 			source->source.mime_types.size -= sizeof(*p); |  | ||||||
| 		} |  | ||||||
| 		wl_resource_post_no_memory(resource); | 		wl_resource_post_no_memory(resource); | ||||||
|  | 		return; | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	char **p = wl_array_add(&source->source.mime_types, sizeof(*p)); | ||||||
|  | 	if (p == NULL) { | ||||||
|  | 		free(dup_mime_type); | ||||||
|  | 		wl_resource_post_no_memory(resource); | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	*p = dup_mime_type; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void source_handle_destroy(struct wl_client *client, | static void source_handle_destroy(struct wl_client *client, | ||||||
|  | @ -164,7 +170,7 @@ static void source_resource_handle_destroy(struct wl_resource *resource) { | ||||||
| 	if (source == NULL) { | 	if (source == NULL) { | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 	wlr_gtk_primary_selection_source_destroy(&source->source); | 	wlr_primary_selection_source_destroy(&source->source); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -191,15 +197,14 @@ static void device_handle_set_selection(struct wl_client *client, | ||||||
| 		client_source = client_data_source_from_resource(source_resource); | 		client_source = client_data_source_from_resource(source_resource); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	struct wlr_gtk_primary_selection_source *source = NULL; | 	struct wlr_primary_selection_source *source = NULL; | ||||||
| 	if (client_source != NULL) { | 	if (client_source != NULL) { | ||||||
| 		source = &client_source->source; | 		source = &client_source->source; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// TODO: improve serial checking
 | 	// TODO: serial checking
 | ||||||
| 	struct wlr_seat *seat = device->seat; | 
 | ||||||
| 	wlr_gtk_primary_selection_device_manager_set_selection(device->manager, | 	wlr_seat_set_primary_selection(device->seat, source); | ||||||
| 		seat, source); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void device_handle_destroy(struct wl_client *client, | static void device_handle_destroy(struct wl_client *client, | ||||||
|  | @ -218,7 +223,7 @@ static void device_handle_resource_destroy(struct wl_resource *resource) { | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| static void device_resource_send_selection(struct wl_resource *resource, | static void device_resource_send_selection(struct wl_resource *resource, | ||||||
| 		struct wlr_gtk_primary_selection_source *source) { | 		struct wlr_primary_selection_source *source) { | ||||||
| 	assert(device_from_resource(resource) != NULL); | 	assert(device_from_resource(resource) != NULL); | ||||||
| 
 | 
 | ||||||
| 	if (source != NULL) { | 	if (source != NULL) { | ||||||
|  | @ -239,42 +244,12 @@ static void device_send_selection( | ||||||
| 	struct wl_resource *resource; | 	struct wl_resource *resource; | ||||||
| 	wl_resource_for_each(resource, &device->resources) { | 	wl_resource_for_each(resource, &device->resources) { | ||||||
| 		if (wl_resource_get_client(resource) == seat_client->client) { | 		if (wl_resource_get_client(resource) == seat_client->client) { | ||||||
| 			device_resource_send_selection(resource, device->source); | 			device_resource_send_selection(resource, | ||||||
|  | 				device->seat->primary_selection_source); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void device_handle_source_destroy(struct wl_listener *listener, |  | ||||||
| 	void *data); |  | ||||||
| 
 |  | ||||||
| static void device_set_selection( |  | ||||||
| 		struct wlr_gtk_primary_selection_device *device, |  | ||||||
| 		struct wlr_gtk_primary_selection_source *source) { |  | ||||||
| 	if (device->source != NULL) { |  | ||||||
| 		wl_list_remove(&device->source_destroy.link); |  | ||||||
| 		wlr_gtk_primary_selection_source_destroy(device->source); |  | ||||||
| 		device->source = NULL; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	struct wl_resource *resource, *tmp; |  | ||||||
| 	wl_resource_for_each_safe(resource, tmp, &device->offers) { |  | ||||||
| 		destroy_offer(resource); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	device->source = source; |  | ||||||
| 	if (source != NULL) { |  | ||||||
| 		device->source_destroy.notify = device_handle_source_destroy; |  | ||||||
| 		wl_signal_add(&source->events.destroy, &device->source_destroy); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	device_send_selection(device); |  | ||||||
| 
 |  | ||||||
| 	struct wlr_seat *seat = device->seat; |  | ||||||
| 	// TODO: remove these from wlr_seat
 |  | ||||||
| 	seat->primary_selection_source = source; |  | ||||||
| 	wlr_signal_emit_safe(&seat->events.primary_selection, seat); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void device_destroy(struct wlr_gtk_primary_selection_device *device); | static void device_destroy(struct wlr_gtk_primary_selection_device *device); | ||||||
| 
 | 
 | ||||||
| static void device_handle_seat_destroy(struct wl_listener *listener, | static void device_handle_seat_destroy(struct wl_listener *listener, | ||||||
|  | @ -293,12 +268,16 @@ static void device_handle_seat_focus_change(struct wl_listener *listener, | ||||||
| 	device_send_selection(device); | 	device_send_selection(device); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void device_handle_source_destroy(struct wl_listener *listener, | static void device_handle_seat_primary_selection(struct wl_listener *listener, | ||||||
| 		void *data) { | 		void *data) { | ||||||
| 	struct wlr_gtk_primary_selection_device *device = | 	struct wlr_gtk_primary_selection_device *device = | ||||||
| 		wl_container_of(listener, device, source_destroy); | 		wl_container_of(listener, device, seat_primary_selection); | ||||||
| 	wl_list_remove(&device->source_destroy.link); | 
 | ||||||
| 	device->source = NULL; | 	struct wl_resource *resource, *tmp; | ||||||
|  | 	wl_resource_for_each_safe(resource, tmp, &device->offers) { | ||||||
|  | 		destroy_offer(resource); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	device_send_selection(device); | 	device_send_selection(device); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -331,6 +310,11 @@ static struct wlr_gtk_primary_selection_device *get_or_create_device( | ||||||
| 	wl_signal_add(&seat->keyboard_state.events.focus_change, | 	wl_signal_add(&seat->keyboard_state.events.focus_change, | ||||||
| 		&device->seat_focus_change); | 		&device->seat_focus_change); | ||||||
| 
 | 
 | ||||||
|  | 	device->seat_primary_selection.notify = | ||||||
|  | 		device_handle_seat_primary_selection; | ||||||
|  | 	wl_signal_add(&seat->events.primary_selection, | ||||||
|  | 		&device->seat_primary_selection); | ||||||
|  | 
 | ||||||
| 	return device; | 	return device; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -341,10 +325,7 @@ static void device_destroy(struct wlr_gtk_primary_selection_device *device) { | ||||||
| 	wl_list_remove(&device->link); | 	wl_list_remove(&device->link); | ||||||
| 	wl_list_remove(&device->seat_destroy.link); | 	wl_list_remove(&device->seat_destroy.link); | ||||||
| 	wl_list_remove(&device->seat_focus_change.link); | 	wl_list_remove(&device->seat_focus_change.link); | ||||||
| 	if (device->source != NULL) { | 	wl_list_remove(&device->seat_primary_selection.link); | ||||||
| 		wl_list_remove(&device->source_destroy.link); |  | ||||||
| 		wlr_gtk_primary_selection_source_destroy(device->source); |  | ||||||
| 	} |  | ||||||
| 	struct wl_resource *resource, *resource_tmp; | 	struct wl_resource *resource, *resource_tmp; | ||||||
| 	wl_resource_for_each_safe(resource, resource_tmp, &device->offers) { | 	wl_resource_for_each_safe(resource, resource_tmp, &device->offers) { | ||||||
| 		destroy_offer(resource); | 		destroy_offer(resource); | ||||||
|  | @ -379,7 +360,7 @@ static void device_manager_handle_create_source(struct wl_client *client, | ||||||
| 		wl_client_post_no_memory(client); | 		wl_client_post_no_memory(client); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 	wlr_gtk_primary_selection_source_init(&source->source, &client_source_impl); | 	wlr_primary_selection_source_init(&source->source, &client_source_impl); | ||||||
| 
 | 
 | ||||||
| 	uint32_t version = wl_resource_get_version(manager_resource); | 	uint32_t version = wl_resource_get_version(manager_resource); | ||||||
| 	source->resource = wl_resource_create(client, | 	source->resource = wl_resource_create(client, | ||||||
|  | @ -420,7 +401,8 @@ void device_manager_handle_get_device(struct wl_client *client, | ||||||
| 	wl_list_insert(&device->resources, wl_resource_get_link(resource)); | 	wl_list_insert(&device->resources, wl_resource_get_link(resource)); | ||||||
| 
 | 
 | ||||||
| 	if (device->seat->keyboard_state.focused_client == seat_client) { | 	if (device->seat->keyboard_state.focused_client == seat_client) { | ||||||
| 		device_resource_send_selection(resource, device->source); | 		device_resource_send_selection(resource, | ||||||
|  | 			device->seat->primary_selection_source); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -442,18 +424,6 @@ static void device_manager_handle_resource_destroy( | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| void wlr_gtk_primary_selection_device_manager_set_selection( |  | ||||||
| 		struct wlr_gtk_primary_selection_device_manager *manager, |  | ||||||
| 		struct wlr_seat *seat, |  | ||||||
| 		struct wlr_gtk_primary_selection_source *source) { |  | ||||||
| 	struct wlr_gtk_primary_selection_device *device = |  | ||||||
| 		get_or_create_device(manager, seat); |  | ||||||
| 	if (device == NULL) { |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
| 	device_set_selection(device, source); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void primary_selection_device_manager_bind(struct wl_client *client, | static void primary_selection_device_manager_bind(struct wl_client *client, | ||||||
| 		void *data, uint32_t version, uint32_t id) { | 		void *data, uint32_t version, uint32_t id) { | ||||||
| 	struct wlr_gtk_primary_selection_device_manager *manager = data; | 	struct wlr_gtk_primary_selection_device_manager *manager = data; | ||||||
|  | @ -516,40 +486,3 @@ void wlr_gtk_primary_selection_device_manager_destroy( | ||||||
| 	wl_global_destroy(manager->global); | 	wl_global_destroy(manager->global); | ||||||
| 	free(manager); | 	free(manager); | ||||||
| } | } | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| void wlr_gtk_primary_selection_source_init( |  | ||||||
| 		struct wlr_gtk_primary_selection_source *source, |  | ||||||
| 		const struct wlr_gtk_primary_selection_source_impl *impl) { |  | ||||||
| 	assert(impl->send); |  | ||||||
| 	wl_array_init(&source->mime_types); |  | ||||||
| 	wl_signal_init(&source->events.destroy); |  | ||||||
| 	source->impl = impl; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void wlr_gtk_primary_selection_source_destroy( |  | ||||||
| 		struct wlr_gtk_primary_selection_source *source) { |  | ||||||
| 	if (source == NULL) { |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	wlr_signal_emit_safe(&source->events.destroy, source); |  | ||||||
| 
 |  | ||||||
| 	char **p; |  | ||||||
| 	wl_array_for_each(p, &source->mime_types) { |  | ||||||
| 		free(*p); |  | ||||||
| 	} |  | ||||||
| 	wl_array_release(&source->mime_types); |  | ||||||
| 
 |  | ||||||
| 	if (source->impl->destroy) { |  | ||||||
| 		source->impl->destroy(source); |  | ||||||
| 	} else { |  | ||||||
| 		free(source); |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void wlr_gtk_primary_selection_source_send( |  | ||||||
| 		struct wlr_gtk_primary_selection_source *source, const char *mime_type, |  | ||||||
| 		int32_t fd) { |  | ||||||
| 	source->impl->send(source, mime_type, fd); |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  | @ -0,0 +1,69 @@ | ||||||
|  | #include <assert.h> | ||||||
|  | #include <stdlib.h> | ||||||
|  | #include <wlr/types/wlr_primary_selection.h> | ||||||
|  | #include "util/signal.h" | ||||||
|  | 
 | ||||||
|  | void wlr_primary_selection_source_init( | ||||||
|  | 		struct wlr_primary_selection_source *source, | ||||||
|  | 		const struct wlr_primary_selection_source_impl *impl) { | ||||||
|  | 	assert(impl->send); | ||||||
|  | 	wl_array_init(&source->mime_types); | ||||||
|  | 	wl_signal_init(&source->events.destroy); | ||||||
|  | 	source->impl = impl; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void wlr_primary_selection_source_destroy( | ||||||
|  | 		struct wlr_primary_selection_source *source) { | ||||||
|  | 	if (source == NULL) { | ||||||
|  | 		return; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	wlr_signal_emit_safe(&source->events.destroy, source); | ||||||
|  | 
 | ||||||
|  | 	char **p; | ||||||
|  | 	wl_array_for_each(p, &source->mime_types) { | ||||||
|  | 		free(*p); | ||||||
|  | 	} | ||||||
|  | 	wl_array_release(&source->mime_types); | ||||||
|  | 
 | ||||||
|  | 	if (source->impl->destroy) { | ||||||
|  | 		source->impl->destroy(source); | ||||||
|  | 	} else { | ||||||
|  | 		free(source); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void wlr_primary_selection_source_send( | ||||||
|  | 		struct wlr_primary_selection_source *source, const char *mime_type, | ||||||
|  | 		int32_t fd) { | ||||||
|  | 	source->impl->send(source, mime_type, fd); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | static void seat_handle_primary_selection_source_destroy( | ||||||
|  | 		struct wl_listener *listener, void *data) { | ||||||
|  | 	struct wlr_seat *seat = | ||||||
|  | 		wl_container_of(listener, seat, primary_selection_source_destroy); | ||||||
|  | 	wl_list_remove(&seat->primary_selection_source_destroy.link); | ||||||
|  | 	seat->primary_selection_source = NULL; | ||||||
|  | 	wlr_signal_emit_safe(&seat->events.primary_selection, seat); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void wlr_seat_set_primary_selection(struct wlr_seat *seat, | ||||||
|  | 		struct wlr_primary_selection_source *source) { | ||||||
|  | 	if (seat->primary_selection_source != NULL) { | ||||||
|  | 		wl_list_remove(&seat->primary_selection_source_destroy.link); | ||||||
|  | 		wlr_primary_selection_source_destroy(seat->primary_selection_source); | ||||||
|  | 		seat->primary_selection_source = NULL; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	seat->primary_selection_source = source; | ||||||
|  | 	if (source != NULL) { | ||||||
|  | 		seat->primary_selection_source_destroy.notify = | ||||||
|  | 			seat_handle_primary_selection_source_destroy; | ||||||
|  | 		wl_signal_add(&source->events.destroy, | ||||||
|  | 			&seat->primary_selection_source_destroy); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	wlr_signal_emit_safe(&seat->events.primary_selection, seat); | ||||||
|  | } | ||||||
|  | @ -5,11 +5,11 @@ | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include <wlr/types/wlr_data_device.h> | #include <wlr/types/wlr_data_device.h> | ||||||
| #include <wlr/types/wlr_gtk_primary_selection.h> | #include <wlr/types/wlr_primary_selection.h> | ||||||
| #include <wlr/util/log.h> | #include <wlr/util/log.h> | ||||||
| #include <xcb/xfixes.h> | #include <xcb/xfixes.h> | ||||||
| #include "xwayland/xwm.h" |  | ||||||
| #include "xwayland/selection.h" | #include "xwayland/selection.h" | ||||||
|  | #include "xwayland/xwm.h" | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Write the X11 selection to a Wayland client. |  * Write the X11 selection to a Wayland client. | ||||||
|  | @ -217,21 +217,21 @@ static const struct wlr_data_source_impl data_source_impl = { | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| struct x11_primary_selection_source { | struct x11_primary_selection_source { | ||||||
| 	struct wlr_gtk_primary_selection_source base; | 	struct wlr_primary_selection_source base; | ||||||
| 	struct wlr_xwm_selection *selection; | 	struct wlr_xwm_selection *selection; | ||||||
| 	struct wl_array mime_types_atoms; | 	struct wl_array mime_types_atoms; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static const struct wlr_gtk_primary_selection_source_impl | static const struct wlr_primary_selection_source_impl | ||||||
| 	primary_selection_source_impl; | 	primary_selection_source_impl; | ||||||
| 
 | 
 | ||||||
| bool primary_selection_source_is_xwayland( | bool primary_selection_source_is_xwayland( | ||||||
| 		struct wlr_gtk_primary_selection_source *wlr_source) { | 		struct wlr_primary_selection_source *wlr_source) { | ||||||
| 	return wlr_source->impl == &primary_selection_source_impl; | 	return wlr_source->impl == &primary_selection_source_impl; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void primary_selection_source_send( | static void primary_selection_source_send( | ||||||
| 		struct wlr_gtk_primary_selection_source *wlr_source, | 		struct wlr_primary_selection_source *wlr_source, | ||||||
| 		const char *mime_type, int fd) { | 		const char *mime_type, int fd) { | ||||||
| 	struct x11_primary_selection_source *source = | 	struct x11_primary_selection_source *source = | ||||||
| 		(struct x11_primary_selection_source *)wlr_source; | 		(struct x11_primary_selection_source *)wlr_source; | ||||||
|  | @ -242,14 +242,14 @@ static void primary_selection_source_send( | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void primary_selection_source_destroy( | static void primary_selection_source_destroy( | ||||||
| 		struct wlr_gtk_primary_selection_source *wlr_source) { | 		struct wlr_primary_selection_source *wlr_source) { | ||||||
| 	struct x11_primary_selection_source *source = | 	struct x11_primary_selection_source *source = | ||||||
| 		(struct x11_primary_selection_source *)wlr_source; | 		(struct x11_primary_selection_source *)wlr_source; | ||||||
| 	wl_array_release(&source->mime_types_atoms); | 	wl_array_release(&source->mime_types_atoms); | ||||||
| 	free(source); | 	free(source); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static const struct wlr_gtk_primary_selection_source_impl | static const struct wlr_primary_selection_source_impl | ||||||
| 		primary_selection_source_impl = { | 		primary_selection_source_impl = { | ||||||
| 	.send = primary_selection_source_send, | 	.send = primary_selection_source_send, | ||||||
| 	.destroy = primary_selection_source_destroy, | 	.destroy = primary_selection_source_destroy, | ||||||
|  | @ -361,7 +361,7 @@ static void xwm_selection_get_targets(struct wlr_xwm_selection *selection) { | ||||||
| 		if (source == NULL) { | 		if (source == NULL) { | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| 		wlr_gtk_primary_selection_source_init(&source->base, | 		wlr_primary_selection_source_init(&source->base, | ||||||
| 			&primary_selection_source_impl); | 			&primary_selection_source_impl); | ||||||
| 
 | 
 | ||||||
| 		source->selection = selection; | 		source->selection = selection; | ||||||
|  | @ -369,11 +369,10 @@ static void xwm_selection_get_targets(struct wlr_xwm_selection *selection) { | ||||||
| 
 | 
 | ||||||
| 		bool ok = source_get_targets(selection, &source->base.mime_types, | 		bool ok = source_get_targets(selection, &source->base.mime_types, | ||||||
| 			&source->mime_types_atoms); | 			&source->mime_types_atoms); | ||||||
| 		if (ok && xwm->xwayland->gtk_primary_selection) { | 		if (ok) { | ||||||
| 			wlr_gtk_primary_selection_device_manager_set_selection( | 			wlr_seat_set_primary_selection(xwm->seat, &source->base); | ||||||
| 				xwm->xwayland->gtk_primary_selection, xwm->seat, &source->base); |  | ||||||
| 		} else { | 		} else { | ||||||
| 			wlr_gtk_primary_selection_source_destroy(&source->base); | 			wlr_primary_selection_source_destroy(&source->base); | ||||||
| 		} | 		} | ||||||
| 	} else if (selection == &xwm->dnd_selection) { | 	} else if (selection == &xwm->dnd_selection) { | ||||||
| 		// TODO
 | 		// TODO
 | ||||||
|  | @ -427,10 +426,8 @@ int xwm_handle_xfixes_selection_notify(struct wlr_xwm *xwm, | ||||||
| 			if (selection == &xwm->clipboard_selection) { | 			if (selection == &xwm->clipboard_selection) { | ||||||
| 				wlr_seat_set_selection(xwm->seat, NULL, | 				wlr_seat_set_selection(xwm->seat, NULL, | ||||||
| 					wl_display_next_serial(xwm->xwayland->wl_display)); | 					wl_display_next_serial(xwm->xwayland->wl_display)); | ||||||
| 			} else if (selection == &xwm->primary_selection && | 			} else if (selection == &xwm->primary_selection) { | ||||||
| 					xwm->xwayland->gtk_primary_selection) { | 				wlr_seat_set_primary_selection(xwm->seat, NULL); | ||||||
| 				wlr_gtk_primary_selection_device_manager_set_selection( |  | ||||||
| 					xwm->xwayland->gtk_primary_selection, xwm->seat, NULL); |  | ||||||
| 			} else if (selection == &xwm->dnd_selection) { | 			} else if (selection == &xwm->dnd_selection) { | ||||||
| 				// TODO: DND
 | 				// TODO: DND
 | ||||||
| 			} else { | 			} else { | ||||||
|  |  | ||||||
|  | @ -4,11 +4,11 @@ | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include <wlr/types/wlr_data_device.h> | #include <wlr/types/wlr_data_device.h> | ||||||
| #include <wlr/types/wlr_gtk_primary_selection.h> | #include <wlr/types/wlr_primary_selection.h> | ||||||
| #include <wlr/util/log.h> | #include <wlr/util/log.h> | ||||||
| #include <xcb/xfixes.h> | #include <xcb/xfixes.h> | ||||||
| #include "xwayland/xwm.h" |  | ||||||
| #include "xwayland/selection.h" | #include "xwayland/selection.h" | ||||||
|  | #include "xwayland/xwm.h" | ||||||
| 
 | 
 | ||||||
| static void xwm_selection_send_notify(struct wlr_xwm *xwm, | static void xwm_selection_send_notify(struct wlr_xwm *xwm, | ||||||
| 		xcb_selection_request_event_t *req, bool success) { | 		xcb_selection_request_event_t *req, bool success) { | ||||||
|  | @ -195,10 +195,10 @@ static void xwm_selection_source_send(struct wlr_xwm_selection *selection, | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| 	} else if (selection == &selection->xwm->primary_selection) { | 	} else if (selection == &selection->xwm->primary_selection) { | ||||||
| 		struct wlr_gtk_primary_selection_source *source = | 		struct wlr_primary_selection_source *source = | ||||||
| 			selection->xwm->seat->primary_selection_source; | 			selection->xwm->seat->primary_selection_source; | ||||||
| 		if (source != NULL) { | 		if (source != NULL) { | ||||||
| 			wlr_gtk_primary_selection_source_send(source, mime_type, fd); | 			wlr_primary_selection_source_send(source, mime_type, fd); | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
| 	} else if (selection == &selection->xwm->dnd_selection) { | 	} else if (selection == &selection->xwm->dnd_selection) { | ||||||
|  | @ -231,7 +231,7 @@ static struct wl_array *xwm_selection_source_get_mime_types( | ||||||
| 			return &source->mime_types; | 			return &source->mime_types; | ||||||
| 		} | 		} | ||||||
| 	} else if (selection == &selection->xwm->primary_selection) { | 	} else if (selection == &selection->xwm->primary_selection) { | ||||||
| 		struct wlr_gtk_primary_selection_source *source = | 		struct wlr_primary_selection_source *source = | ||||||
| 			selection->xwm->seat->primary_selection_source; | 			selection->xwm->seat->primary_selection_source; | ||||||
| 		if (source != NULL) { | 		if (source != NULL) { | ||||||
| 			return &source->mime_types; | 			return &source->mime_types; | ||||||
|  |  | ||||||
|  | @ -5,11 +5,11 @@ | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include <wlr/types/wlr_data_device.h> | #include <wlr/types/wlr_data_device.h> | ||||||
| #include <wlr/types/wlr_gtk_primary_selection.h> | #include <wlr/types/wlr_primary_selection.h> | ||||||
| #include <wlr/util/log.h> | #include <wlr/util/log.h> | ||||||
| #include <xcb/xfixes.h> | #include <xcb/xfixes.h> | ||||||
| #include "xwayland/xwm.h" |  | ||||||
| #include "xwayland/selection.h" | #include "xwayland/selection.h" | ||||||
|  | #include "xwayland/xwm.h" | ||||||
| 
 | 
 | ||||||
| void xwm_selection_transfer_remove_source( | void xwm_selection_transfer_remove_source( | ||||||
| 		struct wlr_xwm_selection_transfer *transfer) { | 		struct wlr_xwm_selection_transfer *transfer) { | ||||||
|  | @ -228,12 +228,10 @@ void xwm_selection_finish(struct wlr_xwm *xwm) { | ||||||
| 			wlr_seat_set_selection(xwm->seat, NULL, | 			wlr_seat_set_selection(xwm->seat, NULL, | ||||||
| 				wl_display_next_serial(xwm->xwayland->wl_display)); | 				wl_display_next_serial(xwm->xwayland->wl_display)); | ||||||
| 		} | 		} | ||||||
| 		if (xwm->xwayland->gtk_primary_selection && | 		if (xwm->seat->primary_selection_source && | ||||||
| 				xwm->seat->primary_selection_source && |  | ||||||
| 				primary_selection_source_is_xwayland( | 				primary_selection_source_is_xwayland( | ||||||
| 					xwm->seat->primary_selection_source)) { | 					xwm->seat->primary_selection_source)) { | ||||||
| 			wlr_gtk_primary_selection_device_manager_set_selection( | 			wlr_seat_set_primary_selection(xwm->seat, NULL); | ||||||
| 				xwm->xwayland->gtk_primary_selection, xwm->seat, NULL); |  | ||||||
| 		} | 		} | ||||||
| 		wlr_xwayland_set_seat(xwm->xwayland, NULL); | 		wlr_xwayland_set_seat(xwm->xwayland, NULL); | ||||||
| 	} | 	} | ||||||
|  | @ -275,11 +273,10 @@ static void seat_handle_primary_selection(struct wl_listener *listener, | ||||||
| 	struct wlr_seat *seat = data; | 	struct wlr_seat *seat = data; | ||||||
| 	struct wlr_xwm *xwm = | 	struct wlr_xwm *xwm = | ||||||
| 		wl_container_of(listener, xwm, seat_primary_selection); | 		wl_container_of(listener, xwm, seat_primary_selection); | ||||||
| 	struct wlr_gtk_primary_selection_source *source = seat->primary_selection_source; | 	struct wlr_primary_selection_source *source = | ||||||
|  | 		seat->primary_selection_source; | ||||||
| 
 | 
 | ||||||
| 	if (source != NULL && | 	if (source != NULL && primary_selection_source_is_xwayland(source)) { | ||||||
| 			primary_selection_source_is_xwayland( |  | ||||||
| 				source)) { |  | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -505,9 +505,3 @@ void wlr_xwayland_set_seat(struct wlr_xwayland *xwayland, | ||||||
| 	xwayland->seat_destroy.notify = xwayland_handle_seat_destroy; | 	xwayland->seat_destroy.notify = xwayland_handle_seat_destroy; | ||||||
| 	wl_signal_add(&seat->events.destroy, &xwayland->seat_destroy); | 	wl_signal_add(&seat->events.destroy, &xwayland->seat_destroy); | ||||||
| } | } | ||||||
| 
 |  | ||||||
| void wlr_xwayland_set_gtk_primary_selection_device_manager( |  | ||||||
| 		struct wlr_xwayland *xwayland, |  | ||||||
| 		struct wlr_gtk_primary_selection_device_manager *manager) { |  | ||||||
| 	xwayland->gtk_primary_selection = manager; |  | ||||||
| } |  | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue