From 4b1ec3956117a0ed30f5df3bd19d71fb9ba51a48 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Fri, 5 Aug 2022 13:21:29 +0800 Subject: [PATCH] Improve multi-pointer X support * etc/TODO: Document that MPX support still needs work. * src/xterm.c (xi_handle_interaction): New function. (handle_one_xevent): Call it in the appropriate places. --- etc/TODO | 13 +++++++++++++ src/xterm.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/etc/TODO b/etc/TODO index 4d0bfd1c2a0..bd846dd8988 100644 --- a/etc/TODO +++ b/etc/TODO @@ -1746,6 +1746,19 @@ for vc-rcs-update-changelog. A two-char comment-starter whose two chars are symbol constituents will not be noticed if it appears within a word. +** Multi-pointer X does not work very well +Emacs is reasonably usable under a multi-pointer X (MPX) environment, +if you turn off tooltips and mouse highlight, and don't use anything +that calls `mouse-position'. Otherwise, tooltips are shown next to +the wrong pointer, mouse highlight simply goes haywire, and +`mouse-position' returns information for the wrong pointer. + +This could be easily fixed in principle, but I cannot find a stable +enough environment under which the fix can be tested. + +The MPX code has not been tested under X toolkit or GTK+ 2.x builds +and is not expected to work there. + This file is part of GNU Emacs. diff --git a/src/xterm.c b/src/xterm.c index ebd27aea069..4bbcfb0e596 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -12616,6 +12616,36 @@ xi_handle_delete_frame (struct x_display_info *dpyinfo, } } +/* Handle an interaction by DEVICE on frame F. TIME is the time of + the interaction; if F isn't currently the global focus frame, but + is the focus of DEVICE, make it the focus frame. */ + +static void +xi_handle_interaction (struct x_display_info *dpyinfo, + struct frame *f, struct xi_device_t *device, + Time time) +{ + bool change; + + change = false; + + if (device->focus_frame == f) + { + device->focus_frame_time = time; + change = true; + } + + if (device->focus_implicit_frame == f) + { + device->focus_implicit_time = time; + change = true; + } + + /* If F isn't currently focused, update the focus state. */ + if (change && f != dpyinfo->x_focus_frame) + xi_handle_focus_change (dpyinfo); +} + #endif /* The focus may have changed. Figure out if it is a real focus change, @@ -21285,6 +21315,16 @@ handle_one_xevent (struct x_display_info *dpyinfo, } } + if (f) + { + /* If the user interacts with a frame that's focused + on another device, but not the current focus + frame, make it the focus frame. */ + if (device) + xi_handle_interaction (dpyinfo, f, device, + xev->time); + } + #ifdef USE_GTK if (!f) { @@ -21566,6 +21606,16 @@ handle_one_xevent (struct x_display_info *dpyinfo, f = x_any_window_to_frame (dpyinfo, xev->event); + if (f) + { + /* If the user interacts with a frame that's focused + on another device, but not the current focus + frame, make it the focus frame. */ + if (device) + xi_handle_interaction (dpyinfo, f, device, + xev->time); + } + XKeyPressedEvent xkey; memset (&xkey, 0, sizeof xkey); -- 2.39.2