diff --git a/README.md b/README.md index fec484e2..b23ca0ed 100644 --- a/README.md +++ b/README.md @@ -178,6 +178,7 @@ information on what to include when reporting a bug. - [Cocoa] Bugfix: Touching event queue from secondary thread before main thread would abort (#1649) - [Wayland] Added support for `glfwRequestWindowAttention` (#2287) + [Wayland] Added support for `glfwFocusWindow` - [Wayland] Added dynamic loading of all Wayland libraries - [Wayland] Bugfix: `CLOCK_MONOTONIC` was not correctly enabled - [X11] Bugfix: Termination would segfault if the IM had been destroyed diff --git a/docs/compat.dox b/docs/compat.dox index ddcd4dbc..66a92614 100644 --- a/docs/compat.dox +++ b/docs/compat.dox @@ -142,9 +142,8 @@ protocols either, no decorations will be drawn around windows. GLFW uses the [xdg-activation protocol](https://wayland.app/protocols/xdg-activation-v1) -to enable attention requests. This protocol is part of -wayland-protocols staging, and mandatory at build time. If the running compositor -does not support this protocol, the attention requests do nothing. +to implement window focus and attention requests. If the running compositor +does not support this protocol, window focus and attention requests do nothing. @section compat_glx GLX extensions diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 5e6fad42..6f8c9b41 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -3856,11 +3856,11 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window); * * @param[in] window The window to give input focus. * - * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref - * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref + * GLFW_PLATFORM_ERROR. * - * @remark @wayland It is not possible for an application to set the input - * focus. This function will emit @ref GLFW_FEATURE_UNAVAILABLE. + * @remark @wayland The compositor will likely ignore focus requests unless + * another window created by the same application already has input focus. * * @thread_safety This function must only be called from the main thread. * diff --git a/src/wl_window.c b/src/wl_window.c index 981f2401..d7f12660 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -2378,8 +2378,36 @@ void _glfwRequestWindowAttentionWayland(_GLFWwindow* window) void _glfwFocusWindowWayland(_GLFWwindow* window) { - _glfwInputError(GLFW_FEATURE_UNAVAILABLE, - "Wayland: The platform does not support setting the input focus"); + if (!_glfw.wl.activationManager) + return; + + if (window->wl.activationToken) + xdg_activation_token_v1_destroy(window->wl.activationToken); + + window->wl.activationToken = + xdg_activation_v1_get_activation_token(_glfw.wl.activationManager); + xdg_activation_token_v1_add_listener(window->wl.activationToken, + &xdgActivationListener, + window); + + xdg_activation_token_v1_set_serial(window->wl.activationToken, + _glfw.wl.serial, + _glfw.wl.seat); + + _GLFWwindow* requester = _glfw.wl.keyboardFocus; + if (requester) + { + xdg_activation_token_v1_set_surface(window->wl.activationToken, + requester->wl.surface); + + if (requester->wl.appId) + { + xdg_activation_token_v1_set_app_id(window->wl.activationToken, + requester->wl.appId); + } + } + + xdg_activation_token_v1_commit(window->wl.activationToken); } void _glfwSetWindowMonitorWayland(_GLFWwindow* window,