commit 34686263b7459f78fd1e6d68dc1aa9c8644876b3 (HEAD, refs/remotes/origin/master) Author: Po Lu Date: Thu Aug 25 12:24:34 2022 +0800 Fix various problems with mouse highlight on XI2 builds * src/dispextern.h (reset_mouse_highlight): Fix coding style. * src/xterm.c (xi_position_changed): New functions. (xi_report_motion_window_clear, handle_one_xevent): Don't report motion events if the pixel position did not actually change. * src/xterm.h (struct xi_device_t): New fields `last_motion_window', `last_motion_x' and `last_motion_y'. diff --git a/src/dispextern.h b/src/dispextern.h index 12ba927261..2f5f4335fe 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -2874,18 +2874,17 @@ typedef struct { INLINE void reset_mouse_highlight (Mouse_HLInfo *hlinfo) { - - hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; - hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; - hlinfo->mouse_face_mouse_x = hlinfo->mouse_face_mouse_y = 0; - hlinfo->mouse_face_beg_x = hlinfo->mouse_face_end_x = 0; - hlinfo->mouse_face_face_id = DEFAULT_FACE_ID; - hlinfo->mouse_face_mouse_frame = NULL; - hlinfo->mouse_face_window = Qnil; - hlinfo->mouse_face_overlay = Qnil; - hlinfo->mouse_face_past_end = false; - hlinfo->mouse_face_hidden = false; - hlinfo->mouse_face_defer = false; + hlinfo->mouse_face_beg_row = hlinfo->mouse_face_beg_col = -1; + hlinfo->mouse_face_end_row = hlinfo->mouse_face_end_col = -1; + hlinfo->mouse_face_mouse_x = hlinfo->mouse_face_mouse_y = 0; + hlinfo->mouse_face_beg_x = hlinfo->mouse_face_end_x = 0; + hlinfo->mouse_face_face_id = DEFAULT_FACE_ID; + hlinfo->mouse_face_mouse_frame = NULL; + hlinfo->mouse_face_window = Qnil; + hlinfo->mouse_face_overlay = Qnil; + hlinfo->mouse_face_past_end = false; + hlinfo->mouse_face_hidden = false; + hlinfo->mouse_face_defer = false; } /*********************************************************************** diff --git a/src/xterm.c b/src/xterm.c index 0684402b14..fb4c0c74db 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -12809,6 +12809,43 @@ xi_handle_interaction (struct x_display_info *dpyinfo, xi_handle_focus_change (dpyinfo); } +/* Return whether or not XEV actually represents a change in the + position of the pointer on DEVICE, with respect to the last event + received. This is necessary because the input extension reports + motion events in very high resolution, while Emacs is only fast + enough to process motion events aligned to the pixel grid. */ + +static bool +xi_position_changed (struct xi_device_t *device, XIDeviceEvent *xev) +{ + bool changed; + + changed = true; + + if (xev->event != device->last_motion_window) + goto out; + + if (lrint (xev->event_x) == device->last_motion_x + && lrint (xev->event_y) == device->last_motion_y) + { + changed = false; + goto out; + } + + out: + device->last_motion_x = lrint (xev->event_x); + device->last_motion_y = lrint (xev->event_y); + device->last_motion_window = xev->event; + + return changed; +} + +static void +xi_report_motion_window_clear (struct xi_device_t *device) +{ + device->last_motion_window = None; +} + #ifdef HAVE_XINPUT2_1 /* Look up a scroll valuator in DEVICE by NUMBER. */ @@ -20060,6 +20097,28 @@ handle_one_xevent (struct x_display_info *dpyinfo, } #endif +#ifdef HAVE_XINPUT2 + if (f && dpyinfo->supports_xi2) + { + Mouse_HLInfo *hlinfo; + + /* The input extension doesn't report motion events when + the part of the window below the pointer changes. To + avoid outdated information from keeping + i.e. mouse-highlight at the wrong position after the + frame is moved or resized, reset the mouse highlight + and last_mouse_motion_frame. */ + + if (dpyinfo->last_mouse_motion_frame == f) + dpyinfo->last_mouse_motion_frame = NULL; + + hlinfo = MOUSE_HL_INFO (f); + + if (hlinfo->mouse_face_mouse_frame == f) + reset_mouse_highlight (hlinfo); + } +#endif + } if (x_dnd_in_progress @@ -20713,7 +20772,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, case XI_Leave: { - XILeaveEvent *leave = (XILeaveEvent *) xi_event; + XILeaveEvent *leave; + struct xi_device_t *device; + + leave = (XILeaveEvent *) xi_event; #ifdef USE_GTK struct xi_device_t *source; XMotionEvent ev; @@ -20730,6 +20792,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, #ifdef USE_GTK source = xi_device_from_id (dpyinfo, leave->sourceid); #endif + device = xi_device_from_id (dpyinfo, leave->deviceid); + + if (device) + xi_report_motion_window_clear (device); /* This allows us to catch LeaveNotify events generated by popup menu grabs. FIXME: this is right when there is a @@ -21149,6 +21215,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, #endif #endif /* HAVE_XINPUT2_1 */ + if (!xi_position_changed (device, xev)) + goto XI_OTHER; + ev.x = lrint (xev->event_x); ev.y = lrint (xev->event_y); ev.window = xev->event; diff --git a/src/xterm.h b/src/xterm.h index 8500ec2771..9d9675428f 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -286,6 +286,12 @@ struct xi_device_t /* The frame that is currently this device's implicit keyboard focus, or NULL. */ struct frame *focus_implicit_frame; + + /* The window on which the last motion event happened. */ + Window last_motion_window; + + /* The rounded integer coordinates of the last motion event. */ + int last_motion_x, last_motion_y; }; #endif commit bc8141594d67fcb95dc58e031d811aee0dbf96e0 Author: Dmitry Gutov Date: Thu Aug 25 01:15:24 2022 +0300 vc-merge: Look for 'merge-file' instead of 'merge' * lisp/vc/vc.el (vc-merge): Look for 'merge-file' in second clause (bug#50258). diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index b05adfb2d5..85a96a29fa 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -2294,7 +2294,7 @@ changes from the current branch." ((vc-find-backend-function backend 'merge-branch) (vc-call-backend backend 'merge-branch)) ;; Otherwise, do a per-file merge. - ((vc-find-backend-function backend 'merge) + ((vc-find-backend-function backend 'merge-file) (vc-buffer-sync) (dolist (file files) (let* ((state (vc-state file)) commit 78923c5f4e26d3cb9fbaf0dbf2d04c523482e52c Author: Alan Mackenzie Date: Wed Aug 24 19:27:32 2022 +0000 C++ Mode - Fontify "class Foo {\n ~Foo() noexcept;" correctly This fixes bug #49787. * lisp/progmodes/cc-engine.el (c-forward-decl-or-cast-1): (In `if' form just before CASE 8) Remove the (not ...) around the (looking-at c-after-suffixed-type-maybe-decl-key). * lisp/progmodes/cc-fonts.el (c-font-lock-complex-decl-prepare): Add `c-not-decl' to the values of c-type which are erased at the start of a fontification. diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index f46c909fea..1139423a45 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -10571,8 +10571,8 @@ This function might do hidden buffer changes." backup-maybe-typeless (when c-recognize-typeless-decls (or (not got-suffix) - (not (looking-at - c-after-suffixed-type-maybe-decl-key)))))) + (looking-at + c-after-suffixed-type-maybe-decl-key))))) ;; Got an empty paren pair and a preceding type that probably ;; really is the identifier. Shift the type backwards to make ;; the last one the identifier. This is analogous to the diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el index 2495d21a10..12bb3d3751 100644 --- a/lisp/progmodes/cc-fonts.el +++ b/lisp/progmodes/cc-fonts.el @@ -940,7 +940,8 @@ casts and declarations are fontified. Used on level 2 and higher." '(c-decl-arg-start c-decl-end c-decl-id-start - c-decl-type-start))) + c-decl-type-start + c-not-decl))) (1- (point)) pos) limit 'c-type))) commit 95b1eacd4750da7329380aabcb383a8f9d96a59b Author: Eli Zaretskii Date: Wed Aug 24 19:19:33 2022 +0300 Fix handling of UNCs in 'parse-colon-path * lisp/files.el (parse-colon-path): Don't remove the second leading slash on systems that support UNCs. (Bug#57353) * test/lisp/files-tests.el (files-tests-bug-21454): Update expected results. (files-colon-path): Add a new test pattern. diff --git a/lisp/files.el b/lisp/files.el index 8596d9a839..740e09055b 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -851,15 +851,20 @@ resulting list of directory names. For an empty path element (i.e., a leading or trailing separator, or two adjacent separators), return nil (meaning `default-directory') as the associated list element." (when (stringp search-path) - (let ((spath (substitute-env-vars search-path))) + (let ((spath (substitute-env-vars search-path)) + (double-slash-special-p + (memq system-type '(windows-nt cygwin ms-dos)))) (mapcar (lambda (f) (if (equal "" f) nil (let ((dir (file-name-as-directory f))) ;; Previous implementation used `substitute-in-file-name' - ;; which collapse multiple "/" in front. Do the same for - ;; backward compatibility. - (if (string-match "\\`/+" dir) - (substring dir (1- (match-end 0))) dir)))) + ;; which collapses multiple "/" in front, while + ;; preserving double slash where it matters. Do + ;; the same for backward compatibility. + (if (string-match "\\`//+" dir) + (substring dir (- (match-end 0) + (if double-slash-special-p 2 1))) + dir)))) (split-string spath path-separator))))) (defun cd-absolute (dir) diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el index 54ada08800..20c712226e 100644 --- a/test/lisp/files-tests.el +++ b/test/lisp/files-tests.el @@ -221,8 +221,8 @@ form.") ("x:/foo//bar/" "y:/bar/qux/" "z:/qux/foo/")) ("x:/foo/bar" "$FOO/baz/;z:/qux/foo/" ("x:/foo/bar/baz/" "z:/qux/foo/")) - ("//foo/bar/" "$FOO/baz/;/qux/foo/" - ("/foo/bar//baz/" "/qux/foo/"))) + ("///foo/bar/" "$FOO/baz/;/qux/foo/" + ("//foo/bar//baz/" "/qux/foo/"))) '(("/foo/bar//baz/:/bar/foo/baz//" nil ("/foo/bar//baz/" "/bar/foo/baz//")) ("/foo/bar/:/bar/qux/:/qux/foo" nil @@ -1504,7 +1504,11 @@ See ." (should (equal (parse-colon-path "/foo//bar/baz") '("/foo//bar/baz/")))) (should (equal (parse-colon-path (concat "." path-separator "/tmp")) - '("./" "/tmp/")))) + '("./" "/tmp/"))) + (should (equal (parse-colon-path (concat "/foo" path-separator "///bar")) + (if (memq system-type '(windows-nt cygwin ms-dos)) + '("/foo/" "//bar/") + '("/foo/" "/bar/"))))) (ert-deftest files-test-magic-mode-alist-doctype () "Test that DOCTYPE and variants put files in mhtml-mode." commit 3835255a38dc8c2a37c063fdcb7f3486094893e9 Author: Alan Mackenzie Date: Wed Aug 24 14:42:11 2022 +0000 CC Mode: Fontify args correctly when arglist closing ) is not on the same line This fixes bug #56841. * lisp/progmodes/cc-engine.el (c-forward-declarator): Fix an off-by-one comparing the position after a c-forward-name with a limit. * lisp/progmodes/cc-mode.el (c-fl-decl-end): Handle correctly point starting inside a literal. Insert a missing c-backward-syntactic-ws in the handling of C++ attributes. Correctly handle an unmatched (. Better handle point starting inside a [ or (. Tidy up the handling of syntactic whitespace at the end of the buffer. diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index bc6155dd66..f46c909fea 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -9557,7 +9557,7 @@ point unchanged and return nil." (or (= paren-depth 0) (c-safe (goto-char (scan-lists (point) 1 paren-depth)))) - (<= (point) limit) + (< (point) limit) ;; Skip over any trailing bit, such as "__attribute__". (progn diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index 027fd8f42f..9327dbf775 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el @@ -2440,49 +2440,59 @@ with // and /*, not more generic line and block comments." (and (/= new-pos pos) new-pos)))) (defun c-fl-decl-end (pos) - ;; If POS is inside a declarator, return the end of the token that follows - ;; the declarator, otherwise return nil. POS being in a literal does not - ;; count as being in a declarator (on pragmatic grounds). POINT is not - ;; preserved. + ;; If POS is inside a declarator, return the position of the end of the + ;; paren pair that terminates it, or of the end of the token that follows + ;; the declarator, otherwise return nil. If there is no such token, the end + ;; of the last token in the buffer is used. POS being in a literal is now + ;; (2022-07) handled correctly. POINT is not preserved. (goto-char pos) (let ((lit-start (c-literal-start)) (lim (c-determine-limit 1000)) enclosing-attribute pos1) - (unless lit-start - (c-backward-syntactic-ws - lim) - (when (setq enclosing-attribute (c-enclosing-c++-attribute)) - (goto-char (car enclosing-attribute))) ; Only happens in C++ Mode. - (when (setq pos1 (c-on-identifier)) - (goto-char pos1) - (let ((lim (save-excursion - (and (c-beginning-of-macro) - (progn (c-end-of-macro) (point)))))) - (and (c-forward-declarator lim) - (if (eq (char-after) ?\() - (and - (c-go-list-forward nil lim) - (progn (c-forward-syntactic-ws lim) - (not (eobp))) - (progn - (if (looking-at c-symbol-char-key) - ;; Deal with baz (foo((bar)) type var), where - ;; foo((bar)) is not semantically valid. The result - ;; must be after var). - (and - (goto-char pos) - (setq pos1 (c-on-identifier)) - (goto-char pos1) - (progn - (c-backward-syntactic-ws lim) - (eq (char-before) ?\()) - (c-fl-decl-end (1- (point)))) - (c-backward-syntactic-ws lim) - (point)))) - (and (progn (c-forward-syntactic-ws lim) - (not (eobp))) + (if lit-start + (goto-char lit-start)) + (c-backward-syntactic-ws lim) + (when (setq enclosing-attribute (c-enclosing-c++-attribute)) + (goto-char (car enclosing-attribute)) ; Only happens in C++ Mode. + (c-backward-syntactic-ws lim)) + (while (and (> (point) lim) + (memq (char-before) '(?\[ ?\())) + (backward-char) + (c-backward-syntactic-ws lim)) + (when (setq pos1 (c-on-identifier)) + (goto-char pos1) + (let ((lim (save-excursion + (and (c-beginning-of-macro) + (progn (c-end-of-macro) (point)))))) + (and (c-forward-declarator lim) + (if (and (eq (char-after) ?\() + (c-go-list-forward nil lim)) + (and + (progn (c-forward-syntactic-ws lim) + (not (eobp))) + (progn + (if (looking-at c-symbol-char-key) + ;; Deal with baz (foo((bar)) type var), where + ;; foo((bar)) is not semantically valid. The result + ;; must be after var). + (and + (goto-char pos) + (setq pos1 (c-on-identifier)) + (goto-char pos1) + (progn + (c-backward-syntactic-ws lim) + (eq (char-before) ?\()) + (c-fl-decl-end (1- (point)))) (c-backward-syntactic-ws lim) - (point))))))))) + (point)))) + (if (progn (c-forward-syntactic-ws lim) + (not (eobp))) + (c-forward-over-token) + (let ((lit-start (c-literal-start))) + (when lit-start + (goto-char lit-start)) + (c-backward-syntactic-ws))) + (and (>= (point) pos) (point)))))))) (defun c-change-expand-fl-region (_beg _end _old-len) ;; Expand the region (c-new-BEG c-new-END) to an after-change font-lock commit 044e11641bc0bfaf0d735bd57f04333f9616cfc7 Author: Santiago Calandrino Date: Wed Aug 24 13:54:28 2022 +0200 Fix string padding in gdb-mi * lisp/progmodes/gdb-mi.el (gdb-table): Fix string padding in gdb-mi (bug#57362). (gdb-pad-string): Unobsolete. (gdb-table-string): Re-fix string padding. Copyright-paperwork-exempt: yes diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el index c256198b3c..bab80719db 100644 --- a/lisp/progmodes/gdb-mi.el +++ b/lisp/progmodes/gdb-mi.el @@ -2943,8 +2943,7 @@ Return position where LINE begins." start-posn))) (defun gdb-pad-string (string padding) - (declare (obsolete string-pad "29.1")) - (string-pad string padding nil t)) + (string-pad string (abs padding) nil (natnump padding))) ;; gdb-table struct is a way to programmatically construct simple ;; tables. It help to reliably align columns of data in GDB buffers @@ -2962,8 +2961,7 @@ When non-nil, PROPERTIES will be added to the whole row when calling `gdb-table-string'." (let ((rows (gdb-table-rows table)) (row-properties (gdb-table-row-properties table)) - (column-sizes (gdb-table-column-sizes table)) - (right-align (gdb-table-right-align table))) + (column-sizes (gdb-table-column-sizes table))) (when (not column-sizes) (setf (gdb-table-column-sizes table) (make-list (length row) 0))) @@ -2973,9 +2971,7 @@ calling `gdb-table-string'." (append row-properties (list properties))) (setf (gdb-table-column-sizes table) (cl-mapcar (lambda (x s) - (let ((new-x - (max (abs x) (string-width (or s ""))))) - (if right-align new-x (- new-x)))) + (max (abs x) (string-width (or s "")))) (gdb-table-column-sizes table) row)) ;; Avoid trailing whitespace at eol @@ -2991,7 +2987,10 @@ calling `gdb-table-string'." (lambda (row properties) (apply #'propertize (mapconcat #'identity - (cl-mapcar (lambda (s x) (string-pad s x nil t)) + (cl-mapcar (lambda (s x) + (string-pad + s x nil + (not (gdb-table-right-align table)))) row column-sizes) sep) properties)) commit b400d7335b0d859b3823bcabc15e3a401fe7e2d0 Author: Eli Zaretskii Date: Wed Aug 24 14:45:07 2022 +0300 ; * lisp/simple.el (read-only-mode): Fix wording of doc string. diff --git a/lisp/simple.el b/lisp/simple.el index 13d0d3b241..ee765c8a57 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -10402,7 +10402,7 @@ ignore read-only status in a Lisp program (whether due to text properties or buffer state), bind `inhibit-read-only' temporarily to a non-nil value. -Reverting a buffer will keep the readedness state set by using +Reverting a buffer will keep the read-only status set by using this command." :variable buffer-read-only ;; We're saving this value here so that we can restore the commit 25ee1ff2065d7421295e3ff6912538c84084c32c Author: Lars Ingebrigtsen Date: Wed Aug 24 13:39:08 2022 +0200 Don't lose read-only marking when reverting a view-mode buffer * lisp/view.el (view--enable): Don't lose read-only-ness when reverting (bug#35166). diff --git a/lisp/view.el b/lisp/view.el index 287112f2d4..1207f01db2 100644 --- a/lisp/view.el +++ b/lisp/view.el @@ -441,7 +441,9 @@ Entry to view-mode runs the normal hook `view-mode-hook'." (setq view-page-size nil view-half-page-size nil view-old-buffer-read-only buffer-read-only - buffer-read-only t)) + buffer-read-only t) + ;; Make reverting the buffer preserve unreadableness. + (setq-local read-only-mode--state t)) (define-obsolete-function-alias 'view-mode-enable 'view-mode "24.4") commit fd74c6f4b81ffb6b373993ef2a5d80f888842397 Author: Lars Ingebrigtsen Date: Wed Aug 24 13:33:02 2022 +0200 When reverting, preserve the readedness state set by `C-x C-q' * lisp/files.el (revert-buffer): Save the user's intention in a variable (bug#50431). * lisp/simple.el (read-only-mode): Use it. diff --git a/lisp/files.el b/lisp/files.el index cf2a522193..8596d9a839 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -6627,9 +6627,14 @@ preserve markers and overlays, at the price of being slower." ;; interface, but leaving the programmatic interface the same. (interactive (list (not current-prefix-arg))) (let ((revert-buffer-in-progress-p t) - (revert-buffer-preserve-modes preserve-modes)) + (revert-buffer-preserve-modes preserve-modes) + (state (and (boundp 'read-only-mode--state) + (list read-only-mode--state)))) (funcall (or revert-buffer-function #'revert-buffer--default) - ignore-auto noconfirm))) + ignore-auto noconfirm) + (when state + (setq buffer-read-only (car state)) + (setq-local read-only-mode--state (car state))))) (defun revert-buffer--default (ignore-auto noconfirm) "Default function for `revert-buffer'. diff --git a/lisp/simple.el b/lisp/simple.el index 460aff8bd8..13d0d3b241 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -10400,8 +10400,15 @@ command works by setting the variable `buffer-read-only', which does not affect read-only regions caused by text properties. To ignore read-only status in a Lisp program (whether due to text properties or buffer state), bind `inhibit-read-only' temporarily -to a non-nil value." +to a non-nil value. + +Reverting a buffer will keep the readedness state set by using +this command." :variable buffer-read-only + ;; We're saving this value here so that we can restore the + ;; readedness state after reverting the buffer to the value that's + ;; been explicitly set by the user. + (setq-local read-only-mode--state buffer-read-only) (cond ((and (not buffer-read-only) view-mode) (View-exit-and-edit) commit e518146a3017669981b6d31c356d0bb105200928 Author: Po Lu Date: Wed Aug 24 19:10:44 2022 +0800 Fix input extension focus tracking with some window managers * src/xterm.c (handle_one_xevent): If a window manager sends us FocusIn and FocusOut with XSendEvent (they do that), don't detect focus changes when XInput 2 is enabled. The X server will tell us the actual truth if the focus really did change. diff --git a/src/xterm.c b/src/xterm.c index 3dfa908f1e..0684402b14 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -19254,6 +19254,21 @@ handle_one_xevent (struct x_display_info *dpyinfo, goto OTHER; case FocusIn: +#if defined HAVE_XINPUT2 \ + && (defined HAVE_GTK3 || (!defined USE_GTK && !defined USE_X_TOOLKIT)) + /* If a FocusIn event is received (because the window manager + sent us one), don't set the core focus if XInput 2 is + enabled, since that would mess up the device-specific focus + tracking. + + The long looking preprocessor conditional only enables this + code on GTK 3 and no toolkit builds, since those are the only + builds where focus is tracked specific to each master device. + Other builds use core events and the client pointer to handle + focus, much like on a build without XInput 2. */ + if (dpyinfo->supports_xi2) + goto OTHER; +#endif #ifdef USE_GTK /* Some WMs (e.g. Mutter in Gnome Shell), don't unmap minimized/iconified windows; thus, for those WMs we won't get @@ -19367,6 +19382,21 @@ handle_one_xevent (struct x_display_info *dpyinfo, goto OTHER; case FocusOut: +#if defined HAVE_XINPUT2 \ + && (defined HAVE_GTK3 || (!defined USE_GTK && !defined USE_X_TOOLKIT)) + /* If a FocusIn event is received (because the window manager + sent us one), don't set the core focus if XInput 2 is + enabled, since that would mess up the device-specific focus + tracking. + + The long looking preprocessor conditional only enables this + code on GTK 3 and no toolkit builds, since those are the only + builds where focus is tracked specific to each master device. + Other builds use core events and the client pointer to handle + focus, much like on a build without XInput 2. */ + if (dpyinfo->supports_xi2) + goto OTHER; +#endif x_detect_focus_change (dpyinfo, any, event, &inev.ie); goto OTHER;