From bf5c75465f37ad45934f58287660f18ec0bcf7bf Mon Sep 17 00:00:00 2001 From: Po Lu Date: Fri, 24 Jun 2022 10:57:35 +0800 Subject: [PATCH] Improve grabbing detection with multiple master devices (MPX) * src/frame.c (gui_mouse_grabbed): Respect any_grab_hook. * src/termhooks.h (GCALIGNED_STRUCT): New hook `any_grab_hook'. * src/xterm.c (x_have_any_grab): New function. (x_create_terminal): Define hook on XI2 builds. --- src/frame.c | 4 +++- src/termhooks.h | 7 +++++++ src/xterm.c | 22 ++++++++++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/frame.c b/src/frame.c index c2f2f8e4642..02c90ea6519 100644 --- a/src/frame.c +++ b/src/frame.c @@ -5130,7 +5130,9 @@ gui_set_no_special_glyphs (struct frame *f, Lisp_Object new_value, Lisp_Object o bool gui_mouse_grabbed (Display_Info *dpyinfo) { - return (dpyinfo->grabbed + return ((dpyinfo->grabbed + || (dpyinfo->terminal->any_grab_hook + && dpyinfo->terminal->any_grab_hook (dpyinfo))) && dpyinfo->last_mouse_frame && FRAME_LIVE_P (dpyinfo->last_mouse_frame)); } diff --git a/src/termhooks.h b/src/termhooks.h index d7190e77362..a1e3e2cde9a 100644 --- a/src/termhooks.h +++ b/src/termhooks.h @@ -877,6 +877,13 @@ struct terminal MENU_BAR_P if X and Y are in FRAME's toolkit menu bar, and true into TOOL_BAR_P if X and Y are in FRAME's toolkit tool bar. */ void (*toolkit_position_hook) (struct frame *, int, int, bool *, bool *); + +#ifdef HAVE_WINDOW_SYSTEM + /* Called to determine if the mouse is grabbed on the given display. + If either dpyinfo->grabbed or this returns true, then the display + will be considered as grabbed. */ + bool (*any_grab_hook) (Display_Info *); +#endif } GCALIGNED_STRUCT; INLINE bool diff --git a/src/xterm.c b/src/xterm.c index 6375b71666b..414a9c0ebed 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -27320,6 +27320,25 @@ x_delete_terminal (struct terminal *terminal) unblock_input (); } +#ifdef HAVE_XINPUT2 +static bool +x_have_any_grab (struct x_display_info *dpyinfo) +{ + int i; + + if (!dpyinfo->supports_xi2) + return false; + + for (i = 0; i < dpyinfo->num_devices; ++i) + { + if (dpyinfo->devices[i].grab) + return true; + } + + return false; +} +#endif + /* Create a struct terminal, initialize it with the X11 specific functions and make DISPLAY->TERMINAL point to it. */ @@ -27387,6 +27406,9 @@ x_create_terminal (struct x_display_info *dpyinfo) terminal->delete_frame_hook = x_destroy_window; terminal->delete_terminal_hook = x_delete_terminal; terminal->toolkit_position_hook = x_toolkit_position; +#ifdef HAVE_XINPUT2 + terminal->any_grab_hook = x_have_any_grab; +#endif /* Other hooks are NULL by default. */ return terminal; -- 2.39.2