-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcursor-clip-hack.patch
329 lines (300 loc) · 13 KB
/
cursor-clip-hack.patch
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
From 042b1be07452d87c80007e4ef9d58c44656754dc Mon Sep 17 00:00:00 2001
From: William Horvath <[email protected]>
Date: Wed, 6 Nov 2024 14:06:24 -0800
Subject: [PATCH] cursor clip hack
---
dlls/win32u/class.c | 3 +++
dlls/win32u/input.c | 4 ++++
dlls/win32u/win32u_private.h | 19 +++++++++++++++++++
dlls/winewayland.drv/wayland_pointer.c | 2 ++
dlls/winewayland.drv/waylanddrv.h | 16 ++++++++++++++++
dlls/winewayland.drv/window.c | 1 +
dlls/winex11.drv/event.c | 2 +-
dlls/winex11.drv/mouse.c | 2 +-
dlls/winex11.drv/opengl.c | 5 +++++
dlls/winex11.drv/window.c | 2 +-
dlls/winex11.drv/x11drv.h | 18 ++++++++++++++++++
dlls/winex11.drv/x11drv_main.c | 2 ++
12 files changed, 73 insertions(+), 3 deletions(-)
diff --git a/dlls/win32u/class.c b/dlls/win32u/class.c
index 33baed3dc23..b9e00d78cbf 100644
--- a/dlls/win32u/class.c
+++ b/dlls/win32u/class.c
@@ -85,6 +85,8 @@ static struct list class_list = LIST_INIT( class_list );
HINSTANCE user32_module = 0;
+BOOL cursor_clip_hack = FALSE;
+
/* find an existing winproc for a given function and type */
/* FIXME: probably should do something more clever than a linear search */
static WINDOWPROC *find_winproc( WNDPROC func, BOOL ansi )
@@ -248,6 +250,7 @@ DLGPROC get_dialog_proc( DLGPROC ret, BOOL ansi )
static void init_user(void)
{
+ cursor_clip_hack = use_cursor_clip_hack();
gdi_init();
sysparams_init();
winstation_init();
diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c
index d94f0da56a0..12802e99af7 100644
--- a/dlls/win32u/input.c
+++ b/dlls/win32u/input.c
@@ -2537,6 +2537,7 @@ static BOOL is_captured_by_system(void)
*/
BOOL clip_fullscreen_window( HWND hwnd, BOOL reset )
{
+ if (cursor_clip_hack) return TRUE;
struct user_thread_info *thread_info = get_user_thread_info();
MONITORINFO monitor_info = {.cbSize = sizeof(MONITORINFO)};
RECT rect, virtual_rect;
@@ -2599,6 +2600,7 @@ BOOL WINAPI NtUserGetPointerInfoList( UINT32 id, POINTER_INPUT_TYPE type, UINT_P
BOOL get_clip_cursor( RECT *rect, UINT dpi, MONITOR_DPI_TYPE type )
{
+ if (cursor_clip_hack) return TRUE;
struct object_lock lock = OBJECT_LOCK_INIT;
const desktop_shm_t *desktop_shm;
NTSTATUS status;
@@ -2614,6 +2616,7 @@ BOOL get_clip_cursor( RECT *rect, UINT dpi, MONITOR_DPI_TYPE type )
BOOL process_wine_clipcursor( HWND hwnd, UINT flags, BOOL reset )
{
+ if (cursor_clip_hack) return TRUE;
struct user_thread_info *thread_info = get_user_thread_info();
RECT rect, virtual_rect = get_virtual_screen_rect( 0, MDT_RAW_DPI );
BOOL was_clipping, empty = !!(flags & SET_CURSOR_NOCLIP);
@@ -2653,6 +2656,7 @@ BOOL process_wine_clipcursor( HWND hwnd, UINT flags, BOOL reset )
*/
BOOL WINAPI NtUserClipCursor( const RECT *rect )
{
+ if (cursor_clip_hack) rect = NULL;
RECT new_rect;
BOOL ret;
diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h
index 68117bef6c3..d480b54aafa 100644
--- a/dlls/win32u/win32u_private.h
+++ b/dlls/win32u/win32u_private.h
@@ -110,6 +110,7 @@ extern BOOL get_clip_cursor( RECT *rect, UINT dpi, MONITOR_DPI_TYPE type );
extern BOOL process_wine_clipcursor( HWND hwnd, UINT flags, BOOL reset );
extern BOOL clip_fullscreen_window( HWND hwnd, BOOL reset );
extern USHORT map_scan_to_kbd_vkey( USHORT scan, HKL layout );
+extern BOOL cursor_clip_hack;
/* menu.c */
extern HMENU create_menu( BOOL is_popup );
@@ -417,4 +418,22 @@ static inline BOOL intersect_rect( RECT *dst, const RECT *src1, const RECT *src2
return !IsRectEmpty( dst );
}
+static inline int use_cursor_clip_hack(void)
+{
+ static int enable_cached = -1;
+ if (enable_cached == -1)
+ {
+ const char *e = getenv("WINE_ENABLE_ABS_TABLET_HACK");
+ if (!getenv("WAYLAND_DISPLAY"))
+ enable_cached = 0;
+ else if (e && (atoi(e) > 1))
+ enable_cached = 2;
+ else if (e && (atoi(e) > 0))
+ enable_cached = 1;
+ else
+ enable_cached = 0;
+ }
+ return enable_cached;
+}
+
#endif /* __WINE_WIN32U_PRIVATE */
diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c
index c20ba170285..6c778f5566a 100644
--- a/dlls/winewayland.drv/wayland_pointer.c
+++ b/dlls/winewayland.drv/wayland_pointer.c
@@ -626,6 +626,7 @@ clear_cursor:
static void reapply_cursor_clipping(void)
{
+ if (use_cursor_clip_hack()) return;
RECT rect;
UINT context = NtUserSetThreadDpiAwarenessContext(NTUSER_DPI_PER_MONITOR_AWARE);
if (NtUserGetClipCursor(&rect)) NtUserClipCursor(&rect);
@@ -1096,6 +1095,7 @@ BOOL WAYLAND_SetCursorPos(INT x, INT y)
*/
BOOL WAYLAND_ClipCursor(const RECT *clip, BOOL reset)
{
+ if (use_cursor_clip_hack()) return TRUE;
struct wayland_pointer *pointer = &process_wayland.pointer;
HWND hwnd;
struct wl_surface *wl_surface = NULL;
diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h
index 7da73d6bba0..0d9472022e6 100644
--- a/dlls/winewayland.drv/waylanddrv.h
+++ b/dlls/winewayland.drv/waylanddrv.h
@@ -41,6 +41,7 @@
#include "wine/gdi_driver.h"
#include "wine/list.h"
#include "wine/rbtree.h"
+#include "stdlib.h"
#include "unixlib.h"
@@ -387,4 +388,19 @@ BOOL WAYLAND_CreateWindowSurface(HWND hwnd, BOOL layered, const RECT *surface_re
UINT WAYLAND_VulkanInit(UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs);
struct opengl_funcs *WAYLAND_wine_get_wgl_driver(UINT version);
+static inline int use_cursor_clip_hack(void)
+{
+ static int enable_cached = -1;
+ if (enable_cached == -1)
+ {
+ const char *e = getenv("WINE_ENABLE_ABS_TABLET_HACK");
+ if (e && (atoi(e) > 1))
+ enable_cached = 2;
+ else if (e && (atoi(e) > 0))
+ enable_cached = 1;
+ else
+ enable_cached = 0;
+ }
+ return enable_cached;
+}
#endif /* __WINE_WAYLANDDRV_H */
diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c
index 604d8e09d0e..14ca7921622 100644
--- a/dlls/winewayland.drv/window.c
+++ b/dlls/winewayland.drv/window.c
@@ -181,6 +181,7 @@ static void wayland_win_data_get_config(struct wayland_win_data *data,
static void reapply_cursor_clipping(void)
{
+ if (use_cursor_clip_hack()) return;
RECT rect;
UINT context = NtUserSetThreadDpiAwarenessContext(NTUSER_DPI_PER_MONITOR_AWARE);
if (NtUserGetClipCursor(&rect )) NtUserClipCursor(&rect);
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index d453a1e34bc..7d97f2c57c8 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -341,7 +341,7 @@ static void wait_grab_pointer( Display *display )
NtUserGetClipCursor( &rect );
NtUserClipCursor( NULL );
- while (XGrabPointer( display, root_window, False, 0, GrabModeAsync, GrabModeAsync,
+ while (cursor_clip_hack < 2 && XGrabPointer( display, root_window, False, 0, GrabModeAsync, GrabModeAsync,
None, None, CurrentTime ) != GrabSuccess)
{
LARGE_INTEGER timeout = {.QuadPart = -10 * (ULONGLONG)10000};
diff --git a/dlls/winex11.drv/mouse.c b/dlls/winex11.drv/mouse.c
index 3ce093a0c38..7ecca5e4f2f 100644
--- a/dlls/winex11.drv/mouse.c
+++ b/dlls/winex11.drv/mouse.c
@@ -524,7 +524,7 @@ static BOOL grab_clipping_window( const RECT *clip )
clip->right < clip_rect.right || clip->bottom < clip_rect.bottom)
data->warp_serial = NextRequest( data->display );
- if (!XGrabPointer( data->display, clip_window, False,
+ if (cursor_clip_hack < 2 && !XGrabPointer( data->display, clip_window, False,
PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, clip_window, None, CurrentTime ))
clipping_cursor = TRUE;
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c
index 5c5bb8f0602..f63a41c7f41 100644
--- a/dlls/winex11.drv/opengl.c
+++ b/dlls/winex11.drv/opengl.c
@@ -1111,6 +1111,11 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct glx_pixel
if (!(gl = calloc( 1, sizeof(*gl) ))) return NULL;
+ /* lazy to find somewhere else to put this so that it doesn't show up more than once */
+ static unsigned int once;
+ if (!once++ && cursor_clip_hack)
+ MESSAGE("XWayland absolute tablet hack enabled, which disables mouse confinement, and may cause cursor glitching\n\texport WINE_ENABLE_ABS_TABLET_HACK=0 to disable.\n");
+
/* Default GLX and WGL swap interval is 1, but in case of glXSwapIntervalSGI
* there is no way to query it, so we have to store it here.
*/
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index f7c012f7a0d..f3ca4486816 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -2813,7 +2813,7 @@ void X11DRV_SetCapture( HWND hwnd, UINT flags )
if (!(flags & (GUI_INMOVESIZE | GUI_INMENUMODE))) return;
- if (hwnd)
+ if (cursor_clip_hack < 2 && hwnd)
{
if (!(data = get_win_data( NtUserGetAncestor( hwnd, GA_ROOT )))) return;
if (data->whole_window)
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 637afaa5e3b..1124634f516 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -1003,5 +1003,23 @@ static inline UINT asciiz_to_unicode( WCHAR *dst, const char *src )
while ((*p++ = *src++));
return (p - dst) * sizeof(WCHAR);
}
+extern int cursor_clip_hack;
+static inline int use_cursor_clip_hack(void)
+{
+ static int enable_cached = -1;
+ if (enable_cached == -1)
+ {
+ const char *e = getenv("WINE_ENABLE_ABS_TABLET_HACK");
+ if (!getenv("WAYLAND_DISPLAY"))
+ enable_cached = 0;
+ else if (e && (atoi(e) > 1))
+ enable_cached = 2;
+ else if (e && (atoi(e) > 0))
+ enable_cached = 1;
+ else
+ enable_cached = 0;
+ }
+ return enable_cached;
+}
#endif /* __WINE_X11DRV_H */
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index 29147758979..9874f18a4b6 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -85,6 +85,7 @@ int primary_monitor = 0;
BOOL client_side_graphics = TRUE;
BOOL client_side_with_render = TRUE;
BOOL shape_layered_windows = TRUE;
+int cursor_clip_hack = 0;
int copy_default_colors = 128;
int alloc_system_colors = 256;
int xrender_error_base = 0;
@@ -831,6 +832,7 @@ static NTSTATUS x11drv_init( void *arg )
X11DRV_InitMouse( gdi_display );
if (use_xim) use_xim = xim_init( input_style );
+ cursor_clip_hack = use_cursor_clip_hack();
init_user_driver();
return STATUS_SUCCESS;
}
--
2.47.0
From ab3b93764847712da1928be9ecda339d407ce26c Mon Sep 17 00:00:00 2001
From: William Horvath <[email protected]>
Date: Wed, 13 Nov 2024 03:05:16 -0800
Subject: [PATCH] cursor-clip-hack additions
---
dlls/win32u/message.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c
index d398579916b..92951ce3c4a 100644
--- a/dlls/win32u/message.c
+++ b/dlls/win32u/message.c
@@ -2116,8 +2116,8 @@ static LRESULT handle_internal_message( HWND hwnd, UINT msg, WPARAM wparam, LPAR
case WM_WINE_CLIPCURSOR:
/* non-hardware message, posted on display mode change to trigger fullscreen
clipping or to the desktop window to forcefully release the cursor grabs */
- if (wparam & SET_CURSOR_FSCLIP) return clip_fullscreen_window( hwnd, FALSE );
- return process_wine_clipcursor( hwnd, wparam, lparam );
+ if (wparam & SET_CURSOR_FSCLIP) return cursor_clip_hack ? TRUE : clip_fullscreen_window( hwnd, FALSE );
+ return cursor_clip_hack ? TRUE : process_wine_clipcursor( hwnd, wparam, lparam );
case WM_WINE_SETCURSOR:
FIXME( "Unexpected non-hardware WM_WINE_SETCURSOR message\n" );
return FALSE;
@@ -2661,7 +2661,9 @@ static BOOL process_hardware_message( MSG *msg, UINT hw_id, const struct hardwar
else if (msg->message >= WM_POINTERUPDATE && msg->message <= WM_POINTERLEAVE)
ret = process_pointer_message( msg, hw_id, msg_data );
else if (msg->message == WM_WINE_CLIPCURSOR)
- process_wine_clipcursor( msg->hwnd, msg->wParam, msg->lParam );
+ {
+ if (!cursor_clip_hack) process_wine_clipcursor( msg->hwnd, msg->wParam, msg->lParam );
+ }
else if (msg->message == WM_WINE_SETCURSOR)
process_wine_setcursor( msg->hwnd, (HWND)msg->wParam, (HCURSOR)msg->lParam );
else
@@ -3580,7 +3582,7 @@ NTSTATUS send_hardware_message( HWND hwnd, UINT flags, const INPUT *input, LPARA
info.timeout = 0;
info.params = NULL;
- if (input->type == INPUT_MOUSE && (input->mi.dwFlags & (MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_RIGHTDOWN)))
+ if (!cursor_clip_hack && input->type == INPUT_MOUSE && (input->mi.dwFlags & (MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_RIGHTDOWN)))
clip_fullscreen_window( hwnd, FALSE );
SERVER_START_REQ( send_hardware_message )
--
2.47.0