From 78befa59f96bb0a13e9ffeb4df1272738c6b5012 Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Thu, 8 Apr 2021 09:42:11 +0200 Subject: [PATCH] gtk-primary-selection: drop support The standard primary-selection protocol is now widely supported. --- include/wlr/types/wlr_gtk_primary_selection.h | 57 -- protocol/gtk-primary-selection.xml | 225 -------- protocol/meson.build | 1 - types/meson.build | 1 - types/seat/wlr_seat_keyboard.c | 1 - types/wlr_gtk_primary_selection.c | 490 ------------------ xwayland/selection/dnd.c | 1 - 7 files changed, 776 deletions(-) delete mode 100644 include/wlr/types/wlr_gtk_primary_selection.h delete mode 100644 protocol/gtk-primary-selection.xml delete mode 100644 types/wlr_gtk_primary_selection.c diff --git a/include/wlr/types/wlr_gtk_primary_selection.h b/include/wlr/types/wlr_gtk_primary_selection.h deleted file mode 100644 index 0d97eba0..00000000 --- a/include/wlr/types/wlr_gtk_primary_selection.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This protocol is obsolete and will be removed in a future version. The - * recommended replacement is wp-primary-selection. - */ - -/* - * 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_GTK_PRIMARY_SELECTION_H -#define WLR_TYPES_WLR_GTK_PRIMARY_SELECTION_H - -#include -#include - -/** - * A primary selection manager which implements the GTK protocol. - */ -struct wlr_gtk_primary_selection_device_manager { - struct wl_global *global; - struct wl_list devices; // wlr_gtk_primary_selection_device::link - - struct wl_listener display_destroy; - - struct { - struct wl_signal destroy; - } events; - - void *data; -}; - -/** - * A device is a per-seat object used to set and get the current selection. - */ -struct wlr_gtk_primary_selection_device { - struct wlr_gtk_primary_selection_device_manager *manager; - struct wlr_seat *seat; - struct wl_list link; // wlr_gtk_primary_selection_device_manager::devices - struct wl_list resources; // wl_resource_get_link - - struct wl_list offers; // wl_resource_get_link - - struct wl_listener seat_destroy; - struct wl_listener seat_focus_change; - struct wl_listener seat_set_primary_selection; - - void *data; -}; - -struct wlr_gtk_primary_selection_device_manager * - wlr_gtk_primary_selection_device_manager_create(struct wl_display *display); - -#endif diff --git a/protocol/gtk-primary-selection.xml b/protocol/gtk-primary-selection.xml deleted file mode 100644 index 02cab94f..00000000 --- a/protocol/gtk-primary-selection.xml +++ /dev/null @@ -1,225 +0,0 @@ - - - - Copyright © 2015, 2016 Red Hat - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice (including the next - paragraph) shall be included in all copies or substantial portions of the - Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - - - - This protocol provides the ability to have a primary selection device to - match that of the X server. This primary selection is a shortcut to the - common clipboard selection, where text just needs to be selected in order - to allow copying it elsewhere. The de facto way to perform this action - is the middle mouse button, although it is not limited to this one. - - Clients wishing to honor primary selection should create a primary - selection source and set it as the selection through - wp_primary_selection_device.set_selection whenever the text selection - changes. In order to minimize calls in pointer-driven text selection, - it should happen only once after the operation finished. Similarly, - a NULL source should be set when text is unselected. - - wp_primary_selection_offer objects are first announced through the - wp_primary_selection_device.data_offer event. Immediately after this event, - the primary data offer will emit wp_primary_selection_offer.offer events - to let know of the mime types being offered. - - When the primary selection changes, the client with the keyboard focus - will receive wp_primary_selection_device.selection events. Only the client - with the keyboard focus will receive such events with a non-NULL - wp_primary_selection_offer. Across keyboard focus changes, previously - focused clients will receive wp_primary_selection_device.events with a - NULL wp_primary_selection_offer. - - In order to request the primary selection data, the client must pass - a recent serial pertaining to the press event that is triggering the - operation, if the compositor deems the serial valid and recent, the - wp_primary_selection_source.send event will happen in the other end - to let the transfer begin. The client owning the primary selection - should write the requested data, and close the file descriptor - immediately. - - If the primary selection owner client disappeared during the transfer, - the client reading the data will receive a - wp_primary_selection_device.selection event with a NULL - wp_primary_selection_offer, the client should take this as a hint - to finish the reads related to the no longer existing offer. - - The primary selection owner should be checking for errors during - writes, merely cancelling the ongoing transfer if any happened. - - - - - The primary selection device manager is a singleton global object that - provides access to the primary selection. It allows to create - wp_primary_selection_source objects, as well as retrieving the per-seat - wp_primary_selection_device objects. - - - - - Create a new primary selection source. - - - - - - - Create a new data device for a given seat. - - - - - - - - Destroy the primary selection device manager. - - - - - - - - Replaces the current selection. The previous owner of the primary selection - will receive a wp_primary_selection_source.cancelled event. - - To unset the selection, set the source to NULL. - - - - - - - - Introduces a new wp_primary_selection_offer object that may be used - to receive the current primary selection. Immediately following this - event, the new wp_primary_selection_offer object will send - wp_primary_selection_offer.offer events to describe the offered mime - types. - - - - - - - The wp_primary_selection_device.selection event is sent to notify the - client of a new primary selection. This event is sent after the - wp_primary_selection.data_offer event introducing this object, and after - the offer has announced its mimetypes through - wp_primary_selection_offer.offer. - - The data_offer is valid until a new offer or NULL is received - or until the client loses keyboard focus. The client must destroy the - previous selection data_offer, if any, upon receiving this event. - - - - - - - Destroy the primary selection device. - - - - - - - A wp_primary_selection_offer represents an offer to transfer the contents - of the primary selection clipboard to the client. Similar to - wl_data_offer, the offer also describes the mime types that the source - will transferthat the - data can be converted to and provides the mechanisms for transferring the - data directly to the client. - - - - - To transfer the contents of the primary selection clipboard, the client - issues this request and indicates the mime type that it wants to - receive. The transfer happens through the passed file descriptor - (typically created with the pipe system call). The source client writes - the data in the mime type representation requested and then closes the - file descriptor. - - The receiving client reads from the read end of the pipe until EOF and - closes its end, at which point the transfer is complete. - - - - - - - - Destroy the primary selection offer. - - - - - - Sent immediately after creating announcing the wp_primary_selection_offer - through wp_primary_selection_device.data_offer. One event is sent per - offered mime type. - - - - - - - - The source side of a wp_primary_selection_offer, it provides a way to - describe the offered data and respond to requests to transfer the - requested contents of the primary selection clipboard. - - - - - This request adds a mime type to the set of mime types advertised to - targets. Can be called several times to offer multiple types. - - - - - - - Destroy the primary selection source. - - - - - - Request for the current primary selection contents from the client. - Send the specified mime type over the passed file descriptor, then - close it. - - - - - - - - This primary selection source is no longer valid. The client should - clean up and destroy this primary selection source. - - - - diff --git a/protocol/meson.build b/protocol/meson.build index a602cd1d..dbeec868 100644 --- a/protocol/meson.build +++ b/protocol/meson.build @@ -32,7 +32,6 @@ protocols = { 'xdg-output-unstable-v1': wl_protocol_dir / 'unstable/xdg-output/xdg-output-unstable-v1.xml', # Other protocols 'drm': 'drm.xml', - 'gtk-primary-selection': 'gtk-primary-selection.xml', 'kde-idle': 'idle.xml', 'kde-server-decoration': 'server-decoration.xml', 'input-method-unstable-v2': 'input-method-unstable-v2.xml', diff --git a/types/meson.build b/types/meson.build index 811d2521..d7b1bc5d 100644 --- a/types/meson.build +++ b/types/meson.build @@ -25,7 +25,6 @@ wlr_files += files( 'wlr_foreign_toplevel_management_v1.c', 'wlr_fullscreen_shell_v1.c', 'wlr_gamma_control_v1.c', - 'wlr_gtk_primary_selection.c', 'wlr_idle_inhibit_v1.c', 'wlr_idle.c', 'wlr_input_device.c', diff --git a/types/seat/wlr_seat_keyboard.c b/types/seat/wlr_seat_keyboard.c index 5328de82..e9aba4d2 100644 --- a/types/seat/wlr_seat_keyboard.c +++ b/types/seat/wlr_seat_keyboard.c @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include "types/wlr_data_device.h" diff --git a/types/wlr_gtk_primary_selection.c b/types/wlr_gtk_primary_selection.c deleted file mode 100644 index 6ee877e4..00000000 --- a/types/wlr_gtk_primary_selection.c +++ /dev/null @@ -1,490 +0,0 @@ -#define _POSIX_C_SOURCE 200809L -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "gtk-primary-selection-protocol.h" -#include "util/signal.h" - -#define DEVICE_MANAGER_VERSION 1 - -static const struct gtk_primary_selection_offer_interface offer_impl; - -static struct wlr_gtk_primary_selection_device *device_from_offer_resource( - struct wl_resource *resource) { - assert(wl_resource_instance_of(resource, - >k_primary_selection_offer_interface, &offer_impl)); - return wl_resource_get_user_data(resource); -} - -static void offer_handle_receive(struct wl_client *client, - struct wl_resource *resource, const char *mime_type, int32_t fd) { - struct wlr_gtk_primary_selection_device *device = - device_from_offer_resource(resource); - if (device == NULL || device->seat->primary_selection_source == NULL) { - close(fd); - return; - } - - wlr_primary_selection_source_send(device->seat->primary_selection_source, - mime_type, fd); -} - -static void offer_handle_destroy(struct wl_client *client, - struct wl_resource *resource) { - wl_resource_destroy(resource); -} - -static const struct gtk_primary_selection_offer_interface offer_impl = { - .receive = offer_handle_receive, - .destroy = offer_handle_destroy, -}; - -static void offer_handle_resource_destroy(struct wl_resource *resource) { - wl_list_remove(wl_resource_get_link(resource)); -} - -static struct wlr_gtk_primary_selection_device *device_from_resource( - struct wl_resource *resource); - -static void create_offer(struct wl_resource *device_resource, - struct wlr_primary_selection_source *source) { - struct wlr_gtk_primary_selection_device *device = - device_from_resource(device_resource); - assert(device != NULL); - - struct wl_client *client = wl_resource_get_client(device_resource); - uint32_t version = wl_resource_get_version(device_resource); - struct wl_resource *resource = wl_resource_create(client, - >k_primary_selection_offer_interface, version, 0); - if (resource == NULL) { - wl_resource_post_no_memory(device_resource); - return; - } - wl_resource_set_implementation(resource, &offer_impl, device, - offer_handle_resource_destroy); - - wl_list_insert(&device->offers, wl_resource_get_link(resource)); - - gtk_primary_selection_device_send_data_offer(device_resource, resource); - - char **p; - wl_array_for_each(p, &source->mime_types) { - gtk_primary_selection_offer_send_offer(resource, *p); - } - - gtk_primary_selection_device_send_selection(device_resource, resource); -} - -static void destroy_offer(struct wl_resource *resource) { - if (device_from_offer_resource(resource) == NULL) { - return; - } - - // Make the offer inert - wl_resource_set_user_data(resource, NULL); - - struct wl_list *link = wl_resource_get_link(resource); - wl_list_remove(link); - wl_list_init(link); -} - - -struct client_data_source { - struct wlr_primary_selection_source source; - struct wl_resource *resource; - bool finalized; -}; - -static void client_source_send( - struct wlr_primary_selection_source *wlr_source, - const char *mime_type, int fd) { - struct client_data_source *source = (struct client_data_source *)wlr_source; - gtk_primary_selection_source_send_send(source->resource, mime_type, fd); - close(fd); -} - -static void client_source_destroy( - struct wlr_primary_selection_source *wlr_source) { - struct client_data_source *source = (struct client_data_source *)wlr_source; - gtk_primary_selection_source_send_cancelled(source->resource); - // Make the source resource inert - wl_resource_set_user_data(source->resource, NULL); - free(source); -} - -static const struct wlr_primary_selection_source_impl client_source_impl = { - .send = client_source_send, - .destroy = client_source_destroy, -}; - -static const struct gtk_primary_selection_source_interface source_impl; - -static struct client_data_source *client_data_source_from_resource( - struct wl_resource *resource) { - assert(wl_resource_instance_of(resource, - >k_primary_selection_source_interface, &source_impl)); - return wl_resource_get_user_data(resource); -} - -static void source_handle_offer(struct wl_client *client, - struct wl_resource *resource, const char *mime_type) { - struct client_data_source *source = - client_data_source_from_resource(resource); - if (source == NULL) { - return; - } - if (source->finalized) { - wlr_log(WLR_DEBUG, "Offering additional MIME type after set_selection"); - } - - const char **mime_type_ptr; - wl_array_for_each(mime_type_ptr, &source->source.mime_types) { - if (strcmp(*mime_type_ptr, mime_type) == 0) { - wlr_log(WLR_DEBUG, "Ignoring duplicate MIME type offer %s", - mime_type); - return; - } - } - - char *dup_mime_type = strdup(mime_type); - if (dup_mime_type == NULL) { - 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, - struct wl_resource *resource) { - wl_resource_destroy(resource); -} - -static const struct gtk_primary_selection_source_interface source_impl = { - .offer = source_handle_offer, - .destroy = source_handle_destroy, -}; - -static void source_resource_handle_destroy(struct wl_resource *resource) { - struct client_data_source *source = - client_data_source_from_resource(resource); - if (source == NULL) { - return; - } - wlr_primary_selection_source_destroy(&source->source); -} - - -static const struct gtk_primary_selection_device_interface device_impl; - -static struct wlr_gtk_primary_selection_device *device_from_resource( - struct wl_resource *resource) { - assert(wl_resource_instance_of(resource, - >k_primary_selection_device_interface, &device_impl)); - return wl_resource_get_user_data(resource); -} - -static void device_handle_set_selection(struct wl_client *client, - struct wl_resource *resource, struct wl_resource *source_resource, - uint32_t serial) { - struct wlr_gtk_primary_selection_device *device = - device_from_resource(resource); - if (device == NULL) { - return; - } - - struct client_data_source *client_source = NULL; - if (source_resource != NULL) { - client_source = client_data_source_from_resource(source_resource); - } - - struct wlr_primary_selection_source *source = NULL; - if (client_source != NULL) { - client_source->finalized = true; - source = &client_source->source; - } - - struct wlr_seat_client *seat_client = - wlr_seat_client_for_wl_client(device->seat, client); - - wlr_seat_request_set_primary_selection(device->seat, seat_client, source, serial); -} - -static void device_handle_destroy(struct wl_client *client, - struct wl_resource *resource) { - wl_resource_destroy(resource); -} - -static const struct gtk_primary_selection_device_interface device_impl = { - .set_selection = device_handle_set_selection, - .destroy = device_handle_destroy, -}; - -static void device_handle_resource_destroy(struct wl_resource *resource) { - wl_list_remove(wl_resource_get_link(resource)); -} - - -static void device_resource_send_selection(struct wl_resource *resource, - struct wlr_primary_selection_source *source) { - assert(device_from_resource(resource) != NULL); - - if (source != NULL) { - create_offer(resource, source); - } else { - gtk_primary_selection_device_send_selection(resource, NULL); - } -} - -static void device_send_selection( - struct wlr_gtk_primary_selection_device *device) { - struct wlr_seat_client *seat_client = - device->seat->keyboard_state.focused_client; - if (seat_client == NULL) { - return; - } - - struct wl_resource *resource; - wl_resource_for_each(resource, &device->resources) { - if (wl_resource_get_client(resource) == seat_client->client) { - device_resource_send_selection(resource, - device->seat->primary_selection_source); - } - } -} - -static void device_destroy(struct wlr_gtk_primary_selection_device *device); - -static void device_handle_seat_destroy(struct wl_listener *listener, - void *data) { - struct wlr_gtk_primary_selection_device *device = - wl_container_of(listener, device, seat_destroy); - device_destroy(device); -} - -static void device_handle_seat_focus_change(struct wl_listener *listener, - void *data) { - struct wlr_gtk_primary_selection_device *device = - wl_container_of(listener, device, seat_focus_change); - // TODO: maybe make previous offers inert, or set a NULL selection for - // previous client? - device_send_selection(device); -} - -static void device_handle_seat_set_primary_selection( - struct wl_listener *listener, void *data) { - struct wlr_gtk_primary_selection_device *device = - wl_container_of(listener, device, seat_set_primary_selection); - - struct wl_resource *resource, *tmp; - wl_resource_for_each_safe(resource, tmp, &device->offers) { - destroy_offer(resource); - } - - device_send_selection(device); -} - -static struct wlr_gtk_primary_selection_device *get_or_create_device( - struct wlr_gtk_primary_selection_device_manager *manager, - struct wlr_seat *seat) { - struct wlr_gtk_primary_selection_device *device; - wl_list_for_each(device, &manager->devices, link) { - if (device->seat == seat) { - return device; - } - } - - device = calloc(1, sizeof(struct wlr_gtk_primary_selection_device)); - if (device == NULL) { - return NULL; - } - device->manager = manager; - device->seat = seat; - - wl_list_init(&device->resources); - wl_list_insert(&manager->devices, &device->link); - - wl_list_init(&device->offers); - - device->seat_destroy.notify = device_handle_seat_destroy; - wl_signal_add(&seat->events.destroy, &device->seat_destroy); - - device->seat_focus_change.notify = device_handle_seat_focus_change; - wl_signal_add(&seat->keyboard_state.events.focus_change, - &device->seat_focus_change); - - device->seat_set_primary_selection.notify = - device_handle_seat_set_primary_selection; - wl_signal_add(&seat->events.set_primary_selection, - &device->seat_set_primary_selection); - - return device; -} - -static void device_destroy(struct wlr_gtk_primary_selection_device *device) { - if (device == NULL) { - return; - } - wl_list_remove(&device->link); - wl_list_remove(&device->seat_destroy.link); - wl_list_remove(&device->seat_focus_change.link); - wl_list_remove(&device->seat_set_primary_selection.link); - struct wl_resource *resource, *resource_tmp; - wl_resource_for_each_safe(resource, resource_tmp, &device->offers) { - destroy_offer(resource); - } - wl_resource_for_each_safe(resource, resource_tmp, &device->resources) { - // Make the resource inert - wl_resource_set_user_data(resource, NULL); - - struct wl_list *link = wl_resource_get_link(resource); - wl_list_remove(link); - wl_list_init(link); - } - free(device); -} - - -static const struct gtk_primary_selection_device_manager_interface - device_manager_impl; - -static struct wlr_gtk_primary_selection_device_manager *manager_from_resource( - struct wl_resource *resource) { - assert(wl_resource_instance_of(resource, - >k_primary_selection_device_manager_interface, &device_manager_impl)); - return wl_resource_get_user_data(resource); -} - -static void device_manager_handle_create_source(struct wl_client *client, - struct wl_resource *manager_resource, uint32_t id) { - struct client_data_source *source = - calloc(1, sizeof(struct client_data_source)); - if (source == NULL) { - wl_client_post_no_memory(client); - return; - } - wlr_primary_selection_source_init(&source->source, &client_source_impl); - - uint32_t version = wl_resource_get_version(manager_resource); - source->resource = wl_resource_create(client, - >k_primary_selection_source_interface, version, id); - if (source->resource == NULL) { - free(source); - wl_client_post_no_memory(client); - return; - } - wl_resource_set_implementation(source->resource, &source_impl, source, - source_resource_handle_destroy); -} - -static void device_manager_handle_get_device(struct wl_client *client, - struct wl_resource *manager_resource, uint32_t id, - struct wl_resource *seat_resource) { - struct wlr_seat_client *seat_client = - wlr_seat_client_from_resource(seat_resource); - struct wlr_gtk_primary_selection_device_manager *manager = - manager_from_resource(manager_resource); - - struct wlr_gtk_primary_selection_device *device = - get_or_create_device(manager, seat_client->seat); - if (device == NULL) { - wl_resource_post_no_memory(manager_resource); - return; - } - - uint32_t version = wl_resource_get_version(manager_resource); - struct wl_resource *resource = wl_resource_create(client, - >k_primary_selection_device_interface, version, id); - if (resource == NULL) { - wl_resource_post_no_memory(manager_resource); - return; - } - wl_resource_set_implementation(resource, &device_impl, device, - device_handle_resource_destroy); - wl_list_insert(&device->resources, wl_resource_get_link(resource)); - - if (device->seat->keyboard_state.focused_client == seat_client) { - device_resource_send_selection(resource, - device->seat->primary_selection_source); - } -} - -static void device_manager_handle_destroy(struct wl_client *client, - struct wl_resource *manager_resource) { - wl_resource_destroy(manager_resource); -} - -static const struct gtk_primary_selection_device_manager_interface - device_manager_impl = { - .create_source = device_manager_handle_create_source, - .get_device = device_manager_handle_get_device, - .destroy = device_manager_handle_destroy, -}; - - -static void primary_selection_device_manager_bind(struct wl_client *client, - void *data, uint32_t version, uint32_t id) { - struct wlr_gtk_primary_selection_device_manager *manager = data; - - struct wl_resource *resource = wl_resource_create(client, - >k_primary_selection_device_manager_interface, version, id); - if (resource == NULL) { - wl_client_post_no_memory(client); - return; - } - wl_resource_set_implementation(resource, &device_manager_impl, manager, - NULL); -} - -static void handle_display_destroy(struct wl_listener *listener, void *data) { - struct wlr_gtk_primary_selection_device_manager *manager = - wl_container_of(listener, manager, display_destroy); - - struct wlr_gtk_primary_selection_device *device, *tmp; - wl_list_for_each_safe(device, tmp, &manager->devices, link) { - device_destroy(device); - } - - wlr_signal_emit_safe(&manager->events.destroy, manager); - wl_list_remove(&manager->display_destroy.link); - wl_global_destroy(manager->global); - free(manager); -} - -struct wlr_gtk_primary_selection_device_manager * - wlr_gtk_primary_selection_device_manager_create( - struct wl_display *display) { - struct wlr_gtk_primary_selection_device_manager *manager = - calloc(1, sizeof(struct wlr_gtk_primary_selection_device_manager)); - if (manager == NULL) { - return NULL; - } - manager->global = wl_global_create(display, - >k_primary_selection_device_manager_interface, DEVICE_MANAGER_VERSION, - manager, primary_selection_device_manager_bind); - if (manager->global == NULL) { - free(manager); - return NULL; - } - - wl_list_init(&manager->devices); - wl_signal_init(&manager->events.destroy); - - manager->display_destroy.notify = handle_display_destroy; - wl_display_add_destroy_listener(display, &manager->display_destroy); - - return manager; -} diff --git a/xwayland/selection/dnd.c b/xwayland/selection/dnd.c index ee9a23a6..1c053e5e 100644 --- a/xwayland/selection/dnd.c +++ b/xwayland/selection/dnd.c @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include "xwayland/xwm.h"