Wayland: Implement glfwFocusWindow

This implements window focus requests via the xdg-activation-v1
protocol.  These requests will likely only work when another window of
the same application already has input focus, but that isn't unlike the
behavior of other platforms.

The GLFW_FEATURE_UNAVAILABLE error has been removed from this function
for now.

Related to #2284
Related to #2306
Related to #2439
This commit is contained in:
Camilla Löwy 2024-02-09 03:55:14 +01:00
parent eeb403135d
commit a360198f8f
4 changed files with 37 additions and 9 deletions

View File

@ -178,6 +178,7 @@ information on what to include when reporting a bug.
- [Cocoa] Bugfix: Touching event queue from secondary thread before main thread - [Cocoa] Bugfix: Touching event queue from secondary thread before main thread
would abort (#1649) would abort (#1649)
- [Wayland] Added support for `glfwRequestWindowAttention` (#2287) - [Wayland] Added support for `glfwRequestWindowAttention` (#2287)
[Wayland] Added support for `glfwFocusWindow`
- [Wayland] Added dynamic loading of all Wayland libraries - [Wayland] Added dynamic loading of all Wayland libraries
- [Wayland] Bugfix: `CLOCK_MONOTONIC` was not correctly enabled - [Wayland] Bugfix: `CLOCK_MONOTONIC` was not correctly enabled
- [X11] Bugfix: Termination would segfault if the IM had been destroyed - [X11] Bugfix: Termination would segfault if the IM had been destroyed

View File

@ -142,9 +142,8 @@ protocols either, no decorations will be drawn around windows.
GLFW uses the [xdg-activation GLFW uses the [xdg-activation
protocol](https://wayland.app/protocols/xdg-activation-v1) protocol](https://wayland.app/protocols/xdg-activation-v1)
to enable attention requests. This protocol is part of to implement window focus and attention requests. If the running compositor
wayland-protocols staging, and mandatory at build time. If the running compositor does not support this protocol, window focus and attention requests do nothing.
does not support this protocol, the attention requests do nothing.
@section compat_glx GLX extensions @section compat_glx GLX extensions

View File

@ -3856,11 +3856,11 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window);
* *
* @param[in] window The window to give input focus. * @param[in] window The window to give input focus.
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). * GLFW_PLATFORM_ERROR.
* *
* @remark @wayland It is not possible for an application to set the input * @remark @wayland The compositor will likely ignore focus requests unless
* focus. This function will emit @ref GLFW_FEATURE_UNAVAILABLE. * another window created by the same application already has input focus.
* *
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
* *

View File

@ -2378,8 +2378,36 @@ void _glfwRequestWindowAttentionWayland(_GLFWwindow* window)
void _glfwFocusWindowWayland(_GLFWwindow* window) void _glfwFocusWindowWayland(_GLFWwindow* window)
{ {
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, if (!_glfw.wl.activationManager)
"Wayland: The platform does not support setting the input focus"); 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, void _glfwSetWindowMonitorWayland(_GLFWwindow* window,