Path: blob/master/platform/linuxbsd/wayland/wayland_thread.h
21733 views
/**************************************************************************/1/* wayland_thread.h */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#pragma once3132#ifdef WAYLAND_ENABLED3334#include "key_mapping_xkb.h"3536#ifdef SOWRAP_ENABLED37#include "wayland/dynwrappers/wayland-client-core-so_wrap.h"38#include "wayland/dynwrappers/wayland-cursor-so_wrap.h"39#include "wayland/dynwrappers/wayland-egl-core-so_wrap.h"40#include "xkbcommon-so_wrap.h"41#else42#include <wayland-client-core.h>43#include <wayland-cursor.h>44#ifdef GLES3_ENABLED45#include <wayland-egl-core.h>46#endif47#include <xkbcommon/xkbcommon-compose.h>48#include <xkbcommon/xkbcommon.h>49#endif // SOWRAP_ENABLED5051// These must go after the Wayland client include to work properly.52#include "wayland/protocol/idle_inhibit.gen.h"53#include "wayland/protocol/primary_selection.gen.h"54// These four protocol headers name wl_pointer method arguments as `pointer`,55// which is the same name as X11's pointer typedef. This trips some very56// annoying shadowing warnings. A `#define` works around this issue.57#define pointer wl_pointer58#include "wayland/protocol/cursor_shape.gen.h"59#include "wayland/protocol/pointer_constraints.gen.h"60#include "wayland/protocol/pointer_gestures.gen.h"61#include "wayland/protocol/relative_pointer.gen.h"62#undef pointer63#include "wayland/protocol/fractional_scale.gen.h"64#include "wayland/protocol/tablet.gen.h"65#include "wayland/protocol/text_input.gen.h"66#include "wayland/protocol/viewporter.gen.h"67#include "wayland/protocol/wayland.gen.h"68#include "wayland/protocol/xdg_activation.gen.h"69#include "wayland/protocol/xdg_decoration.gen.h"70#include "wayland/protocol/xdg_foreign_v2.gen.h"71#include "wayland/protocol/xdg_shell.gen.h"72#include "wayland/protocol/xdg_system_bell.gen.h"73#include "wayland/protocol/xdg_toplevel_icon.gen.h"7475#include "wayland/protocol/godot_embedding_compositor.gen.h"7677// NOTE: Deprecated.78#include "wayland/protocol/xdg_foreign_v1.gen.h"7980#ifdef LIBDECOR_ENABLED81#ifdef SOWRAP_ENABLED82#include "dynwrappers/libdecor-so_wrap.h"83#else84#include <libdecor.h>85#endif // SOWRAP_ENABLED86#endif // LIBDECOR_ENABLED8788#include "core/input/input_event.h"89#include "core/os/thread.h"90#include "servers/display/display_server.h"9192#include "wayland_embedder.h"9394class WaylandThread {95public:96// Messages used for exchanging information between Godot's and Wayland's thread.97class Message : public RefCounted {98GDSOFTCLASS(Message, RefCounted);99100public:101Message() {}102virtual ~Message() = default;103};104105class WindowMessage : public Message {106GDSOFTCLASS(WindowMessage, Message);107108public:109DisplayServer::WindowID id = DisplayServer::INVALID_WINDOW_ID;110};111112// Message data for window rect changes.113class WindowRectMessage : public WindowMessage {114GDSOFTCLASS(WindowRectMessage, WindowMessage);115116public:117// NOTE: This is in "scaled" terms. For example, if there's a 1920x1080 rect118// with a scale factor of 2, the actual value of `rect` will be 3840x2160.119Rect2i rect;120};121122class WindowEventMessage : public WindowMessage {123GDSOFTCLASS(WindowEventMessage, WindowMessage);124125public:126DisplayServer::WindowEvent event;127};128129class InputEventMessage : public Message {130GDSOFTCLASS(InputEventMessage, Message);131132public:133Ref<InputEvent> event;134};135136class DropFilesEventMessage : public WindowMessage {137GDSOFTCLASS(DropFilesEventMessage, WindowMessage);138139public:140Vector<String> files;141};142143class IMEUpdateEventMessage : public WindowMessage {144GDSOFTCLASS(IMEUpdateEventMessage, WindowMessage);145146public:147String text;148Vector2i selection;149};150151class IMECommitEventMessage : public WindowMessage {152GDSOFTCLASS(IMECommitEventMessage, WindowMessage);153154public:155String text;156};157158struct RegistryState {159WaylandThread *wayland_thread;160161// Core Wayland globals.162struct wl_shm *wl_shm = nullptr;163uint32_t wl_shm_name = 0;164165struct wl_compositor *wl_compositor = nullptr;166uint32_t wl_compositor_name = 0;167168struct wl_subcompositor *wl_subcompositor = nullptr;169uint32_t wl_subcompositor_name = 0;170171struct wl_data_device_manager *wl_data_device_manager = nullptr;172uint32_t wl_data_device_manager_name = 0;173174List<struct wl_output *> wl_outputs;175List<struct wl_seat *> wl_seats;176177// xdg-shell globals.178179struct xdg_wm_base *xdg_wm_base = nullptr;180uint32_t xdg_wm_base_name = 0;181182// NOTE: Deprecated.183struct zxdg_exporter_v1 *xdg_exporter_v1 = nullptr;184uint32_t xdg_exporter_v1_name = 0;185186uint32_t xdg_exporter_v2_name = 0;187struct zxdg_exporter_v2 *xdg_exporter_v2 = nullptr;188189// wayland-protocols globals.190191struct wp_viewporter *wp_viewporter = nullptr;192uint32_t wp_viewporter_name = 0;193194struct wp_fractional_scale_manager_v1 *wp_fractional_scale_manager = nullptr;195uint32_t wp_fractional_scale_manager_name = 0;196197struct wp_cursor_shape_manager_v1 *wp_cursor_shape_manager = nullptr;198uint32_t wp_cursor_shape_manager_name = 0;199200struct zxdg_decoration_manager_v1 *xdg_decoration_manager = nullptr;201uint32_t xdg_decoration_manager_name = 0;202203struct xdg_system_bell_v1 *xdg_system_bell = nullptr;204uint32_t xdg_system_bell_name = 0;205206struct xdg_toplevel_icon_manager_v1 *xdg_toplevel_icon_manager = nullptr;207uint32_t xdg_toplevel_icon_manager_name = 0;208209struct xdg_activation_v1 *xdg_activation = nullptr;210uint32_t xdg_activation_name = 0;211212struct zwp_primary_selection_device_manager_v1 *wp_primary_selection_device_manager = nullptr;213uint32_t wp_primary_selection_device_manager_name = 0;214215struct zwp_relative_pointer_manager_v1 *wp_relative_pointer_manager = nullptr;216uint32_t wp_relative_pointer_manager_name = 0;217218struct zwp_pointer_constraints_v1 *wp_pointer_constraints = nullptr;219uint32_t wp_pointer_constraints_name = 0;220221struct zwp_pointer_gestures_v1 *wp_pointer_gestures = nullptr;222uint32_t wp_pointer_gestures_name = 0;223224struct zwp_idle_inhibit_manager_v1 *wp_idle_inhibit_manager = nullptr;225uint32_t wp_idle_inhibit_manager_name = 0;226227struct zwp_tablet_manager_v2 *wp_tablet_manager = nullptr;228uint32_t wp_tablet_manager_name = 0;229230struct zwp_text_input_manager_v3 *wp_text_input_manager = nullptr;231uint32_t wp_text_input_manager_name = 0;232233// We're really not meant to use this one directly but we still need to know234// whether it's available.235uint32_t wp_fifo_manager_name = 0;236237struct godot_embedding_compositor *godot_embedding_compositor = nullptr;238uint32_t godot_embedding_compositor_name = 0;239};240241// General Wayland-specific states. Shouldn't be accessed directly.242// TODO: Make private?243244struct WindowState {245DisplayServer::WindowID id = DisplayServer::INVALID_WINDOW_ID;246DisplayServer::WindowID parent_id = DisplayServer::INVALID_WINDOW_ID;247248Rect2i rect;249DisplayServer::WindowMode mode = DisplayServer::WINDOW_MODE_WINDOWED;250251// Toplevel states.252bool maximized = false; // MUST obey configure size.253bool fullscreen = false; // Can be smaller than configure size.254bool resizing = false; // Configure size is a max.255// No need for `activated` (yet)256bool tiled_left = false;257bool tiled_right = false;258bool tiled_top = false;259bool tiled_bottom = false;260bool suspended = false; // We can stop drawing.261262// These are true by default as it isn't guaranteed that we'll find an263// xdg-shell implementation with wm_capabilities available. If and once we264// receive a wm_capabilities event these will get reset and updated with265// whatever the compositor says.266bool can_minimize = true;267bool can_maximize = true;268bool can_fullscreen = true;269270HashSet<struct wl_output *> wl_outputs;271272// NOTE: If for whatever reason this callback is destroyed _while_ the event273// thread is still running, it might be a good idea to set its user data to274// `nullptr`. From some initial testing of mine, it looks like it might still275// be called even after being destroyed, pointing to probably invalid window276// data by then and segfaulting hard.277struct wl_callback *frame_callback = nullptr;278uint64_t last_frame_time = 0;279280struct wl_surface *wl_surface = nullptr;281struct xdg_surface *xdg_surface = nullptr;282struct xdg_toplevel *xdg_toplevel = nullptr;283284struct wp_viewport *wp_viewport = nullptr;285struct wp_fractional_scale_v1 *wp_fractional_scale = nullptr;286287// NOTE: Deprecated.288struct zxdg_exported_v1 *xdg_exported_v1 = nullptr;289290struct zxdg_exported_v2 *xdg_exported_v2 = nullptr;291292struct xdg_popup *xdg_popup = nullptr;293294String exported_handle;295296// Currently applied buffer scale.297int buffer_scale = 1;298299// Buffer scale must be applied right before rendering but _after_ committing300// everything else or otherwise we might have an inconsistent state (e.g.301// double scale and odd resolution). This flag assists with that; when set,302// on the next frame, we'll commit whatever is set in `buffer_scale`.303bool buffer_scale_changed = false;304305// NOTE: The preferred buffer scale is currently only dynamically calculated.306// It can be accessed by calling `window_state_get_preferred_buffer_scale`.307308// NOTE: Popups manually inherit the parent's scale on creation. Make sure to309// sync them up with any new fields.310311// Override used by the fractional scale add-on object. If less or equal to 0312// (default) then the normal output-based scale is used instead.313double fractional_scale = 0;314315// What the compositor is recommending us.316double preferred_fractional_scale = 0;317318struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration = nullptr;319320struct zwp_idle_inhibitor_v1 *wp_idle_inhibitor = nullptr;321322#ifdef LIBDECOR_ENABLED323// If this is null the xdg_* variables must be set and vice-versa. This way we324// can handle this mess gracefully enough to hopefully being able of getting325// rid of this cleanly once we have our own CSDs.326struct libdecor_frame *libdecor_frame = nullptr;327struct libdecor_configuration *pending_libdecor_configuration = nullptr;328#endif329330RegistryState *registry;331WaylandThread *wayland_thread;332};333334// "High level" Godot-side screen data.335struct ScreenData {336// Geometry data.337Point2i position;338339String make;340String model;341342Size2i size;343Size2i physical_size;344345float refresh_rate = -1;346int scale = 1;347};348349struct ScreenState {350uint32_t wl_output_name = 0;351352ScreenData pending_data;353ScreenData data;354355WaylandThread *wayland_thread;356};357358enum class Gesture {359NONE,360MAGNIFY,361};362363enum class PointerConstraint {364NONE,365LOCKED,366CONFINED,367};368369struct PointerData {370Point2 position;371uint32_t motion_time = 0;372373// Relative motion has its own optional event and so needs its own time.374Vector2 relative_motion;375uint32_t relative_motion_time = 0;376377BitField<MouseButtonMask> pressed_button_mask = MouseButtonMask::NONE;378379MouseButton last_button_pressed = MouseButton::NONE;380Point2 last_pressed_position;381382DisplayServer::WindowID pointed_id = DisplayServer::INVALID_WINDOW_ID;383DisplayServer::WindowID last_pointed_id = DisplayServer::INVALID_WINDOW_ID;384385// This is needed to check for a new double click every time.386bool double_click_begun = false;387388uint32_t button_time = 0;389uint32_t button_serial = 0;390391uint32_t scroll_type = WL_POINTER_AXIS_SOURCE_WHEEL;392393// The amount "scrolled" in pixels, in each direction.394Vector2 scroll_vector;395396// The amount of scroll "clicks" in each direction, in fractions of 120.397Vector2i discrete_scroll_vector_120;398399uint32_t pinch_scale = 1;400};401402struct TabletToolData {403Point2 position;404Vector2 tilt;405uint32_t pressure = 0;406407BitField<MouseButtonMask> pressed_button_mask = MouseButtonMask::NONE;408409MouseButton last_button_pressed = MouseButton::NONE;410Point2 last_pressed_position;411412bool double_click_begun = false;413414uint64_t button_time = 0;415uint64_t motion_time = 0;416417DisplayServer::WindowID proximal_id = DisplayServer::INVALID_WINDOW_ID;418DisplayServer::WindowID last_proximal_id = DisplayServer::INVALID_WINDOW_ID;419uint32_t proximity_serial = 0;420};421422struct TabletToolState {423struct wl_seat *wl_seat = nullptr;424425bool is_eraser = false;426427TabletToolData data_pending;428TabletToolData data;429};430431struct OfferState {432HashSet<String> mime_types;433};434435struct SeatState {436RegistryState *registry = nullptr;437438WaylandThread *wayland_thread = nullptr;439440struct wl_seat *wl_seat = nullptr;441uint32_t wl_seat_name = 0;442443// Pointer.444struct wl_pointer *wl_pointer = nullptr;445446uint32_t pointer_enter_serial = 0;447448struct wp_cursor_shape_device_v1 *wp_cursor_shape_device = nullptr;449450struct zwp_relative_pointer_v1 *wp_relative_pointer = nullptr;451struct zwp_locked_pointer_v1 *wp_locked_pointer = nullptr;452struct zwp_confined_pointer_v1 *wp_confined_pointer = nullptr;453454struct zwp_pointer_gesture_pinch_v1 *wp_pointer_gesture_pinch = nullptr;455456// NOTE: According to the wp_pointer_gestures protocol specification, there457// can be only one active gesture at a time.458Gesture active_gesture = Gesture::NONE;459460// Used for delta calculations.461// NOTE: The wp_pointer_gestures protocol keeps track of the total scale of462// the pinch gesture, while godot instead wants its delta.463wl_fixed_t old_pinch_scale = 0;464465struct wl_surface *cursor_surface = nullptr;466struct wl_callback *cursor_frame_callback = nullptr;467uint32_t cursor_time_ms = 0;468469// This variable is needed to buffer all pointer changes until a470// wl_pointer.frame event, as per Wayland's specification. Everything is471// first set in `data_buffer` and then `data` is set with its contents on472// an input frame event. All methods should generally read from473// `pointer_data` and write to `data_buffer`.474PointerData pointer_data_buffer;475PointerData pointer_data;476477// Keyboard.478struct wl_keyboard *wl_keyboard = nullptr;479480// For key events.481DisplayServer::WindowID focused_id = DisplayServer::INVALID_WINDOW_ID;482483struct xkb_context *xkb_context = nullptr;484struct xkb_keymap *xkb_keymap = nullptr;485struct xkb_state *xkb_state = nullptr;486struct xkb_compose_state *xkb_compose_state = nullptr;487struct xkb_compose_table *xkb_compose_table = nullptr;488489const char *keymap_buffer = nullptr;490uint32_t keymap_buffer_size = 0;491492HashMap<xkb_keycode_t, Key> pressed_keycodes;493494xkb_layout_index_t current_layout_index = 0;495496// Clients with `wl_seat`s older than version 4 do not support497// `wl_keyboard::repeat_info`, so we'll provide a reasonable default of 25498// keys per second, with a start delay of 600 milliseconds.499int32_t repeat_key_delay_msec = 1000 / 25;500int32_t repeat_start_delay_msec = 600;501502xkb_keycode_t repeating_keycode = XKB_KEYCODE_INVALID;503uint64_t last_repeat_start_msec = 0;504uint64_t last_repeat_msec = 0;505506uint32_t mods_depressed = 0;507uint32_t mods_latched = 0;508uint32_t mods_locked = 0;509510bool shift_pressed = false;511bool ctrl_pressed = false;512bool alt_pressed = false;513bool meta_pressed = false;514515uint32_t last_key_pressed_serial = 0;516517struct wl_data_device *wl_data_device = nullptr;518519// Drag and drop.520DisplayServer::WindowID dnd_id = DisplayServer::INVALID_WINDOW_ID;521struct wl_data_offer *wl_data_offer_dnd = nullptr;522uint32_t dnd_enter_serial = 0;523524// Clipboard.525struct wl_data_source *wl_data_source_selection = nullptr;526Vector<uint8_t> selection_data;527528struct wl_data_offer *wl_data_offer_selection = nullptr;529530// Primary selection.531struct zwp_primary_selection_device_v1 *wp_primary_selection_device = nullptr;532533struct zwp_primary_selection_source_v1 *wp_primary_selection_source = nullptr;534Vector<uint8_t> primary_data;535536struct zwp_primary_selection_offer_v1 *wp_primary_selection_offer = nullptr;537538// Tablet.539struct zwp_tablet_seat_v2 *wp_tablet_seat = nullptr;540541List<struct zwp_tablet_tool_v2 *> tablet_tools;542543// IME.544struct zwp_text_input_v3 *wp_text_input = nullptr;545DisplayServer::WindowID ime_window_id = DisplayServer::INVALID_WINDOW_ID;546bool ime_enabled = false;547bool ime_active = false;548String ime_text;549String ime_text_commit;550Vector2i ime_cursor;551Rect2i ime_rect;552};553554struct CustomCursor {555struct wl_buffer *wl_buffer = nullptr;556uint32_t *buffer_data = nullptr;557uint32_t buffer_data_size = 0;558559Point2i hotspot;560};561562struct EmbeddingCompositorState {563LocalVector<struct godot_embedded_client *> clients;564565// Only a client per PID can create a window.566HashMap<int, struct godot_embedded_client *> mapped_clients;567568OS::ProcessID focused_pid = -1;569};570571struct EmbeddedClientState {572struct godot_embedding_compositor *embedding_compositor = nullptr;573574uint32_t pid = 0;575bool window_mapped = false;576};577578private:579struct ThreadData {580SafeFlag thread_done;581Mutex mutex;582583struct wl_display *wl_display = nullptr;584};585586// FIXME: Is this the right thing to do?587inline static const char *proxy_tag = "godot";588589Thread events_thread;590ThreadData thread_data;591592HashMap<DisplayServer::WindowID, WindowState> windows;593594List<Ref<Message>> messages;595596xdg_toplevel_icon_v1 *xdg_icon = nullptr;597wl_buffer *icon_buffer = nullptr;598599String cursor_theme_name;600int unscaled_cursor_size = 24;601602// NOTE: Regarding screen scale handling, the cursor cache is currently603// "static", by which I mean that we try to change it as little as possible and604// thus will be as big as the largest screen. This is mainly due to the fact605// that doing it dynamically doesn't look like it's worth it to me currently,606// especially as usually screen scales don't change continuously.607int cursor_scale = 1;608609// Use cursor-shape-v1 protocol if the compositor supports it.610wp_cursor_shape_device_v1_shape standard_cursors[DisplayServer::CURSOR_MAX] = {611wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT, //CURSOR_ARROW612wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_TEXT, //CURSOR_IBEAM613wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_POINTER, //CURSOR_POINTING_HAND614wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_CROSSHAIR, //CURSOR_CROSS615wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_WAIT, //CURSOR_WAIT616wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_PROGRESS, //CURSOR_BUSY617wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_GRAB, //CURSOR_DRAG618wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_GRABBING, //CURSOR_CAN_DROP619wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NO_DROP, //CURSOR_FORBIDDEN620wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NS_RESIZE, //CURSOR_VSIZE621wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_EW_RESIZE, //CURSOR_HSIZE622wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NESW_RESIZE, //CURSOR_BDIAGSIZE623wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_NWSE_RESIZE, //CURSOR_FDIAGSIZE624wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_MOVE, //CURSOR_MOVE625wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_ROW_RESIZE, //CURSOR_VSPLIT626wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_COL_RESIZE, //CURSOR_HSPLIT627wp_cursor_shape_device_v1_shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_HELP, //CURSOR_HELP628};629630// Fallback to reading $XCURSOR and system themes if the compositor does not.631struct wl_cursor_theme *wl_cursor_theme = nullptr;632struct wl_cursor *wl_cursors[DisplayServer::CURSOR_MAX] = {};633634// User-defined cursor overrides. Take precedence over standard and wl cursors.635HashMap<DisplayServer::CursorShape, CustomCursor> custom_cursors;636637DisplayServer::CursorShape cursor_shape = DisplayServer::CURSOR_ARROW;638bool cursor_visible = true;639640PointerConstraint pointer_constraint = PointerConstraint::NONE;641642struct wl_display *wl_display = nullptr;643struct wl_registry *wl_registry = nullptr;644645struct wl_seat *wl_seat_current = nullptr;646647bool frame = true;648649RegistryState registry;650651bool initialized = false;652653#ifdef TOOLS_ENABLED654WaylandEmbedder embedder;655#endif656657#ifdef LIBDECOR_ENABLED658struct libdecor *libdecor_context = nullptr;659#endif // LIBDECOR_ENABLED660661// Main polling method.662static void _poll_events_thread(void *p_data);663664// Core Wayland event handlers.665static void _wl_registry_on_global(void *data, struct wl_registry *wl_registry, uint32_t name, const char *interface, uint32_t version);666static void _wl_registry_on_global_remove(void *data, struct wl_registry *wl_registry, uint32_t name);667668static void _wl_surface_on_enter(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output);669static void _wl_surface_on_leave(void *data, struct wl_surface *wl_surface, struct wl_output *wl_output);670static void _wl_surface_on_preferred_buffer_scale(void *data, struct wl_surface *wl_surface, int32_t factor);671static void _wl_surface_on_preferred_buffer_transform(void *data, struct wl_surface *wl_surface, uint32_t transform);672673static void _frame_wl_callback_on_done(void *data, struct wl_callback *wl_callback, uint32_t callback_data);674675static void _wl_output_on_geometry(void *data, struct wl_output *wl_output, int32_t x, int32_t y, int32_t physical_width, int32_t physical_height, int32_t subpixel, const char *make, const char *model, int32_t transform);676static void _wl_output_on_mode(void *data, struct wl_output *wl_output, uint32_t flags, int32_t width, int32_t height, int32_t refresh);677static void _wl_output_on_done(void *data, struct wl_output *wl_output);678static void _wl_output_on_scale(void *data, struct wl_output *wl_output, int32_t factor);679static void _wl_output_on_name(void *data, struct wl_output *wl_output, const char *name);680static void _wl_output_on_description(void *data, struct wl_output *wl_output, const char *description);681682static void _wl_seat_on_capabilities(void *data, struct wl_seat *wl_seat, uint32_t capabilities);683static void _wl_seat_on_name(void *data, struct wl_seat *wl_seat, const char *name);684685static void _cursor_frame_callback_on_done(void *data, struct wl_callback *wl_callback, uint32_t time_ms);686687static void _wl_pointer_on_enter(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y);688static void _wl_pointer_on_leave(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface);689static void _wl_pointer_on_motion(void *data, struct wl_pointer *wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y);690static void _wl_pointer_on_button(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state);691static void _wl_pointer_on_axis(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value);692static void _wl_pointer_on_frame(void *data, struct wl_pointer *wl_pointer);693static void _wl_pointer_on_axis_source(void *data, struct wl_pointer *wl_pointer, uint32_t axis_source);694static void _wl_pointer_on_axis_stop(void *data, struct wl_pointer *wl_pointer, uint32_t time, uint32_t axis);695static void _wl_pointer_on_axis_discrete(void *data, struct wl_pointer *wl_pointer, uint32_t axis, int32_t discrete);696static void _wl_pointer_on_axis_value120(void *data, struct wl_pointer *wl_pointer, uint32_t axis, int32_t value120);697static void _wl_pointer_on_axis_relative_direction(void *data, struct wl_pointer *wl_pointer, uint32_t axis, uint32_t direction);698699static void _wl_keyboard_on_keymap(void *data, struct wl_keyboard *wl_keyboard, uint32_t format, int32_t fd, uint32_t size);700static void _wl_keyboard_on_enter(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface, struct wl_array *keys);701static void _wl_keyboard_on_leave(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *surface);702static void _wl_keyboard_on_key(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state);703static void _wl_keyboard_on_modifiers(void *data, struct wl_keyboard *wl_keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group);704static void _wl_keyboard_on_repeat_info(void *data, struct wl_keyboard *wl_keyboard, int32_t rate, int32_t delay);705706static void _wl_data_device_on_data_offer(void *data, struct wl_data_device *wl_data_device, struct wl_data_offer *id);707static void _wl_data_device_on_enter(void *data, struct wl_data_device *wl_data_device, uint32_t serial, struct wl_surface *surface, wl_fixed_t x, wl_fixed_t y, struct wl_data_offer *id);708static void _wl_data_device_on_leave(void *data, struct wl_data_device *wl_data_device);709static void _wl_data_device_on_motion(void *data, struct wl_data_device *wl_data_device, uint32_t time, wl_fixed_t x, wl_fixed_t y);710static void _wl_data_device_on_drop(void *data, struct wl_data_device *wl_data_device);711static void _wl_data_device_on_selection(void *data, struct wl_data_device *wl_data_device, struct wl_data_offer *id);712713static void _wl_data_offer_on_offer(void *data, struct wl_data_offer *wl_data_offer, const char *mime_type);714static void _wl_data_offer_on_source_actions(void *data, struct wl_data_offer *wl_data_offer, uint32_t source_actions);715static void _wl_data_offer_on_action(void *data, struct wl_data_offer *wl_data_offer, uint32_t dnd_action);716717static void _wl_data_source_on_target(void *data, struct wl_data_source *wl_data_source, const char *mime_type);718static void _wl_data_source_on_send(void *data, struct wl_data_source *wl_data_source, const char *mime_type, int32_t fd);719static void _wl_data_source_on_cancelled(void *data, struct wl_data_source *wl_data_source);720static void _wl_data_source_on_dnd_drop_performed(void *data, struct wl_data_source *wl_data_source);721static void _wl_data_source_on_dnd_finished(void *data, struct wl_data_source *wl_data_source);722static void _wl_data_source_on_action(void *data, struct wl_data_source *wl_data_source, uint32_t dnd_action);723724// xdg-shell event handlers.725static void _xdg_wm_base_on_ping(void *data, struct xdg_wm_base *xdg_wm_base, uint32_t serial);726727static void _xdg_surface_on_configure(void *data, struct xdg_surface *xdg_surface, uint32_t serial);728729static void _xdg_toplevel_on_configure(void *data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height, struct wl_array *states);730static void _xdg_toplevel_on_close(void *data, struct xdg_toplevel *xdg_toplevel);731static void _xdg_toplevel_on_configure_bounds(void *data, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height);732static void _xdg_toplevel_on_wm_capabilities(void *data, struct xdg_toplevel *xdg_toplevel, struct wl_array *capabilities);733734static void _xdg_popup_on_configure(void *data, struct xdg_popup *xdg_popup, int32_t x, int32_t y, int32_t width, int32_t height);735static void _xdg_popup_on_popup_done(void *data, struct xdg_popup *xdg_popup);736static void _xdg_popup_on_repositioned(void *data, struct xdg_popup *xdg_popup, uint32_t token);737738// wayland-protocols event handlers.739static void _wp_fractional_scale_on_preferred_scale(void *data, struct wp_fractional_scale_v1 *wp_fractional_scale_v1, uint32_t scale);740741static void _wp_relative_pointer_on_relative_motion(void *data, struct zwp_relative_pointer_v1 *wp_relative_pointer_v1, uint32_t uptime_hi, uint32_t uptime_lo, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t dx_unaccel, wl_fixed_t dy_unaccel);742743static void _wp_pointer_gesture_pinch_on_begin(void *data, struct zwp_pointer_gesture_pinch_v1 *wp_pointer_gesture_pinch_v1, uint32_t serial, uint32_t time, struct wl_surface *surface, uint32_t fingers);744static void _wp_pointer_gesture_pinch_on_update(void *data, struct zwp_pointer_gesture_pinch_v1 *wp_pointer_gesture_pinch_v1, uint32_t time, wl_fixed_t dx, wl_fixed_t dy, wl_fixed_t scale, wl_fixed_t rotation);745static void _wp_pointer_gesture_pinch_on_end(void *data, struct zwp_pointer_gesture_pinch_v1 *zp_pointer_gesture_pinch_v1, uint32_t serial, uint32_t time, int32_t cancelled);746747static void _wp_primary_selection_device_on_data_offer(void *data, struct zwp_primary_selection_device_v1 *wp_primary_selection_device_v1, struct zwp_primary_selection_offer_v1 *offer);748static void _wp_primary_selection_device_on_selection(void *data, struct zwp_primary_selection_device_v1 *wp_primary_selection_device_v1, struct zwp_primary_selection_offer_v1 *id);749750static void _wp_primary_selection_offer_on_offer(void *data, struct zwp_primary_selection_offer_v1 *wp_primary_selection_offer_v1, const char *mime_type);751752static void _wp_primary_selection_source_on_send(void *data, struct zwp_primary_selection_source_v1 *wp_primary_selection_source_v1, const char *mime_type, int32_t fd);753static void _wp_primary_selection_source_on_cancelled(void *data, struct zwp_primary_selection_source_v1 *wp_primary_selection_source_v1);754755static void _wp_tablet_seat_on_tablet_added(void *data, struct zwp_tablet_seat_v2 *wp_tablet_seat_v2, struct zwp_tablet_v2 *id);756static void _wp_tablet_seat_on_tool_added(void *data, struct zwp_tablet_seat_v2 *wp_tablet_seat_v2, struct zwp_tablet_tool_v2 *id);757static void _wp_tablet_seat_on_pad_added(void *data, struct zwp_tablet_seat_v2 *wp_tablet_seat_v2, struct zwp_tablet_pad_v2 *id);758759static void _wp_tablet_tool_on_type(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t tool_type);760static void _wp_tablet_tool_on_hardware_serial(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t hardware_serial_hi, uint32_t hardware_serial_lo);761static void _wp_tablet_tool_on_hardware_id_wacom(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t hardware_id_hi, uint32_t hardware_id_lo);762static void _wp_tablet_tool_on_capability(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t capability);763static void _wp_tablet_tool_on_done(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2);764static void _wp_tablet_tool_on_removed(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2);765static void _wp_tablet_tool_on_proximity_in(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t serial, struct zwp_tablet_v2 *tablet, struct wl_surface *surface);766static void _wp_tablet_tool_on_proximity_out(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2);767static void _wp_tablet_tool_on_down(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t serial);768static void _wp_tablet_tool_on_up(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2);769static void _wp_tablet_tool_on_motion(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, wl_fixed_t x, wl_fixed_t y);770static void _wp_tablet_tool_on_pressure(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t pressure);771static void _wp_tablet_tool_on_distance(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t distance);772static void _wp_tablet_tool_on_tilt(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, wl_fixed_t tilt_x, wl_fixed_t tilt_y);773static void _wp_tablet_tool_on_rotation(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, wl_fixed_t degrees);774static void _wp_tablet_tool_on_slider(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, int32_t position);775static void _wp_tablet_tool_on_wheel(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, wl_fixed_t degrees, int32_t clicks);776static void _wp_tablet_tool_on_button(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t serial, uint32_t button, uint32_t state);777static void _wp_tablet_tool_on_frame(void *data, struct zwp_tablet_tool_v2 *wp_tablet_tool_v2, uint32_t time);778779static void _wp_text_input_on_enter(void *data, struct zwp_text_input_v3 *wp_text_input_v3, struct wl_surface *surface);780static void _wp_text_input_on_leave(void *data, struct zwp_text_input_v3 *wp_text_input_v3, struct wl_surface *surface);781static void _wp_text_input_on_preedit_string(void *data, struct zwp_text_input_v3 *wp_text_input_v3, const char *text, int32_t cursor_begin, int32_t cursor_end);782static void _wp_text_input_on_commit_string(void *data, struct zwp_text_input_v3 *wp_text_input_v3, const char *text);783static void _wp_text_input_on_delete_surrounding_text(void *data, struct zwp_text_input_v3 *wp_text_input_v3, uint32_t before_length, uint32_t after_length);784static void _wp_text_input_on_done(void *data, struct zwp_text_input_v3 *wp_text_input_v3, uint32_t serial);785786static void _xdg_toplevel_decoration_on_configure(void *data, struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration, uint32_t mode);787788// NOTE: Deprecated.789static void _xdg_exported_v1_on_handle(void *data, zxdg_exported_v1 *exported, const char *handle);790791static void _xdg_exported_v2_on_handle(void *data, zxdg_exported_v2 *exported, const char *handle);792793static void _xdg_activation_token_on_done(void *data, struct xdg_activation_token_v1 *xdg_activation_token, const char *token);794795static void _godot_embedding_compositor_on_client(void *data, struct godot_embedding_compositor *godot_embedding_compositor, struct godot_embedded_client *godot_embedded_client, int32_t pid);796797static void _godot_embedded_client_on_disconnected(void *data, struct godot_embedded_client *godot_embedded_client);798static void _godot_embedded_client_on_window_embedded(void *data, struct godot_embedded_client *godot_embedded_client);799static void _godot_embedded_client_on_window_focus_in(void *data, struct godot_embedded_client *godot_embedded_client);800static void _godot_embedded_client_on_window_focus_out(void *data, struct godot_embedded_client *godot_embedded_client);801802// Core Wayland event listeners.803static constexpr struct wl_registry_listener wl_registry_listener = {804.global = _wl_registry_on_global,805.global_remove = _wl_registry_on_global_remove,806};807808static constexpr struct wl_surface_listener wl_surface_listener = {809.enter = _wl_surface_on_enter,810.leave = _wl_surface_on_leave,811.preferred_buffer_scale = _wl_surface_on_preferred_buffer_scale,812.preferred_buffer_transform = _wl_surface_on_preferred_buffer_transform,813};814815static constexpr struct wl_callback_listener frame_wl_callback_listener = {816.done = _frame_wl_callback_on_done,817};818819static constexpr struct wl_output_listener wl_output_listener = {820.geometry = _wl_output_on_geometry,821.mode = _wl_output_on_mode,822.done = _wl_output_on_done,823.scale = _wl_output_on_scale,824.name = _wl_output_on_name,825.description = _wl_output_on_description,826};827828static constexpr struct wl_seat_listener wl_seat_listener = {829.capabilities = _wl_seat_on_capabilities,830.name = _wl_seat_on_name,831};832833static constexpr struct wl_callback_listener cursor_frame_callback_listener = {834.done = _cursor_frame_callback_on_done,835};836837static constexpr struct wl_pointer_listener wl_pointer_listener = {838.enter = _wl_pointer_on_enter,839.leave = _wl_pointer_on_leave,840.motion = _wl_pointer_on_motion,841.button = _wl_pointer_on_button,842.axis = _wl_pointer_on_axis,843.frame = _wl_pointer_on_frame,844.axis_source = _wl_pointer_on_axis_source,845.axis_stop = _wl_pointer_on_axis_stop,846.axis_discrete = _wl_pointer_on_axis_discrete,847.axis_value120 = _wl_pointer_on_axis_value120,848.axis_relative_direction = _wl_pointer_on_axis_relative_direction,849};850851static constexpr struct wl_keyboard_listener wl_keyboard_listener = {852.keymap = _wl_keyboard_on_keymap,853.enter = _wl_keyboard_on_enter,854.leave = _wl_keyboard_on_leave,855.key = _wl_keyboard_on_key,856.modifiers = _wl_keyboard_on_modifiers,857.repeat_info = _wl_keyboard_on_repeat_info,858};859860static constexpr struct wl_data_device_listener wl_data_device_listener = {861.data_offer = _wl_data_device_on_data_offer,862.enter = _wl_data_device_on_enter,863.leave = _wl_data_device_on_leave,864.motion = _wl_data_device_on_motion,865.drop = _wl_data_device_on_drop,866.selection = _wl_data_device_on_selection,867};868869static constexpr struct wl_data_offer_listener wl_data_offer_listener = {870.offer = _wl_data_offer_on_offer,871.source_actions = _wl_data_offer_on_source_actions,872.action = _wl_data_offer_on_action,873};874875static constexpr struct wl_data_source_listener wl_data_source_listener = {876.target = _wl_data_source_on_target,877.send = _wl_data_source_on_send,878.cancelled = _wl_data_source_on_cancelled,879.dnd_drop_performed = _wl_data_source_on_dnd_drop_performed,880.dnd_finished = _wl_data_source_on_dnd_finished,881.action = _wl_data_source_on_action,882};883884// xdg-shell event listeners.885static constexpr struct xdg_wm_base_listener xdg_wm_base_listener = {886.ping = _xdg_wm_base_on_ping,887};888889static constexpr struct xdg_surface_listener xdg_surface_listener = {890.configure = _xdg_surface_on_configure,891};892893static constexpr struct xdg_toplevel_listener xdg_toplevel_listener = {894.configure = _xdg_toplevel_on_configure,895.close = _xdg_toplevel_on_close,896.configure_bounds = _xdg_toplevel_on_configure_bounds,897.wm_capabilities = _xdg_toplevel_on_wm_capabilities,898};899900static constexpr struct xdg_popup_listener xdg_popup_listener = {901.configure = _xdg_popup_on_configure,902.popup_done = _xdg_popup_on_popup_done,903.repositioned = _xdg_popup_on_repositioned,904};905906// wayland-protocols event listeners.907static constexpr struct wp_fractional_scale_v1_listener wp_fractional_scale_listener = {908.preferred_scale = _wp_fractional_scale_on_preferred_scale,909};910911static constexpr struct zwp_relative_pointer_v1_listener wp_relative_pointer_listener = {912.relative_motion = _wp_relative_pointer_on_relative_motion,913};914915static constexpr struct zwp_pointer_gesture_pinch_v1_listener wp_pointer_gesture_pinch_listener = {916.begin = _wp_pointer_gesture_pinch_on_begin,917.update = _wp_pointer_gesture_pinch_on_update,918.end = _wp_pointer_gesture_pinch_on_end,919};920921static constexpr struct zwp_primary_selection_device_v1_listener wp_primary_selection_device_listener = {922.data_offer = _wp_primary_selection_device_on_data_offer,923.selection = _wp_primary_selection_device_on_selection,924};925926static constexpr struct zwp_primary_selection_offer_v1_listener wp_primary_selection_offer_listener = {927.offer = _wp_primary_selection_offer_on_offer,928};929930static constexpr struct zwp_primary_selection_source_v1_listener wp_primary_selection_source_listener = {931.send = _wp_primary_selection_source_on_send,932.cancelled = _wp_primary_selection_source_on_cancelled,933};934935static constexpr struct zwp_tablet_seat_v2_listener wp_tablet_seat_listener = {936.tablet_added = _wp_tablet_seat_on_tablet_added,937.tool_added = _wp_tablet_seat_on_tool_added,938.pad_added = _wp_tablet_seat_on_pad_added,939};940941static constexpr struct zwp_tablet_tool_v2_listener wp_tablet_tool_listener = {942.type = _wp_tablet_tool_on_type,943.hardware_serial = _wp_tablet_tool_on_hardware_serial,944.hardware_id_wacom = _wp_tablet_tool_on_hardware_id_wacom,945.capability = _wp_tablet_tool_on_capability,946.done = _wp_tablet_tool_on_done,947.removed = _wp_tablet_tool_on_removed,948.proximity_in = _wp_tablet_tool_on_proximity_in,949.proximity_out = _wp_tablet_tool_on_proximity_out,950.down = _wp_tablet_tool_on_down,951.up = _wp_tablet_tool_on_up,952.motion = _wp_tablet_tool_on_motion,953.pressure = _wp_tablet_tool_on_pressure,954.distance = _wp_tablet_tool_on_distance,955.tilt = _wp_tablet_tool_on_tilt,956.rotation = _wp_tablet_tool_on_rotation,957.slider = _wp_tablet_tool_on_slider,958.wheel = _wp_tablet_tool_on_wheel,959.button = _wp_tablet_tool_on_button,960.frame = _wp_tablet_tool_on_frame,961};962963static constexpr struct zwp_text_input_v3_listener wp_text_input_listener = {964.enter = _wp_text_input_on_enter,965.leave = _wp_text_input_on_leave,966.preedit_string = _wp_text_input_on_preedit_string,967.commit_string = _wp_text_input_on_commit_string,968.delete_surrounding_text = _wp_text_input_on_delete_surrounding_text,969.done = _wp_text_input_on_done,970};971972// NOTE: Deprecated.973static constexpr struct zxdg_exported_v1_listener xdg_exported_v1_listener = {974.handle = _xdg_exported_v1_on_handle,975};976977static constexpr struct zxdg_exported_v2_listener xdg_exported_v2_listener = {978.handle = _xdg_exported_v2_on_handle,979};980981static constexpr struct zxdg_toplevel_decoration_v1_listener xdg_toplevel_decoration_listener = {982.configure = _xdg_toplevel_decoration_on_configure,983};984985static constexpr struct xdg_activation_token_v1_listener xdg_activation_token_listener = {986.done = _xdg_activation_token_on_done,987};988989// Godot interfaces.990static constexpr struct godot_embedding_compositor_listener godot_embedding_compositor_listener = {991.client = _godot_embedding_compositor_on_client,992};993994static constexpr struct godot_embedded_client_listener godot_embedded_client_listener = {995.disconnected = _godot_embedded_client_on_disconnected,996.window_embedded = _godot_embedded_client_on_window_embedded,997.window_focus_in = _godot_embedded_client_on_window_focus_in,998.window_focus_out = _godot_embedded_client_on_window_focus_out,999};10001001#ifdef LIBDECOR_ENABLED1002// libdecor event handlers.1003static void libdecor_on_error(struct libdecor *context, enum libdecor_error error, const char *message);10041005static void libdecor_frame_on_configure(struct libdecor_frame *frame, struct libdecor_configuration *configuration, void *user_data);10061007static void libdecor_frame_on_close(struct libdecor_frame *frame, void *user_data);10081009static void libdecor_frame_on_commit(struct libdecor_frame *frame, void *user_data);10101011static void libdecor_frame_on_dismiss_popup(struct libdecor_frame *frame, const char *seat_name, void *user_data);10121013// libdecor event listeners.1014static constexpr struct libdecor_interface libdecor_interface = {1015.error = libdecor_on_error,1016.reserved0 = nullptr,1017.reserved1 = nullptr,1018.reserved2 = nullptr,1019.reserved3 = nullptr,1020.reserved4 = nullptr,1021.reserved5 = nullptr,1022.reserved6 = nullptr,1023.reserved7 = nullptr,1024.reserved8 = nullptr,1025.reserved9 = nullptr,1026};10271028static constexpr struct libdecor_frame_interface libdecor_frame_interface = {1029.configure = libdecor_frame_on_configure,1030.close = libdecor_frame_on_close,1031.commit = libdecor_frame_on_commit,1032.dismiss_popup = libdecor_frame_on_dismiss_popup,1033.reserved0 = nullptr,1034.reserved1 = nullptr,1035.reserved2 = nullptr,1036.reserved3 = nullptr,1037.reserved4 = nullptr,1038.reserved5 = nullptr,1039.reserved6 = nullptr,1040.reserved7 = nullptr,1041.reserved8 = nullptr,1042.reserved9 = nullptr,1043};1044#endif // LIBDECOR_ENABLED10451046static Vector<uint8_t> _read_fd(int fd);1047static int _allocate_shm_file(size_t size);10481049static Vector<uint8_t> _wl_data_offer_read(struct wl_display *wl_display, const char *p_mime, struct wl_data_offer *wl_data_offer);1050static Vector<uint8_t> _wp_primary_selection_offer_read(struct wl_display *wl_display, const char *p_mime, struct zwp_primary_selection_offer_v1 *wp_primary_selection_offer);10511052static void _seat_state_set_current(WaylandThread::SeatState &p_ss);1053static Ref<InputEventKey> _seat_state_get_key_event(SeatState *p_ss, xkb_keycode_t p_keycode, bool p_pressed);1054static Ref<InputEventKey> _seat_state_get_unstuck_key_event(SeatState *p_ss, xkb_keycode_t p_keycode, bool p_pressed, Key p_key);10551056static void _seat_state_handle_xkb_keycode(SeatState *p_ss, xkb_keycode_t p_xkb_keycode, bool p_pressed, bool p_echo = false);10571058static void _wayland_state_update_cursor();10591060void _set_current_seat(struct wl_seat *p_seat);10611062bool _load_cursor_theme(int p_cursor_size);10631064void _update_scale(int p_scale);10651066public:1067Mutex &mutex = thread_data.mutex;10681069struct wl_display *get_wl_display() const;10701071// Core Wayland utilities for integrating with our own data structures.1072static bool wl_proxy_is_godot(struct wl_proxy *p_proxy);1073static void wl_proxy_tag_godot(struct wl_proxy *p_proxy);10741075static WindowState *wl_surface_get_window_state(struct wl_surface *p_surface);1076static ScreenState *wl_output_get_screen_state(struct wl_output *p_output);1077static SeatState *wl_seat_get_seat_state(struct wl_seat *p_seat);1078static TabletToolState *wp_tablet_tool_get_state(struct zwp_tablet_tool_v2 *p_tool);1079static OfferState *wl_data_offer_get_offer_state(struct wl_data_offer *p_offer);10801081static OfferState *wp_primary_selection_offer_get_offer_state(struct zwp_primary_selection_offer_v1 *p_offer);10821083static EmbeddingCompositorState *godot_embedding_compositor_get_state(struct godot_embedding_compositor *p_compositor);10841085void seat_state_unlock_pointer(SeatState *p_ss);1086void seat_state_lock_pointer(SeatState *p_ss);1087void seat_state_set_hint(SeatState *p_ss, int p_x, int p_y);1088void seat_state_confine_pointer(SeatState *p_ss);10891090static void seat_state_update_cursor(SeatState *p_ss);10911092void seat_state_echo_keys(SeatState *p_ss);10931094static int window_state_get_preferred_buffer_scale(WindowState *p_ws);1095static double window_state_get_scale_factor(const WindowState *p_ws);1096static void window_state_update_size(WindowState *p_ws, int p_width, int p_height);10971098static Vector2i scale_vector2i(const Vector2i &p_vector, double p_amount);10991100void push_message(Ref<Message> message);1101bool has_message();1102Ref<Message> pop_message();11031104void beep() const;11051106void set_icon(const Ref<Image> &p_icon);11071108void window_create(DisplayServer::WindowID p_window_id, const Size2i &p_size, DisplayServer::WindowID p_parent_id = DisplayServer::INVALID_WINDOW_ID);1109void window_create_popup(DisplayServer::WindowID p_window_id, DisplayServer::WindowID p_parent_id, Rect2i p_rect);1110void window_destroy(DisplayServer::WindowID p_window_Id);11111112void window_set_parent(DisplayServer::WindowID p_window_id, DisplayServer::WindowID p_parent_id);11131114struct wl_surface *window_get_wl_surface(DisplayServer::WindowID p_window_id) const;1115WindowState *window_get_state(DisplayServer::WindowID p_window_id);1116const WindowState *window_get_state(DisplayServer::WindowID p_window_id) const;1117Size2i window_set_size(DisplayServer::WindowID p_window_id, const Size2i &p_size);11181119void window_start_resize(DisplayServer::WindowResizeEdge p_edge, DisplayServer::WindowID p_window);11201121void window_set_max_size(DisplayServer::WindowID p_window_id, const Size2i &p_size);1122void window_set_min_size(DisplayServer::WindowID p_window_id, const Size2i &p_size);11231124bool window_can_set_mode(DisplayServer::WindowID p_window_id, DisplayServer::WindowMode p_window_mode) const;1125void window_try_set_mode(DisplayServer::WindowID p_window_id, DisplayServer::WindowMode p_window_mode);1126DisplayServer::WindowMode window_get_mode(DisplayServer::WindowID p_window_id) const;11271128void window_set_borderless(DisplayServer::WindowID p_window_id, bool p_borderless);1129void window_set_title(DisplayServer::WindowID p_window_id, const String &p_title);1130void window_set_app_id(DisplayServer::WindowID p_window_id, const String &p_app_id);11311132bool window_is_focused(DisplayServer::WindowID p_window_id);11331134// Optional - requires xdg_activation_v11135void window_request_attention(DisplayServer::WindowID p_window_id);11361137void window_start_drag(DisplayServer::WindowID p_window_id);11381139// Optional - require idle_inhibit_unstable_v11140void window_set_idle_inhibition(DisplayServer::WindowID p_window_id, bool p_enable);1141bool window_get_idle_inhibition(DisplayServer::WindowID p_window_id) const;11421143ScreenData screen_get_data(int p_screen) const;1144int get_screen_count() const;11451146void pointer_set_constraint(PointerConstraint p_constraint);1147void pointer_set_hint(const Point2i &p_hint);1148PointerConstraint pointer_get_constraint() const;1149DisplayServer::WindowID pointer_get_pointed_window_id() const;1150DisplayServer::WindowID pointer_get_last_pointed_window_id() const;1151BitField<MouseButtonMask> pointer_get_button_mask() const;11521153void cursor_set_visible(bool p_visible);1154void cursor_set_shape(DisplayServer::CursorShape p_cursor_shape);11551156void cursor_set_custom_shape(DisplayServer::CursorShape p_cursor_shape);1157void cursor_shape_set_custom_image(DisplayServer::CursorShape p_cursor_shape, Ref<Image> p_image, const Point2i &p_hotspot);1158void cursor_shape_clear_custom_image(DisplayServer::CursorShape p_cursor_shape);11591160void window_set_ime_active(const bool p_active, DisplayServer::WindowID p_window_id);1161void window_set_ime_position(const Point2i &p_pos, DisplayServer::WindowID p_window_id);11621163int keyboard_get_layout_count() const;1164int keyboard_get_current_layout_index() const;1165void keyboard_set_current_layout_index(int p_index);1166String keyboard_get_layout_name(int p_index) const;11671168Key keyboard_get_key_from_physical(Key p_key) const;1169Key keyboard_get_label_from_physical(Key p_key) const;11701171void keyboard_echo_keys();11721173bool selection_has_mime(const String &p_mime) const;1174Vector<uint8_t> selection_get_mime(const String &p_mime) const;11751176void selection_set_text(const String &p_text);11771178// Optional primary support - requires wp_primary_selection_unstable_v11179bool primary_has_mime(const String &p_mime) const;1180Vector<uint8_t> primary_get_mime(const String &p_mime) const;11811182void primary_set_text(const String &p_text);11831184void commit_surfaces();11851186void set_frame();1187bool get_reset_frame();1188bool wait_frame_suspend_ms(int p_timeout);1189bool is_fifo_available() const;11901191uint64_t window_get_last_frame_time(DisplayServer::WindowID p_window_id) const;1192bool window_is_suspended(DisplayServer::WindowID p_window_id) const;1193bool is_suspended() const;11941195struct godot_embedding_compositor *get_embedding_compositor();11961197OS::ProcessID embedded_compositor_get_focused_pid();11981199Error init();1200void destroy();1201};12021203#endif // WAYLAND_ENABLED120412051206