From b8b08ed2f994014edba4b56e3946bded68bd4668 Mon Sep 17 00:00:00 2001 From: anon3989 Date: Thu, 11 Sep 2025 18:41:26 +0000 Subject: [PATCH] Added GLFW_WAYLAND_ZWLR_KEYBOARD_ON_FOCUS --- docs/window.md | 107 ++++++++++++++++++++----------------- examples/wayland-widget.c | 30 ++++++++--- include/GLFW/glfw3.h | 31 +++++++---- include/GLFW/glfw3native.h | 17 ++++++ src/internal.h | 1 + src/window.c | 3 ++ src/wl_window.c | 59 +++++++++++++++----- 7 files changed, 167 insertions(+), 81 deletions(-) diff --git a/docs/window.md b/docs/window.md index 4f467aa31..58ec9d7bd 100644 --- a/docs/window.md +++ b/docs/window.md @@ -527,6 +527,12 @@ If success, you can control layer behavior with [](@ref glfwWaylandZwlrSetLayer) api. Example available [here](https://github.com/glfw/glfw/blob/master/examples/wayland-widget.c). +@anchor GLFW_WAYLAND_ZWLR_KEYBOARD_ON_FOCUS_hint +__GLFW_WAYLAND_ZWLR_KEYBOARD_ON_FOCUS__ By default, layer shell surfaces do not receive keyboard +events. Set this flag to automatically redirect focus to app on hover, and release it when mouse +leave surface. This is set by @ref glfwWindowHint. Otherwise, you may control keyboard focus +with [](@ref glfwWaylandZwlrSetKeyboardFocus) api. + #### X11 specific window hints {#window_hints_x11} @anchor GLFW_X11_CLASS_NAME_hint @@ -539,56 +545,57 @@ These are set with @ref glfwWindowHintString. #### Supported and default values {#window_hints_values} -Window hint | Default value | Supported values ------------------------------ | --------------------------- | ---------------- -GLFW_RESIZABLE | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` -GLFW_VISIBLE | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` -GLFW_DECORATED | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` -GLFW_FOCUSED | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` -GLFW_AUTO_ICONIFY | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` -GLFW_FLOATING | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` -GLFW_MAXIMIZED | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` -GLFW_CENTER_CURSOR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` -GLFW_TRANSPARENT_FRAMEBUFFER | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` -GLFW_FOCUS_ON_SHOW | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` -GLFW_SCALE_TO_MONITOR | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` -GLFW_SCALE_FRAMEBUFFER | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` -GLFW_MOUSE_PASSTHROUGH | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` -GLFW_POSITION_X | `GLFW_ANY_POSITION` | Any valid screen x-coordinate or `GLFW_ANY_POSITION` -GLFW_POSITION_Y | `GLFW_ANY_POSITION` | Any valid screen y-coordinate or `GLFW_ANY_POSITION` -GLFW_RED_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -GLFW_GREEN_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -GLFW_BLUE_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -GLFW_ALPHA_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -GLFW_DEPTH_BITS | 24 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -GLFW_STENCIL_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -GLFW_ACCUM_RED_BITS | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -GLFW_ACCUM_GREEN_BITS | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -GLFW_ACCUM_BLUE_BITS | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -GLFW_ACCUM_ALPHA_BITS | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -GLFW_AUX_BUFFERS | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -GLFW_SAMPLES | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` -GLFW_REFRESH_RATE | `GLFW_DONT_CARE` | 0 to `INT_MAX` or `GLFW_DONT_CARE` -GLFW_STEREO | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` -GLFW_SRGB_CAPABLE | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` -GLFW_DOUBLEBUFFER | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` -GLFW_CLIENT_API | `GLFW_OPENGL_API` | `GLFW_OPENGL_API`, `GLFW_OPENGL_ES_API` or `GLFW_NO_API` -GLFW_CONTEXT_CREATION_API | `GLFW_NATIVE_CONTEXT_API` | `GLFW_NATIVE_CONTEXT_API`, `GLFW_EGL_CONTEXT_API` or `GLFW_OSMESA_CONTEXT_API` -GLFW_CONTEXT_VERSION_MAJOR | 1 | Any valid major version number of the chosen client API -GLFW_CONTEXT_VERSION_MINOR | 0 | Any valid minor version number of the chosen client API -GLFW_CONTEXT_ROBUSTNESS | `GLFW_NO_ROBUSTNESS` | `GLFW_NO_ROBUSTNESS`, `GLFW_NO_RESET_NOTIFICATION` or `GLFW_LOSE_CONTEXT_ON_RESET` -GLFW_CONTEXT_RELEASE_BEHAVIOR | `GLFW_ANY_RELEASE_BEHAVIOR` | `GLFW_ANY_RELEASE_BEHAVIOR`, `GLFW_RELEASE_BEHAVIOR_FLUSH` or `GLFW_RELEASE_BEHAVIOR_NONE` -GLFW_OPENGL_FORWARD_COMPAT | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` -GLFW_CONTEXT_DEBUG | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` -GLFW_OPENGL_PROFILE | `GLFW_OPENGL_ANY_PROFILE` | `GLFW_OPENGL_ANY_PROFILE`, `GLFW_OPENGL_COMPAT_PROFILE` or `GLFW_OPENGL_CORE_PROFILE` -GLFW_WIN32_KEYBOARD_MENU | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` -GLFW_WIN32_SHOWDEFAULT | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` -GLFW_COCOA_FRAME_NAME | `""` | A UTF-8 encoded frame autosave name -GLFW_COCOA_GRAPHICS_SWITCHING | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` -GLFW_X11_CLASS_NAME | `""` | An ASCII encoded `WM_CLASS` class name -GLFW_X11_INSTANCE_NAME | `""` | An ASCII encoded `WM_CLASS` instance name -GLFW_WAYLAND_APP_ID | `""` | An ASCII encoded Wayland `app_id` name -GLFW_WAYLAND_USE_ZWLR | 0 | `GLFW_WAYLAND_ZWLR_LAYER_BACKGROUD`, `GLFW_WAYLAND_ZWLR_LAYER_BOTTOM`, `GLFW_WAYLAND_ZWLR_LAYER_TOP` or `GLFW_WAYLAND_ZWLR_LAYER_OVERLAY` +Window hint | Default value | Supported values +---------------------------------- | --------------------------- | ---------------- +GLFW_RESIZABLE | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_VISIBLE | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_DECORATED | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_FOCUSED | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_AUTO_ICONIFY | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_FLOATING | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_MAXIMIZED | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_CENTER_CURSOR | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_TRANSPARENT_FRAMEBUFFER | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_FOCUS_ON_SHOW | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_SCALE_TO_MONITOR | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_SCALE_FRAMEBUFFER | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_MOUSE_PASSTHROUGH | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_POSITION_X | `GLFW_ANY_POSITION` | Any valid screen x-coordinate or `GLFW_ANY_POSITION` +GLFW_POSITION_Y | `GLFW_ANY_POSITION` | Any valid screen y-coordinate or `GLFW_ANY_POSITION` +GLFW_RED_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +GLFW_GREEN_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +GLFW_BLUE_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +GLFW_ALPHA_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +GLFW_DEPTH_BITS | 24 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +GLFW_STENCIL_BITS | 8 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +GLFW_ACCUM_RED_BITS | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +GLFW_ACCUM_GREEN_BITS | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +GLFW_ACCUM_BLUE_BITS | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +GLFW_ACCUM_ALPHA_BITS | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +GLFW_AUX_BUFFERS | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +GLFW_SAMPLES | 0 | 0 to `INT_MAX` or `GLFW_DONT_CARE` +GLFW_REFRESH_RATE | `GLFW_DONT_CARE` | 0 to `INT_MAX` or `GLFW_DONT_CARE` +GLFW_STEREO | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_SRGB_CAPABLE | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_DOUBLEBUFFER | `GLFW_TRUE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_CLIENT_API | `GLFW_OPENGL_API` | `GLFW_OPENGL_API`, `GLFW_OPENGL_ES_API` or `GLFW_NO_API` +GLFW_CONTEXT_CREATION_API | `GLFW_NATIVE_CONTEXT_API` | `GLFW_NATIVE_CONTEXT_API`, `GLFW_EGL_CONTEXT_API` or `GLFW_OSMESA_CONTEXT_API` +GLFW_CONTEXT_VERSION_MAJOR | 1 | Any valid major version number of the chosen client API +GLFW_CONTEXT_VERSION_MINOR | 0 | Any valid minor version number of the chosen client API +GLFW_CONTEXT_ROBUSTNESS | `GLFW_NO_ROBUSTNESS` | `GLFW_NO_ROBUSTNESS`, `GLFW_NO_RESET_NOTIFICATION` or `GLFW_LOSE_CONTEXT_ON_RESET` +GLFW_CONTEXT_RELEASE_BEHAVIOR | `GLFW_ANY_RELEASE_BEHAVIOR` | `GLFW_ANY_RELEASE_BEHAVIOR`, `GLFW_RELEASE_BEHAVIOR_FLUSH` or `GLFW_RELEASE_BEHAVIOR_NONE` +GLFW_OPENGL_FORWARD_COMPAT | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_CONTEXT_DEBUG | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_OPENGL_PROFILE | `GLFW_OPENGL_ANY_PROFILE` | `GLFW_OPENGL_ANY_PROFILE`, `GLFW_OPENGL_COMPAT_PROFILE` or `GLFW_OPENGL_CORE_PROFILE` +GLFW_WIN32_KEYBOARD_MENU | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_WIN32_SHOWDEFAULT | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_COCOA_FRAME_NAME | `""` | A UTF-8 encoded frame autosave name +GLFW_COCOA_GRAPHICS_SWITCHING | `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` +GLFW_X11_CLASS_NAME | `""` | An ASCII encoded `WM_CLASS` class name +GLFW_X11_INSTANCE_NAME | `""` | An ASCII encoded `WM_CLASS` instance name +GLFW_WAYLAND_APP_ID | `""` | An ASCII encoded Wayland `app_id` name +GLFW_WAYLAND_USE_ZWLR | 0 | `GLFW_WAYLAND_ZWLR_LAYER_BACKGROUD`, `GLFW_WAYLAND_ZWLR_LAYER_BOTTOM`, `GLFW_WAYLAND_ZWLR_LAYER_TOP` or `GLFW_WAYLAND_ZWLR_LAYER_OVERLAY` +GLFW_WAYLAND_ZWLR_KEYBOARD_ON_FOCUS| `GLFW_FALSE` | `GLFW_TRUE` or `GLFW_FALSE` ## Window event processing {#window_events} diff --git a/examples/wayland-widget.c b/examples/wayland-widget.c index 957f38ecd..9ad6e7698 100644 --- a/examples/wayland-widget.c +++ b/examples/wayland-widget.c @@ -26,7 +26,7 @@ -#define WIN_HEIGHT 150 +static unsigned char LastCharPressed = 0; void nk_process(GLFWwindow*, struct nk_context*, float, float); @@ -38,7 +38,7 @@ static void GLFW_DebugCallback(int err_code, const char* description) } static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) - { printf("Captured %i\n", key); } + { if (action == GLFW_PRESS) LastCharPressed = key; } @@ -48,14 +48,12 @@ int main(int argc, char** argv) if (!glfwInit()) return 1; + //glfwWindowHint(GLFW_WAYLAND_ZWLR_KEYBOARD_ON_FOCUS, GLFW_TRUE); // no need to call glfwWaylandSetKeyboardFocus manually glfwWindowHint(GLFW_WAYLAND_USE_ZWLR, GLFW_WAYLAND_ZWLR_LAYER_TOP); GLFWwindow* window = glfwCreateWindow(600, 400, "Don't Care", NULL, NULL); if (!window) return 1; - //glfwWaylandZwlrSetExclusiveZone(window, WIN_HEIGHT + 50); // try to play with - //glfwWaylandZwlrSetMargin(window, 10, 10, 10, 10); - glfwMakeContextCurrent(window); glfwSetKeyCallback (window, key_callback); gladLoadGL (glfwGetProcAddress); @@ -111,9 +109,17 @@ void nk_process(GLFWwindow* window, struct nk_context* ctx, float width, float h glfwSetWindowShouldClose(window, GLFW_TRUE); } - nk_layout_row_dynamic(ctx, (height / 3), 1); - nk_layout_row_dynamic(ctx, 30, 2); + nk_layout_row_dynamic(ctx, (height / 4), 1); + nk_layout_row_dynamic(ctx, 30, 1); + { + static char inputBuff[64]; + sprintf(inputBuff, "Mouse focus: %b | Char received: %i", + glfwGetWindowAttrib(window, GLFW_FOCUSED), LastCharPressed); + nk_label(ctx, inputBuff, NK_TEXT_CENTERED); + } + + nk_layout_row_dynamic(ctx, 30, 2); { static char exclusiveBuff[12]; @@ -192,6 +198,16 @@ void nk_process(GLFWwindow* window, struct nk_context* ctx, float width, float h nk_combo_end(ctx); } } + + nk_layout_row_dynamic(ctx, 30, 2); + { + if (nk_button_label(ctx, "Request keybord focus")) + glfwWaylandZwlrSetKeyboardFocus(window, GLFW_TRUE); + + if (nk_button_label(ctx, "Release keybord focus")) + glfwWaylandZwlrSetKeyboardFocus(window, GLFW_FALSE); + } + } diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 9181882f7..bafd657e3 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -1136,15 +1136,6 @@ extern "C" { */ #define GLFW_WAYLAND_APP_ID 0x00026001 -#define GLFW_WAYLAND_ZWLR_LAYER_BACKGROUND 0x00026002 -#define GLFW_WAYLAND_ZWLR_LAYER_BOTTOM 0x00026003 -#define GLFW_WAYLAND_ZWLR_LAYER_TOP 0x00026004 -#define GLFW_WAYLAND_ZWLR_LAYER_OVERLAY 0x00026005 - -#define GLFW_WAYLAND_ZWLR_ANCHOR_TOP 0x1 -#define GLFW_WAYLAND_ZWLR_ANCHOR_BOTTOM 0x2 -#define GLFW_WAYLAND_ZWLR_ANCHOR_LEFT 0x4 -#define GLFW_WAYLAND_ZWLR_ANCHOR_RIGHT 0x8 /*! @brief Wayland specific * [window hint](@ref GLFW_WAYLAND_USE_ZWLR_hint). * @@ -1154,9 +1145,27 @@ extern "C" { * - GLFW_WAYLAND_ZWLR_TOP * - GLFW_WAYLAND_ZWLR_OVERLAY */ -#define GLFW_WAYLAND_USE_ZWLR 0x00026010 +#define GLFW_WAYLAND_USE_ZWLR 0x00026010 + +#define GLFW_WAYLAND_ZWLR_LAYER_BACKGROUND 0x00026011 +#define GLFW_WAYLAND_ZWLR_LAYER_BOTTOM 0x00026012 +#define GLFW_WAYLAND_ZWLR_LAYER_TOP 0x00026013 +#define GLFW_WAYLAND_ZWLR_LAYER_OVERLAY 0x00026014 + +#define GLFW_WAYLAND_ZWLR_ANCHOR_TOP 0x1 +#define GLFW_WAYLAND_ZWLR_ANCHOR_BOTTOM 0x2 +#define GLFW_WAYLAND_ZWLR_ANCHOR_LEFT 0x4 +#define GLFW_WAYLAND_ZWLR_ANCHOR_RIGHT 0x8 + +/*! @brief Wayland specific + * [window hint](@ref GLFW_WAYLAND_ZWLR_KEYBOARD_ON_FOCUS). + * + * By default, layer shell surfaces do not receive keyboard events. + * Set this flag to automatically redirect focus to app on hover, + * and release it when mouse leave surface. + */ +#define GLFW_WAYLAND_ZWLR_KEYBOARD_ON_FOCUS 0x00026015 -/*! @} */ #define GLFW_NO_API 0 #define GLFW_OPENGL_API 0x00030001 diff --git a/include/GLFW/glfw3native.h b/include/GLFW/glfw3native.h index 03c0c4896..85a04c808 100644 --- a/include/GLFW/glfw3native.h +++ b/include/GLFW/glfw3native.h @@ -629,6 +629,23 @@ GLFWAPI void glfwWaylandZwlrSetExclusiveZone(GLFWwindow* window, int zone); * @ingroup native */ GLFWAPI void glfwWaylandZwlrSetMargin(GLFWwindow* window, int top, int right, int bottom, int left); + +/*! @brief Request or release keyboard focus from compositor. + * + * @warning Create fallback mechanism to release focus before request one. + * Standart window events are not processed by GLFW in ZWLR mode, + * you will not be able to interact with your compositor after focus granted. + * + * @errors Possible errors include @ref GLFW_FEATURE_UNAVAILABLE and @ref + * GLFW_PLATFORM_UNAVAILABLE. + * + * @thread_safety This function should be called from main thread. + * + * @since Added in version 3.5. + * + * @ingroup native + */ +GLFWAPI void glfwWaylandZwlrSetKeyboardFocus(GLFWwindow* window, int focus); #endif #if defined(GLFW_EXPOSE_NATIVE_EGL) diff --git a/src/internal.h b/src/internal.h index 0133ee242..44dd6d9a2 100644 --- a/src/internal.h +++ b/src/internal.h @@ -428,6 +428,7 @@ struct _GLFWwndconfig struct { char appId[256]; GLFWbool useZWLR; + GLFWbool zwlrKeyboardGrabOnFocus; } wl; }; diff --git a/src/window.c b/src/window.c index 3f99b2ed9..5f63e2f2d 100644 --- a/src/window.c +++ b/src/window.c @@ -384,6 +384,9 @@ GLFWAPI void glfwWindowHint(int hint, int value) case GLFW_WAYLAND_USE_ZWLR: _glfw.hints.window.wl.useZWLR = value; return; + case GLFW_WAYLAND_ZWLR_KEYBOARD_ON_FOCUS: + _glfw.hints.window.wl.zwlrKeyboardGrabOnFocus = value ? GLFW_TRUE : GLFW_FALSE; + return; case GLFW_SCALE_TO_MONITOR: _glfw.hints.window.scaleToMonitor = value ? GLFW_TRUE : GLFW_FALSE; return; diff --git a/src/wl_window.c b/src/wl_window.c index 9924ee734..49ce93e93 100644 --- a/src/wl_window.c +++ b/src/wl_window.c @@ -1167,7 +1167,7 @@ static bool createZwlrShellObjects(_GLFWwindow* window) if (!_glfw.wl.zwlrLayerShell) { _glfwInputError(GLFW_PLATFORM_ERROR, - "Wayland: zwlr protocol not supported on this system"); + "Wayland: ZWLR protocol not supported on this system"); return GLFW_FALSE; } @@ -1618,11 +1618,14 @@ static void pointerHandleEnter(void* userData, _glfwInputCursorPos(window, window->wl.cursorPosX, window->wl.cursorPosY); } - if (window->wl.zwlr.surface) + if (_glfw.hints.window.wl.zwlrKeyboardGrabOnFocus) { - // mf don't receive keyboard events by default - zwlr_layer_surface_v1_set_keyboard_interactivity(window->wl.zwlr.surface, - ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND); + if (window->wl.zwlr.surface) + { + // mf don't receive keyboard events by default + zwlr_layer_surface_v1_set_keyboard_interactivity(window->wl.zwlr.surface, + ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_ON_DEMAND); + } } } else @@ -1653,10 +1656,13 @@ static void pointerHandleLeave(void* userData, _glfw.wl.serial = serial; _glfw.wl.pointerFocus = NULL; - if (window->wl.zwlr.surface) // TODO: find out why wl.hovered not fired + if (_glfw.hints.window.wl.zwlrKeyboardGrabOnFocus) { - zwlr_layer_surface_v1_set_keyboard_interactivity(window->wl.zwlr.surface, - ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE); + if (window->wl.zwlr.surface) // TODO: find out why wl.hovered not fired + { + zwlr_layer_surface_v1_set_keyboard_interactivity(window->wl.zwlr.surface, + ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE); + } } if (window->wl.hovered) @@ -3460,7 +3466,7 @@ GLFWAPI void glfwWaylandZwlrSetLayer(GLFWwindow* handle, int layer) if (!(window->wl.zwlr.surface)) { _glfwInputError(GLFW_FEATURE_UNAVAILABLE, - "Wayland: zwlr not supported or wasn't requested"); + "Wayland: ZWLR not supported or wasn't requested"); return; } @@ -3474,7 +3480,7 @@ GLFWAPI void glfwWaylandZwlrSetLayer(GLFWwindow* handle, int layer) default: { _glfwInputError(GLFW_INVALID_ENUM, - "Wayland: invalid zwlr layer received"); + "Wayland: invalid ZWLR layer received"); return; } } @@ -3500,7 +3506,7 @@ GLFWAPI void glfwWaylandZwlrSetAnchor(GLFWwindow* handle, int anchor) if (!(window->wl.zwlr.surface)) { _glfwInputError(GLFW_FEATURE_UNAVAILABLE, - "Wayland: zwlr not supported or wasn't requested"); + "Wayland: ZWLR not supported or wasn't requested"); return; } @@ -3522,7 +3528,7 @@ GLFWAPI void glfwWaylandZwlrSetExclusiveZone(GLFWwindow* handle, int zone) if (!(window->wl.zwlr.surface)) { _glfwInputError(GLFW_FEATURE_UNAVAILABLE, - "Wayland: zwlr not supported or wasn't requested"); + "Wayland: ZWLR not supported or wasn't requested"); return; } @@ -3544,12 +3550,39 @@ GLFWAPI void glfwWaylandZwlrSetMargin(GLFWwindow* handle, int top, int right, in if (!(window->wl.zwlr.surface)) { _glfwInputError(GLFW_FEATURE_UNAVAILABLE, - "Wayland: zwlr not supported or wasn't requested"); + "Wayland: ZWLR not supported or wasn't requested"); return; } zwlr_layer_surface_v1_set_margin(window->wl.zwlr.surface, top, right, bottom, left); } + +GLFWAPI void glfwWaylandZwlrSetKeyboardFocus(GLFWwindow* handle, int focus) +{ + _GLFW_REQUIRE_INIT(); + + if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND) + { + _glfwInputError(GLFW_PLATFORM_UNAVAILABLE, + "Wayland: Platform not initialized"); + return; + } + + _GLFWwindow* window = (_GLFWwindow*) handle; + if (!(window->wl.zwlr.surface)) + { + _glfwInputError(GLFW_FEATURE_UNAVAILABLE, + "Wayland: ZWLR not supported or wasn't requested"); + return; + } + + int flag; + if (focus) flag = ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE; + else flag = ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_NONE; + + zwlr_layer_surface_v1_set_keyboard_interactivity(window->wl.zwlr.surface, flag); +} + #endif // _GLFW_WAYLAND