1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
From 2bcc4749b1ab6819d6dfdb07cd1832ab5d3339bd Mon Sep 17 00:00:00 2001
From: Friz64 <friz64@protonmail.com>
Date: Sun, 25 Feb 2024 00:51:49 +0100
Subject: [PATCH 1/3] Wayland: Partially implement `glfwSetCursorPos`
---
src/wl_platform.h | 2 ++
src/wl_window.c | 37 +++++++++++++++++++++++++++++++++++--
2 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/src/wl_platform.h b/src/wl_platform.h
index 149cd241..53b09eef 100644
--- a/src/wl_platform.h
+++ b/src/wl_platform.h
@@ -371,6 +371,7 @@ typedef struct _GLFWwindowWayland
GLFWbool iconified;
GLFWbool activated;
GLFWbool fullscreen;
+ double cursorPosX, cursorPosY;
} pending;
struct {
@@ -386,6 +387,7 @@ typedef struct _GLFWwindowWayland
_GLFWcursor* currentCursor;
double cursorPosX, cursorPosY;
+ GLFWbool pendingCursorPos;
char* appId;
diff --git a/src/wl_window.c b/src/wl_window.c
index 5b491ffb..4283f88f 100644
--- a/src/wl_window.c
+++ b/src/wl_window.c
@@ -2667,8 +2667,34 @@ void _glfwGetCursorPosWayland(_GLFWwindow* window, double* xpos, double* ypos)
void _glfwSetCursorPosWayland(_GLFWwindow* window, double x, double y)
{
- _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
- "Wayland: The platform does not support setting the cursor position");
+ if (!_glfw.wl.pointerConstraints)
+ {
+ _glfwInputError(GLFW_FEATURE_UNAVAILABLE,
+ "Wayland: The compositor does not support setting the cursor position");
+ return;
+ }
+
+ if (window->wl.lockedPointer) {
+ zwp_locked_pointer_v1_set_cursor_position_hint(window->wl.lockedPointer,
+ wl_fixed_from_double(x),
+ wl_fixed_from_double(y));
+ } else {
+ if (window->cursorMode != GLFW_CURSOR_DISABLED) {
+ _glfwInputError(GLFW_PLATFORM_ERROR,
+ "Wayland: Delaying the cursor position update until "
+ "the cursor mode is set to GLFW_CURSOR_DISABLED");
+ }
+
+ // The cursor is not currently locked, but it may be locked later. Either
+ // - the application has already set the cursor mode to GLFW_CURSOR_DISABLED,
+ // but the cursor is currently outside of the window, or
+ // - the application has not yet set the cursor mode to GLFW_CURSOR_DISABLED,
+ // but will do so soon.
+ // Defer setting the cursor position to _glfwSetCursorWayland.
+ window->wl.pending.cursorPosX = x;
+ window->wl.pending.cursorPosY = y;
+ window->wl.pendingCursorPos = GLFW_TRUE;
+ }
}
void _glfwSetCursorModeWayland(_GLFWwindow* window, int mode)
@@ -3009,6 +3035,13 @@ void _glfwSetCursorWayland(_GLFWwindow* window, _GLFWcursor* cursor)
unconfinePointer(window);
if (!window->wl.lockedPointer)
lockPointer(window);
+
+ if (window->wl.pendingCursorPos == GLFW_TRUE) {
+ zwp_locked_pointer_v1_set_cursor_position_hint(window->wl.lockedPointer,
+ wl_fixed_from_double(window->wl.pending.cursorPosX),
+ wl_fixed_from_double(window->wl.pending.cursorPosY));
+ window->wl.pendingCursorPos = GLFW_FALSE;
+ }
}
else if (window->cursorMode == GLFW_CURSOR_CAPTURED)
{
--
2.52.0
|