First keystroke not sent to the X client when switching windows using <escape>
Hi,
This might not be a bug but I wanted my experience to be written down somewhere where a search engine could pick it up as it might save somebody else's time.
First of all thanks for creating and maintaining EXWM. It has boosted my productivity a lot :)
I use ace-window to switch between windows. I've been doing this even before I jumped into EXWM. As I use it very often, I decided to bind it to <escape> which I have swapped with CapsLock using Xmodmap.
(use-package ace-window
...
:bind (("<escape>" . ace-window))
...
)
This has always worked fine using "normal" buffers in any mode.
When I installed EXWM I realised that once I had switched to a window containing an EXWM buffer, I was unable to switch back using <escape> because the keystroke was being sent directly to the X client. Okay, so I guessed that I had to tell EXWM not to send that key to the app but to Emacs instead. I read about exwm-input-prefix-keys and after some Googling I ended up with this:
(use-package exwm
:config
...
(add-to-list 'exwm-input-prefix-keys (aref (kbd "<escape>") 0))
...
)
This changed things. I was able to switch back and forth from a window containing an EXWM buffer to a "normal one". However, something odd was happening.
When I was moving from a normal buffer to an X client, the first keystroke was not being sent to the application. Instead, I was getting an error in my minibuffer:
"command-execute: Buffer is read-only"
This was only happening with the first keystroke. The focus switched correctly to the application, though. I wanted to know what command was being executed because none should be once the window gained focus so I redefined command-execute to add some custom code as a quick and dirty way to debug. After that, I saw that for instance when I was pressing C-t right after switching to a Firefox window to open a new tab what was actually happening was that Emacs was executing transpose-chars on the EXWM buffer which was failing of course because the buffer was read-only. After immediately pressing again C-t everything worked fine, a new tab was opened and I could use Firefox normally. This was happening with any keystroke even simple text input, C-t is just an example.
I tried configuring the binding like this instead:
(define-key exwm-mode-map (kbd "<escape>") 'ace-window)
But I was getting the same result. Guess this is what @adithyaov describes here as "a little buggy".
So then came up with the idea of using a less "meaningful" key to do this, so instead of using <escape> I swapped CapsLock with <f8> and changed the configuration as follows:
(use-package ace-window
...
:bind (("<f8>" . ace-window))
...
)
...
(use-package exwm
:config
...
(define-key exwm-mode-map (kbd "<f8>") 'ace-window)
...
)
And voila, everything started to work as it should.
Sorry for the noise if this is expected behaviour. I'm a newbie :)
thanks for the detailed report! I'm having a similar error, including the "read only" error, that seems to be a newly-instituted delay to focus changing to exwm buffers. I have to "switch to..." twice to get it right, but only sometimes. It's annoying, and I don't know a fix yet. I no longer use ace-window, but instead use winum. Anyway, I'll see the buffer gain focus, but the "window" in it doesn't have my focus yet (I get "read only", or C-x C-b opens the listing in my previous window and not the new one). I'm still debugging, but will leave this here as a note.