diff options
| author | Po Lu | 2022-09-03 21:39:30 +0800 |
|---|---|---|
| committer | Po Lu | 2022-09-03 21:44:48 +0800 |
| commit | ab5ca80e745e86c33e6bec86c9331978d071d1a4 (patch) | |
| tree | c64d04249e0157c772710812a96a4966e68b24f9 /src | |
| parent | 419d7579056850057d9897f012acd30d2670b7b9 (diff) | |
| download | emacs-ab5ca80e745e86c33e6bec86c9331978d071d1a4.tar.gz emacs-ab5ca80e745e86c33e6bec86c9331978d071d1a4.zip | |
Work around another X server bug in crossing event dispatch
* src/xterm.c (xi_focus_handle_for_device): Clear implicit focus
along with FocusOut. (bug#57468)
(x_mouse_leave): Avoid invalid reads of
dpyinfo->x_focus_event_frame on input extension builds.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xterm.c | 27 |
1 files changed, 26 insertions, 1 deletions
diff --git a/src/xterm.c b/src/xterm.c index 19d2198cdf6..accd1b90fb8 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -12740,6 +12740,25 @@ xi_focus_handle_for_device (struct x_display_info *dpyinfo, | |||
| 12740 | 12740 | ||
| 12741 | case XI_FocusOut: | 12741 | case XI_FocusOut: |
| 12742 | device->focus_frame = NULL; | 12742 | device->focus_frame = NULL; |
| 12743 | |||
| 12744 | /* So, unfortunately, the X Input Extension is implemented such | ||
| 12745 | that means XI_Leave events will not have their focus field | ||
| 12746 | set if the core focus is transferred to another window after | ||
| 12747 | an entry event that pretends to (or really does) set the | ||
| 12748 | implicit focus. In addition, if the core focus is set, but | ||
| 12749 | the extension focus on the client pointer is not, all | ||
| 12750 | XI_Enter events will have their focus fields set, despite not | ||
| 12751 | actually changing the effective focus window. Combined with | ||
| 12752 | almost all window managers not setting the focus on input | ||
| 12753 | extension devices, this means that Emacs will continue to | ||
| 12754 | think the implicit focus is set on one of its frames if the | ||
| 12755 | actual (core) focus is transferred to another window while | ||
| 12756 | the pointer remains inside a frame. The only workaround in | ||
| 12757 | this case is to clear the implicit focus along with | ||
| 12758 | XI_FocusOut events, which is not correct at all, but better | ||
| 12759 | than leaving frames in an incorrectly-focused state. | ||
| 12760 | (bug#57468) */ | ||
| 12761 | device->focus_implicit_frame = NULL; | ||
| 12743 | break; | 12762 | break; |
| 12744 | 12763 | ||
| 12745 | case XI_Enter: | 12764 | case XI_Enter: |
| @@ -13163,7 +13182,13 @@ x_mouse_leave (struct x_display_info *dpyinfo) | |||
| 13163 | hlinfo->mouse_face_mouse_frame = NULL; | 13182 | hlinfo->mouse_face_mouse_frame = NULL; |
| 13164 | } | 13183 | } |
| 13165 | 13184 | ||
| 13166 | x_new_focus_frame (dpyinfo, dpyinfo->x_focus_event_frame); | 13185 | #ifdef HAVE_XINPUT2 |
| 13186 | if (!dpyinfo->supports_xi2) | ||
| 13187 | /* I don't understand what the call below is supposed to do. But | ||
| 13188 | reading dpyinfo->x_focus_event_frame is invalid on input | ||
| 13189 | extension builds, so disable it there. */ | ||
| 13190 | #endif | ||
| 13191 | x_new_focus_frame (dpyinfo, dpyinfo->x_focus_event_frame); | ||
| 13167 | } | 13192 | } |
| 13168 | #endif | 13193 | #endif |
| 13169 | 13194 | ||