From 61429c73c786d7566a4733a09927d65690c3a5ed Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Fri, 3 Nov 2023 19:57:54 +0530 Subject: [PATCH] Wayland: Fix primary selections not working with the river compositor Fixes #6785 --- docs/changelog.rst | 2 ++ glfw/wl_init.c | 6 +++--- glfw/wl_platform.h | 2 +- glfw/wl_window.c | 28 +++++++--------------------- 4 files changed, 13 insertions(+), 25 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 085fef400..c98b94846 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -94,6 +94,8 @@ Detailed list of changes - ssh kitten: Fix a regression that broken :kbd:`ctrl+space` mapping in zsh (:iss:`6780`) +- Wayland: Fix primary selections not working with the river compositor (:iss:`6785`) + 0.30.1 [2023-10-05] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/glfw/wl_init.c b/glfw/wl_init.c index acff040ae..6a4e52a6a 100644 --- a/glfw/wl_init.c +++ b/glfw/wl_init.c @@ -99,7 +99,7 @@ static void pointerHandleEnter(void* data UNUSED, return; } window->wl.decorations.focus = focus; - _glfw.wl.serial = serial; _glfw.wl.input_serial = serial; + _glfw.wl.serial = serial; _glfw.wl.input_serial = serial; _glfw.wl.pointer_serial = serial; _glfw.wl.pointerFocus = window; window->wl.hovered = true; @@ -311,7 +311,7 @@ static void pointerHandleButton(void* data UNUSED, if (window->wl.decorations.focus != CENTRAL_WINDOW) return; - _glfw.wl.serial = serial; _glfw.wl.input_serial = serial; + _glfw.wl.serial = serial; _glfw.wl.input_serial = serial; _glfw.wl.pointer_serial = serial; /* Makes left, right and middle 0, 1 and 2. Overall order follows evdev * codes. */ @@ -463,7 +463,7 @@ static void keyboardHandleEnter(void* data UNUSED, return; } - _glfw.wl.serial = serial; _glfw.wl.input_serial = serial; + _glfw.wl.serial = serial; _glfw.wl.input_serial = serial; _glfw.wl.keyboard_enter_serial = serial; _glfw.wl.keyboardFocusId = window->id; _glfwInputWindowFocus(window, true); uint32_t* key; diff --git a/glfw/wl_platform.h b/glfw/wl_platform.h index 6a5fa3589..5490e8133 100644 --- a/glfw/wl_platform.h +++ b/glfw/wl_platform.h @@ -292,7 +292,7 @@ typedef struct _GLFWlibraryWayland struct wl_surface* cursorSurface; GLFWCursorShape cursorPreviousShape; - uint32_t serial, input_serial; + uint32_t serial, input_serial, pointer_serial, keyboard_enter_serial; int32_t keyboardRepeatRate; monotonic_t keyboardRepeatDelay; diff --git a/glfw/wl_window.c b/glfw/wl_window.c index c277bd0ab..619361f8b 100644 --- a/glfw/wl_window.c +++ b/glfw/wl_window.c @@ -1942,22 +1942,6 @@ static const struct zwp_primary_selection_device_v1_listener primary_selection_d }; -static void -clipboard_copy_callback_done(void *data, struct wl_callback *callback, uint32_t serial) { - if (_glfw.wl.dataDevice && data == (void*)_glfw.wl.dataSourceForClipboard) { - wl_data_device_set_selection(_glfw.wl.dataDevice, data, serial); - } - wl_callback_destroy(callback); -} - -static void -primary_selection_copy_callback_done(void *data, struct wl_callback *callback, uint32_t serial) { - if (_glfw.wl.primarySelectionDevice && data == (void*)_glfw.wl.dataSourceForPrimarySelection) { - zwp_primary_selection_device_v1_set_selection(_glfw.wl.primarySelectionDevice, data, serial); - } - wl_callback_destroy(callback); -} - void _glfwSetupWaylandDataDevice(void) { _glfw.wl.dataDevice = wl_data_device_manager_get_data_device(_glfw.wl.dataDeviceManager, _glfw.wl.seat); if (_glfw.wl.dataDevice) wl_data_device_add_listener(_glfw.wl.dataDevice, &data_device_listener, NULL); @@ -2049,13 +2033,15 @@ _glfwPlatformSetClipboard(GLFWClipboardType t) { } f(data_source, cd->mime_types[i]); } - struct wl_callback *callback = wl_display_sync(_glfw.wl.display); if (t == GLFW_CLIPBOARD) { - static const struct wl_callback_listener clipboard_copy_callback_listener = {.done = clipboard_copy_callback_done}; - wl_callback_add_listener(callback, &clipboard_copy_callback_listener, _glfw.wl.dataSourceForClipboard); + // According to the Wayland spec only the application that has keyboard focus can set the clipboard. + // Hurray for the Wayland nanny state! + wl_data_device_set_selection(_glfw.wl.dataDevice, _glfw.wl.dataSourceForClipboard, _glfw.wl.keyboard_enter_serial); } else { - static const struct wl_callback_listener primary_selection_copy_callback_listener = {.done = primary_selection_copy_callback_done}; - wl_callback_add_listener(callback, &primary_selection_copy_callback_listener, _glfw.wl.dataSourceForPrimarySelection); + // According to the Wayland spec we can only set the primary selection in response to a pointer button event + // Hurray for the Wayland nanny state! + zwp_primary_selection_device_v1_set_selection( + _glfw.wl.primarySelectionDevice, _glfw.wl.dataSourceForPrimarySelection, _glfw.wl.input_serial); } }