exwm icon indicating copy to clipboard operation
exwm copied to clipboard

Focus Retention when switching to (non-EXWM) buffers

Open moritzschaefer opened this issue 1 year ago • 9 comments

When switching to another window (usually on a different workspace) with an emacs (not EXWM/X) buffer, it happens (50% of cases) that the 'focus' remains on the last window.

This is visible from the cursor color in switched-to window-buffer (a transparent box image)

rather than the full-color active-cursor cursor image

More importantly, when in this inactive state, it happens that typing on the keyboard, leads to input-actions on the previous buffer/window (no matter whether it is an EXWM/X buffer or an emacs buffer)! In consequence, the active workspace automatically "switches back" showing the previously active window/workspace/buffer.

Any ideas on how to debug this?

PS 1: For a long time, I suspected that this is the same error as described in #759, but it must be different, since it also happens when switching between emacs-buffers (although less often)

PS 2: Following old #942 I am opening this in this new repo. A big thank you to the maintainer(s) for moving this project forward!

moritzschaefer avatar Jan 20 '24 10:01 moritzschaefer

I also stumble over over focus issues from time to time (in general, maybe not specifically this one). Fixing focus issues has a high priority and I hope that we will make progress there soon. In general it is helpful if you provide a minimal recipe (a minimal Emacs configuration), and figure out precise reproduction steps. As you wrote, the issue only happens in 50% of the cases, so the behavior is likely timing dependent and this makes it a little harder to debug. Maybe @Stebalien has some specific debugging suggestions?

minad avatar Jan 20 '24 10:01 minad

I have had this exact same issue and my solution was to update libX11 to 1.8.4 as I documented here https://github.com/ch11ng/exwm/issues/889#issuecomment-1458771088 . There are other suggested fixes in that thread.

nagy avatar Jan 20 '24 10:01 nagy

Thank you so much for pointing me there. I read through the issues, but didn't recognize that issue as mine while skimming over it. Closing here in favor of the other one

moritzschaefer avatar Jan 20 '24 13:01 moritzschaefer

I also experience this from time to time. For months I suspected that it was tied to mu4e, but just now it is happening without mu4e and between two Emacs buffers (doc-view mode and org-mode). My libX11 is on version 1.8.7.

ArneBab avatar Jan 14 '25 06:01 ArneBab

@ArneBab can you try setting x-no-window-manager to t? I've found not setting this can cause some focus issues, but I've only seen them when switching between X and Emacs windows.

(note: this is now set to t on master, but that hasn't been released yet)

Stebalien avatar Jan 14 '25 06:01 Stebalien

I set it now — will report whether the issue repeats in the next days. Thank you!

ArneBab avatar Jan 14 '25 09:01 ArneBab

I have the same issues as originally described. When my mouse switches between a window displaying an emacs buffer and a window displaying an exwm buffer, in either direction, the focus isn't always followed.

However, when I very slowly move my cursor between the windows, focus does follow as intended. This happens when moving vertically and horizontally.

Another case where it does work reliably is if I'm going clockwise or counter-clockwise in a 2x2 layout of interleaving exwm and non-exwm windows, like this:

 .-------------.--------------.
|      EXWM    |  NON-EXWM    |
|              |              |
| ------------ | ------------ |
|  NON-EXWM    |      EXWM    |
|              |              |
| ------------ | ------------ |

And if I have a vertical stack of interleaving EXWM + non-EXWM windows, the focus skips over the second buffer from the top if my cursor is going down, and the second buffer from the bottom if my cursor is going up:

Cursor going down \/
.--------------.
|      EXWM    |  <-- start point
|  (focused)   |
| ------------ |
|  NON-EXWM    |
|  (skipped)   |
| ------------ |
|      EXWM    |
|  (focused)   |
| ------------ |
|  NON-EXWM    |
|  (focused)   |
| ------------ |


Cursor going up ^
.--------------.
|      EXWM    |
|  (focused)   |
| ------------ |
|  NON-EXWM    |
|  (focused)   |
| ------------ |
|      EXWM    |
|  (skipped)   |
| ------------ |
|  NON-EXWM    |
|  (focused)   | <-- start point
| ------------ |


So, basically: two of the same type of buffers will always switch focus between each other if there's another kind in-between them; and once both of them have switched, then the other type of buffer will focus properly.

Anyway here's what my XELB debug looks like when I switch buffers quickly vs slowly:

nonexwm -> exwm fast (focus doesn't follow):
[00:13:13]exwm-input--on-EnterNotify:   buffer=*EXWM*<2>; window=#<window 53 on *EXWM*<2>>
[00:13:13]exwm--on-PropertyNotify:      atom=WM_NORMAL_HINTS(40)
[00:13:13]exwm--update-normal-hints:    #x1a0001e
[00:13:13]exwm-input--on-PropertyNotify:
[00:13:13]exwm--on-PropertyNotify:      atom=WM_NORMAL_HINTS(40)
[00:13:13]exwm--update-normal-hints:    #x1a0001e
[00:13:13]exwm-input--on-PropertyNotify:


exwm -> nonexwm fast (focus doesn't follow):
[00:13:24]exwm--on-PropertyNotify:      atom=WM_NORMAL_HINTS(40)
[00:13:24]exwm--update-normal-hints:    #x1a0001e
[00:13:24]exwm-input--on-PropertyNotify:
[00:13:24]exwm--on-PropertyNotify:      atom=WM_NORMAL_HINTS(40)
[00:13:24]exwm--update-normal-hints:    #x1a0001e
[00:13:24]exwm-input--on-PropertyNotify:


nonexwm -> exwm slow (focus follows):
[00:14:17]exwm-input--on-buffer-list-update:    current-buffer=#<buffer *EXWM*<2>> selected-window=#<window 53 on *EXWM*<2>>
[00:14:17]exwm-input--update-focus:     focus-window=#<window 53 on *EXWM*<2>> focus-buffer=*EXWM*<2>
[00:14:17]exwm-input--update-focus:     Set focus on #x1a0001e
[00:14:17]exwm-input--set-focus:        #x1000018 (corrected) => #x1a0001e
[00:14:17]exwm-input--update-timestamp:
[00:14:17]exwm-input--on-EnterNotify:   buffer=*EXWM*<2>; window=#<window 53 on *EXWM*<2>>
[00:14:17]exwm--on-PropertyNotify:      atom=_TIME(571)
[00:14:17]exwm-input--on-PropertyNotify:
[00:14:17]exwm-input--set-active-window:
[00:14:17]exwm--on-PropertyNotify:      atom=WM_NORMAL_HINTS(40)
[00:14:17]exwm--update-normal-hints:    #x1a0001e
[00:14:17]exwm-input--on-PropertyNotify:
[00:14:17]exwm--on-PropertyNotify:      atom=WM_NORMAL_HINTS(40)
[00:14:17]exwm--update-normal-hints:    #x1a0001e
[00:14:17]exwm-input--on-PropertyNotify:
[00:14:17]exwm--on-PropertyNotify:      atom=WM_NORMAL_HINTS(40)
[00:14:17]exwm--update-normal-hints:    #x1a0001e
[00:14:17]exwm-input--on-PropertyNotify:
[00:14:17]exwm--on-PropertyNotify:      atom=WM_NORMAL_HINTS(40)
[00:14:17]exwm--update-normal-hints:    #x1a0001e
[00:14:17]exwm-input--on-PropertyNotify:


exwm -> nonexwm slow (focus follows):
[00:15:37]exwm--on-PropertyNotify:      atom=WM_NORMAL_HINTS(40)
[00:15:37]exwm--update-normal-hints:    #x1a0001e
[00:15:37]exwm-input--on-PropertyNotify:
[00:15:37]exwm--on-PropertyNotify:      atom=WM_NORMAL_HINTS(40)
[00:15:37]exwm--update-normal-hints:    #x1a0001e
[00:15:37]exwm-input--on-PropertyNotify:
[00:15:37]exwm-input--on-buffer-list-update:    current-buffer=#<buffer *XELB-DEBUG*> selected-window=#<window 56 on *XELB-DEBUG*>
[00:15:37]exwm-input--update-focus:     focus-window=#<window 56 on *XELB-DEBUG*> focus-buffer=*XELB-DEBUG*
[00:15:37]exwm-input--update-focus:     Focus on #<window 56 on *XELB-DEBUG*>
[00:15:37]exwm-input--set-active-window:
[00:15:37]exwm--on-PropertyNotify:      atom=WM_NORMAL_HINTS(40)
[00:15:37]exwm--update-normal-hints:    #x1a0001e
[00:15:37]exwm-input--on-PropertyNotify:
[00:15:37]exwm--on-PropertyNotify:      atom=WM_NORMAL_HINTS(40)
[00:15:37]exwm--update-normal-hints:    #x1a0001e
[00:15:37]exwm-input--on-PropertyNotify:

I see that there isn't even an event captured by exwm-input when I quickly move my cursor exwm->non-exwm. So, maybe there is a XELB bug?

Kiboneu avatar Feb 15 '25 18:02 Kiboneu

I set it now — will report whether the issue repeats in the next days. Thank you!

Since I set x-no-window-manager t, I have only seen this issue very rarely. So a release with this setting as default would solve my part of the problem.

ArneBab avatar Feb 15 '25 19:02 ArneBab

@Kiboneu

Unfortunately, I've never gotten "focus follows mouse" to work properly. I spent some time debugging it and gave up.

I'm guessing it works when moving "really slowly" because there's a small border between the two windows and that lets Emacs see the mouse movement evens.


@ArneBab

Since I set x-no-window-manager t, I have only seen this issue very rarely. So a release with this setting as default would solve my part of the problem.

This should be the default in the latest release (0.33). Does it work for you?

Stebalien avatar Feb 15 '25 19:02 Stebalien

@Kiboneu the following seems to work now:

(setopt focus-follows-mouse 'auto-raise
        mouse-autoselect-window t)

As long as these are set BEFORE starting EXWM.

Can you confirm that?

Stebalien avatar Oct 26 '25 18:10 Stebalien

To me this is not an issue anymore, except for chromium/electron-based apps

moritzschaefer avatar Oct 31 '25 01:10 moritzschaefer

Yeah, I can reproduce the chromium issue. For me, it's easiest to reproduce by:

  1. Starting on an open chromium window.
  2. Calling next-buffer to switch to an Emacs buffer.
  3. Calling previous-buffer to switch back to the chromium window.

At that point, chrome will refuse to respond to keypresses until I click on the window (or switch away and back).

It's clear there's some property/message chrome is expecting that we're not setting.

Stebalien avatar Nov 04 '25 03:11 Stebalien

I'm closing this in favor of a focused chromium issue: https://github.com/emacs-exwm/exwm/issues/163

Stebalien avatar Nov 04 '25 17:11 Stebalien