-
Notifications
You must be signed in to change notification settings - Fork 323
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Modifiers can become stuck after using --clearmodifiers #43
Comments
@jonhrafe and I are having the same issue when triggering |
I'm experiencing the same issue. You can work around this by using xdotool's
|
Same here. The action sequence is the following:
My memory is fuzzy on the details. Is is possible to query the physical state bypassing the X state? This would fix this issue. |
Any updates on this? |
After a poke on twitter, I did some thinking about this. The problem as I understand it is described well in this issue -- it's basically a race between xdotool resetting modifier/key states and the human releasing the keys physically. When the human releases before xdotool finishes, it will restore any modifiers (as if you are holding shift or contrtol or other modifier keys) even after a human has released. I'm not confident we can solve this race condition, so I am thinking we can change the behavior of xdotool to not restore modifiers. Whether this behavior change happens through a flag or not, I am not sure and will rely on y'all to help me figure out if this should be the default behavior or not. I have ideas for what the human interface for this could look like, but first I'd like to test a solution! |
FYI I have posted a bounty for this issue on bounty source. Would love to see us figure out a clean solution. https://www.bountysource.com/issues/2526330-modifiers-can-become-stuck-after-using-clearmodifiers |
A rough outline of the solution is to avoid having xdotool race the human. To do this, we must have a way to skip the "restore modifiers" step. I'm thinking that --clearmodifiers should, by default, skip restoration of modifiers. Restoring modifiers was intended for a kind of "xdotool shouldn't do anything unexpected to the keyboard state" and when a human invokes xdotool via hotkey that uses a modifier (say, control + F1), the human could release those keys before xdotool "restores" the clearing of the control modifier. Given the use cases here, I suspect it's mostly humans invoking xdotool via such hotkeys and ultimately beating xdotool at this race, leaving xdotool to do something unexpected and undesired. Proposal:
Ultimately, if time ordered steps occur as follows, the keyboard should not have an active modifiers by the end:
Today, step 5 is xdotool restoring ("pressing") the control key before exit which leaves it in the stuck-down state as reported in this issue. My proposal in the PR linked #276 is to no longer do this restoration. |
I will try to build and test the branch. I think this comment from @wavexx is an accurate and concise description of the issue. I don't know what APIs and techniques are available as I have not done any X11 programming myself, but I think logically the cleanest solution would be for each modifier that was initially detected, then cleared for the scripted keystrokes, before restoring it confirm it's still down. If so restore it, but if it's up, don't restore it. Although in my particular use case I think maybe Jordan's proposal would work. Here's the details of how this bug impacts me:
|
I tested the fix in #276 but it screws up my usage pattern because now even though I'm still physically pressing my super modifier, xdotool now clears it so instead of triggering my same hotkey again I'm now just typing letters. |
Ahh yeah I didn't think this was what you were doing; I agree with your point about @wavexx's comment. It is possible to query the physical keyboard state using XQueryKeymap, and this is what happens internally in xdo's It shouldn't be too hard to query the keymap a second time (when it comes time to restore) and only restore modifiers for keys that are still pressed. However, I am still not certain about timing/race conditions. I'm willing to write the code and hope that testing shows it works ;) On timing, honestly, In my head, the code to rescan and selectively restore only keys that are still active should be pretty simple (intersect two lists, etc) so I can probably have a patch ready to try later this week. |
OK bear in mind there's other stuff at the start of the "race" like scripts running assorted commands, forking processes, etc, so the timing might be like:
note my actual xdotool command in the most common case is |
Small status update. XQueryKeymap shows what X11 believes about the current key state which includes anything sent with XTEST. In my testing, this shows:
This means that we can't use XQueryKeymap to see if a key is still held by the human. |
It's possible XINPUT or xkbcommon could help here. xinput shows physical device state:
|
side note: It might be easier (?) in the long-term to move the input (keyboard/mouse) stuff to a separate library from xdotool. Wayland is coming to most major distros if it isn't there already, and xdotool doesn't really work at all on these systems. There are non-xdo alternatives for input emulation like Linux's uinput kernel module which lets you simulate keyboard/mouse inputs from userland similarly to xdotool, but the interface for uinput is the linux kernel instead of xdo's x11 interface. I've been thinking about doing exactly this for several years now. It's a larger effort than this particular xdotool bug, I think, but might be worth it. |
`xdotool` has a race condition when holding down modifier keys: jordansissel/xdotool#43 (Note: this commit is on a repo of personal $HOME files.)
I've made a very dirty solution for this. The case is there are two keyboard input devices in xorg. One "AT Translated Set 2 keyboard", and a second "Virtual core XTEST keyboard". The key stucks only on the seconds virtual keyboard.
@jordansissel gave me the idea with his I'm using Alt+d for minimize/restore hexchat with IceWM, but you can easily adopt the method to any other wm.
Number 64 is the keycode for left Alt, so I release it on virtual keyboard just right after releasing on the physical. |
There is a bug in xdotool where --clear-modifiers can lead to the i3 $mod key getting stuck, see jordansissel/xdotool#43 This means that instead of receiving e.g. <C-h>, vim will now receive <C-M-h> (assuming i3 $mod is set to the alt key), so the keybindings in the .vimrc need to be adapted accordingly
There is a bug in xdotool where --clear-modifiers can lead to the i3 $mod key getting stuck, see jordansissel/xdotool#43 This means that instead of receiving e.g. <C-h>, vim will now receive <C-M-h> (assuming i3 $mod is set to the alt key), so the keybindings in the .vimrc need to be adapted accordingly
Is there any way to get the keys unstuck when this happens, besides having to log out and losing all open programs? |
@chylex Pressing and releasing the modifier key that is currently stuck should do it. If you needed a good reason to smash the keyboard, that's the perfect excuse. |
@wavexx Doesn't work. I use |
@chylex So the keys are always Super+[key], but I assume kickoff just uses Super by itself? (never used kickoff sorry). If that's the case, I'd almost think kickoff is monitoring for Super state toggles without checking for the current modifier state itself. Although xdotool definitely breaks the modifier state, the effect is not permanent. I would still consider this to be a bug in kickoff: the modifier state should always be reset internally to each program, usually on the "off" state, under the assumption that events could be lost or duplicated during the lifetime of a program. |
Maybe try switching to another VT (e.g. via control-alt-F2), logging in on the console and then running an
VT-switching keystrokes don't depend on X11, and hence should work regardless of what X thinks the state of the modifier keys is. |
for the moment I solved the issue by wrapping
seems to work well without the delay, but I'm using this to emulate macos shortcuts on my i3 setup, so mileage may vary |
This waits for the user to release any modifier keys that are currently held before starting to type. This allows avoiding race conditions when xdotool is called from a keyboard shortcut, and starts to type characters with the modifier still held. Currently the usual way to do so is with --clearmodifiers, but this introduces its own race conditions (see e.g. issue jordansissel#43) if the physical key is released while the typing is in progress.
Maybe it's better if we release the keys manually instead of fixing them with `--clearmodifiers` and jordansissel/xdotool#43 . Issue: #56
Thanks for this. Putting this in a Despite having used |
Taken from a bug report on Google Code:
What steps will reproduce the problem?
Having this in .xbindkeysrc:
"sleep 0.1 && xdotool type --clearmodifiers --args 1 123123 && xdotool key --clearmodifiers Tab && xdotool type --clearmodifiers --args 1 123123"
m:0x40 + c:10
Mod4 + 1
(That's for filling 2 textboxes in a browser)
push win(mod4)+1
sometimes the mod4 key is "stuck"
that means pressing e.g. TAB acts like win+TAB
What version of the product are you using? On what operating system?
20110530.1-6
xubuntu 13.04
My addendum:
"xdotool sleep 0.2 type --clearmodifiers test123"
m:0x14 + c:49
Control+Mod2 + grave
I'm experiencing this issue too. I think the problem is that I hit the macro by first pressing control then a moment later pressing grave, and to release the key combination I let go of everything at once. So, the macro thinks it needs to put the modifier back into the "down" state, even though it has already been released.
To put it more succinctly, I suspect that the problem is that clearmodifiers doesn't keep track of changes to key state since the modifiers were saved.
The text was updated successfully, but these errors were encountered: