Open jcbedacuk opened 2 years ago
Hmm.. This does sound like odd behavior.
I can see a way (but haven't tested it) that xdotool might switch between XTEST and XSendEvent:
When sending keys, if a window ID is non-zero, that is, you know which specific window to send keys to, xdotool will check if that window is currently focused, and if so, will use XTEST. If that window is not focused, then it uses XSendEvent.
This change was added in #85 due to #84.
I'm not sure why it's necessary to use XTest normally
Because too many programs ignore XSendEvent synthetic events which defeats the goals of xdotool. We try to make the best default choice, where possible, because a user wanting "Type the letter 'a'" should not have to know what XSendEvent and XTEST are, nor should they be required to understand any other deeper details about X11.
But given that it does, should it at least use the same value of use_xtest for an entire key sequence, rather than recomputing it for every event
I agree with you. It's worth revisiting how xdotool decides when to use XTEST vs XSendEvent and see about fixing your issue while at the same time not reviving the problem from #85/#84.
I can imagine some API changes that would make this simpler, though I haven't dug much into the code to see what changes might be needed.
This is still an issue (not surprising since it's still open and no one has fixed it!):
$ xdotool --version
xdotool version 3.20211022.1
$ pacman -Qo /usr/lib/libxdo.so
/usr/lib/libxdo.so is owned by xdotool 3.20211022.1-1
and @jcbedacuk's description is spot-on.
As they stated, a straight-forward fix to this (no API changes required) would be to link keydown
+keyup
events sent by the same key
event such that they cannot be sent via two different interfaces (keydown
via XTEST
and the subsequent keyup
via XSendEvent
in this case) resulting in the XTEST
device ending up in an inconsistent state (and spamming a key repeatedly).
As in @jcbedacuk's case, mine was also caused by sending a key which closes the window. I tried using windowclose
for this instead, but unfortunately in my case the window must be closed in a particular way to get the desired result so the appropriate key must be pressed (which for me is just Enter to select the default highlight button).
For anyone else stumbling into here in the future, after researching this issue and others which link to it I came up with the following workaround:
xdotool keydown --window ${windowid} Enter
xdotool keyup --window 0 Enter
This takes advantage of this comment from #85:
I think it's worth noting that doing key --window 0 a will send 'a' to the current window -- I don't know if this is documented, though. There's a special window value xdo uses for knowing when to act on the "current window" and that is 0.
and the code above to force the keyup
to be sent to XTEST
whether the ${windowid}
was focused or not. In the event that it was focused (causing the keydown
to be sent via XTEST
) sending a keyup
via XTEST
to correct its state seems to be harmless to the current window (whatever it may be) and certainly more harmless than spamming keydown
for that key instead.
If I send a key (let's call it q) to an application that has focus, and the application responds to the keydown event (sent via XTest) by quitting, then xdotool tries (and fails) to send the keyup by XSendEvent. This results in the XTest device key being down, and then q autorepeats in whatever window now has focus until cleared by pressing a physical version of the key. I'm not sure why it's necessary to use XTest normally (overriding an application's decision to ignore synthetic events should perhaps be a positive choice rather than a default). But given that it does, should it at least use the same value of use_xtest for an entire key sequence, rather than recomputing it for every event?