Try to use the activation protocol to focus windows
This commit is contained in:
parent
4d30ae55f3
commit
ba8d30896b
10
glfw/wl_init.c
vendored
10
glfw/wl_init.c
vendored
@ -99,7 +99,7 @@ static void pointerHandleEnter(void* data UNUSED,
|
||||
return;
|
||||
}
|
||||
window->wl.decorations.focus = focus;
|
||||
_glfw.wl.serial = serial;
|
||||
_glfw.wl.serial = serial; _glfw.wl.input_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.serial = serial; _glfw.wl.input_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.serial = serial; _glfw.wl.input_serial = serial;
|
||||
_glfw.wl.keyboardFocusId = window->id;
|
||||
_glfwInputWindowFocus(window, true);
|
||||
uint32_t* key;
|
||||
@ -516,7 +516,7 @@ static void keyboardHandleKey(void* data UNUSED,
|
||||
return;
|
||||
int action = state == WL_KEYBOARD_KEY_STATE_PRESSED ? GLFW_PRESS : GLFW_RELEASE;
|
||||
|
||||
_glfw.wl.serial = serial;
|
||||
_glfw.wl.serial = serial; _glfw.wl.input_serial = serial;
|
||||
glfw_xkb_handle_key_event(window, &_glfw.wl.xkb, key, action);
|
||||
|
||||
if (action == GLFW_PRESS && _glfw.wl.keyboardRepeatRate > 0 && glfw_xkb_should_repeat(&_glfw.wl.xkb, key))
|
||||
@ -539,7 +539,7 @@ static void keyboardHandleModifiers(void* data UNUSED,
|
||||
uint32_t modsLocked,
|
||||
uint32_t group)
|
||||
{
|
||||
_glfw.wl.serial = serial;
|
||||
_glfw.wl.serial = serial; _glfw.wl.input_serial = serial;
|
||||
glfw_xkb_update_modifiers(&_glfw.wl.xkb, modsDepressed, modsLatched, modsLocked, 0, 0, group);
|
||||
}
|
||||
|
||||
|
||||
2
glfw/wl_platform.h
vendored
2
glfw/wl_platform.h
vendored
@ -293,7 +293,7 @@ typedef struct _GLFWlibraryWayland
|
||||
|
||||
struct wl_surface* cursorSurface;
|
||||
GLFWCursorShape cursorPreviousShape;
|
||||
uint32_t serial;
|
||||
uint32_t serial, input_serial;
|
||||
|
||||
int32_t keyboardRepeatRate;
|
||||
monotonic_t keyboardRepeatDelay;
|
||||
|
||||
26
glfw/wl_window.c
vendored
26
glfw/wl_window.c
vendored
@ -1160,12 +1160,17 @@ request_attention(GLFWwindow *window, const char *token, void *data UNUSED) {
|
||||
if (window && token && token[0]) xdg_activation_v1_activate(_glfw.wl.xdg_activation_v1, token, ((_GLFWwindow*)window)->wl.surface);
|
||||
}
|
||||
|
||||
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) {
|
||||
static bool
|
||||
has_activation_in_flight(_GLFWwindow* window, GLFWactivationcallback callback) {
|
||||
for (size_t i = 0; i < _glfw.wl.activation_requests.sz; i++) {
|
||||
glfw_wl_xdg_activation_request *r = _glfw.wl.activation_requests.array + i;
|
||||
if (r->window_id == window->id && r->callback == request_attention) return;
|
||||
if (r->window_id == window->id && r->callback == callback) return true;
|
||||
}
|
||||
get_activation_token(window, 0, request_attention, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
void _glfwPlatformRequestWindowAttention(_GLFWwindow* window) {
|
||||
if (!has_activation_in_flight(window, request_attention)) get_activation_token(window, 0, request_attention, NULL);
|
||||
}
|
||||
|
||||
int _glfwPlatformWindowBell(_GLFWwindow* window UNUSED)
|
||||
@ -1174,10 +1179,21 @@ int _glfwPlatformWindowBell(_GLFWwindow* window UNUSED)
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
focus_window(GLFWwindow *window, const char *token, void *data UNUSED) {
|
||||
if (!window) return;
|
||||
if (token && token[0]) xdg_activation_v1_activate(_glfw.wl.xdg_activation_v1, token, ((_GLFWwindow*)window)->wl.surface);
|
||||
else {
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: Window focus request via xdg-activation protocol was denied by the compositor. Use a better compositor.");
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwPlatformFocusWindow(_GLFWwindow* window UNUSED)
|
||||
{
|
||||
_glfwInputError(GLFW_FEATURE_UNAVAILABLE,
|
||||
"Wayland: The platform does not support setting the input focus");
|
||||
// Attempt to focus the window by using the activation protocol, whether it works
|
||||
// is entirely compositor dependent and as we all know Wayland and its ecosystem is
|
||||
// the product of morons.
|
||||
if (_glfw.wl.input_serial && !has_activation_in_flight(window, focus_window)) get_activation_token(window, _glfw.wl.input_serial, focus_window, NULL);
|
||||
}
|
||||
|
||||
void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user