magit / transient

Transient commands
https://magit.vc/manual/transient
GNU General Public License v3.0
707 stars 65 forks source link

Show-stopping Transient EXWM conflict #118

Closed WorldsEndless closed 3 years ago

WorldsEndless commented 3 years ago

Transient and EXWM seem to have some clash that I never had with Hydras, which are quick to fail and get out of the way. The issue is that when I invoke a global transient from an exwm window (often by accident), suddenly transient pops up intercepting my next keypress -- but apparently intercepting it after exwm does. The result is that I have a screen which cannot receive input; I continually get errors from Transient about an unknown input (e.g. C-g or "mouse-1") but the exwm (e.g. Firefox, or another emacs) window also can't receive any input. If I'm lucky I can click on one of my other monitors and it will exit the Transient. But in the worst case I have to pkill emacs from a terminal, as I just did a few minutes ago with a Firefox issue and a mistype into a global Transient.

Is there an obvious remedy that I should have, other than "stop invoking transient in the wrong places"?

magit-version : Magit v2.90.1-1230-gf883b62f, Git 2.31.1, Emacs 27.2, gnu/linux

tarsius commented 3 years ago

What is a "global" transient and how is it different from a non-global transient?

WorldsEndless commented 3 years ago

Oops -- sorry to make up terminology. I mean, a global key-binding to a transient, as opposed to a mode-specific one. global-set-key sort of thing.

WorldsEndless commented 3 years ago

(returning to this issue)

I have been gradually experimenting with replacing my hydras with transients, partly as a proof of concept. I have a show-stopping issue when I end up invoking the transients from an exwm window, however. The transient pops up, but no key I press is then sent to the transient and I end up trapped in a loop: transient is expecting a key, which needs to be passed by exwm, but exwm can't pass any keys because transit is intercepting them. Fortunately I can click on an emacs buffer on one of my other monitors and this terminates the transient. That is, the transient is unhappy, but I can't kill it because the transient is not being passed the c-g properly. I get an error message that resembles:

Unbound suffix: ‘u’ (Use ‘C-g’ to abort, ‘?’ for help) [self-insert-command]

Now, this isn't reproducible on demand. It seems to be connected with an error in exwm that sometimes makes for a distinction between window focus and keyboard focus. And yes, this problem is not entirely Transient's fault. However, with hydras, they automatically, quickly terminate if they receive something they can't handle. Now, there are many of the more sophisticated cases with Transient where you wouldn't want this behavior at all, such as magit, when you have multiple-event interfaces. But before I give up on using transient for simple dispatch, is there a way I can tell certain Transients to fail fast and terminate on ANY unknown suffix?

WorldsEndless commented 3 years ago

Ah! I think I found the answer.

  :transient-non-suffix 'transient--do-quit-one

This isn't completely the same, since it lets the non-suffix itself pass through, but seems to do the trick. But seems to me that this is a must-have for simple dispatch-map usage of transient.

tarsius commented 11 months ago

You might want to try without this kludge for a while. The getting stuck issue should be fixed now.

tarsius commented 11 months ago

Oh, and use :transient t instead of :transient transient--do-stay.