Giter VIP home page Giter VIP logo

Comments (22)

subnixr avatar subnixr commented on July 2, 2024 4

for the moment I solved the issue by wrapping xdotool key --clearmodifiers in a simple script (based on @bbugyi200 solution):

#!/bin/sh -e
xdotool key --clearmodifiers $@
xdotool keyup Meta_L Meta_R Alt_L Alt_R Super_L Super_R

seems to work well without the delay, but I'm using this to emulate macos shortcuts on my i3 setup, so mileage may vary

from xdotool.

dimitarvdimitrov avatar dimitarvdimitrov commented on July 2, 2024 3

Any updates on this?

from xdotool.

jordansissel avatar jordansissel commented on July 2, 2024 3

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!
I've opened #276 which disables the "restore modifiers" piece of --clearmodifiers and hopefully results in some improved behavior for folks. If you are able to test this branch, please report any findings (successful or otherwise)

from xdotool.

jordansissel avatar jordansissel commented on July 2, 2024 2

but I might hit the letter again and again without ever releasing super to move additional tabs

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 xdo_get_active_modifiers.

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, xdotool key --clearmodifiers ... should practically execute extremely quickly. Fast enough that hotkey activation (and xdotool invocation) and human keyboard key release shouldn't really even compete! And yet, these races still happen somehow where the human key release happens before xdotool finishes? I don't know exactly why or how this happens, but xdotool typing should be much faster than a single keystroke at normal human typing speeds... My hypothesis is that because we are seeing these races in which humans release a key faster than xdotool completes, then even if we rescan the active keyboard keys, it'll still be too slow somehow. One way to test is to write the code to try this rescanning and let y'all test.

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.

from xdotool.

jordansissel avatar jordansissel commented on July 2, 2024 2

It's possible XINPUT or xkbcommon could help here. xinput shows physical device state:

# Hold ctrl and shift keys down shortly after starting the command below
% sleep 0.5; xinput query-state 7 | grep -v up;  xdotool keyup Shift_L; xinput query-state 7 | grep -v up
1 class :
KeyClass
	key[37]=down
	key[50]=down
1 class :
KeyClass
	key[37]=down
	key[50]=down

7 above is device id 7 which on my system is my physical keyboard device:

↳ Windows keyboard id=7 [slave keyboard (3)]

from xdotool.

wavexx avatar wavexx commented on July 2, 2024 1

Same here. The action sequence is the following:

  • I invoke xdotool with "Ctrl" held, since xdotool is triggered by some shortcut
  • xdotool --clearmodifiers will reset the ctrl state and perform the action as intended
  • while xdotool is operating, I lift the finger from Ctrl
  • xdotool completes the action, and restores the "Ctrl" state, although "Ctrl" is no longer physically held on the keyboard.

My memory is fuzzy on the details. Is is possible to query the physical state bypassing the X state?
Maybe through xinput directly?

This would fix this issue.

from xdotool.

jordansissel avatar jordansissel commented on July 2, 2024 1

Small status update.

XQueryKeymap shows what X11 believes about the current key state which includes anything sent with XTEST. In my testing, this shows:

  1. Human presses and holds shift
  2. Xdotool --clearmodifiers releases shift key
  3. XQueryKeymap shows shift is no longer held even though the physical key is held.

This means that we can't use XQueryKeymap to see if a key is still held by the human.
I'll check for any other API which might expose the physical keyboard key states.

from xdotool.

jordansissel avatar jordansissel commented on July 2, 2024 1

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.

from xdotool.

daducci avatar daducci commented on July 2, 2024

@jonhrafe and I are having the same issue when triggering xdotool with a **keyboard shortcut&& inside the Atom editor; see [daducci/atom-ipython-exec#2]. Is there any workaround to this behaviour?

from xdotool.

bbugyi200 avatar bbugyi200 commented on July 2, 2024

I'm experiencing the same issue. You can work around this by using xdotool's keyup option after a
short delay. The problem with this, however, is that if you are using a key mapping that is
sometimes used repeatedly you will be forced to lift your fingers off of the modifiers after each
use of the binding. You can mitigate the annoyance by placing the xdotool commands inside of a
script and killing old instances of the script (if any exist) before moving forward. Something like
this works good:

pid_file=/tmp/"$(basename "$0")".pid
old_pid="$(cat "${pid_file}")"
if kill -0 "${old_pid}" &> /dev/null; then
    kill "${old_pid}"
fi

echo "$$" > "${pid_file}"

DO STUFF HERE (--clearmodifiers)

sleep 0.5 && xdotool keyup Meta_L Meta_R Alt_L Alt_R Super_L Super_R

from xdotool.

focusaurus avatar focusaurus commented on July 2, 2024

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

from xdotool.

jordansissel avatar jordansissel commented on July 2, 2024

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:

  1. Have all --clearmodifiers flags no longer attempt to restore modifiers
  2. Later, if someone needs it, we can add a way (flag, or otherwise) to add modifier restoration back in?

Ultimately, if time ordered steps occur as follows, the keyboard should not have an active modifiers by the end:

  1. Human presses control+f1 hotkey to invoke xdotoolkey --clearmodifiers ... (using xbindkeys or something)
  2. xdotool sees 'control' modifier is active and clears it
  3. xdotool types the keys as instructed
  4. human releases control key
  5. xdotool finishes

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.

from xdotool.

focusaurus avatar focusaurus commented on July 2, 2024

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'm navigating tabs (tmux, firefox, vs code, etc I have them all scripted this way)
  • So I press and hold my modifier which is super then I type a letter bound to a "next tab script", it runs, invokes an xdotool to send the appropriate app hot key, but I might hit the letter again and again without ever releasing super to move additional tabs. When I'm finally done I'll release super but if I do that too quickly I'll hit this bug and it's stuck down.

from xdotool.

focusaurus avatar focusaurus commented on July 2, 2024

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.

from xdotool.

focusaurus avatar focusaurus commented on July 2, 2024

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:

  • I keydown a letter that starts a hotkey
  • hotkey launches a script
  • script runs a bunch of unrelated commands that take non-zero time
  • script runs xdotool --clearmodifiers (I'm still holding the modifier)
  • I just happen to release the modifier at this moment but bear in mind this could easily be 100ms from the start so it's not like I'm racing xdotool for something like 1ms
  • The xdotool restores the modifier resulting in the stuck bug

note my actual xdotool command in the most common case is xdotool key --clearmodifiers ctrl+b o so it's 2 separate keystrokes which adds a tiny bit of delay.

from xdotool.

zaza42 avatar zaza42 commented on July 2, 2024

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.

$ xinput
<...cut...>
⎣ Virtual core keyboard                   	id=3	[master keyboard (2)]
    ↳ Virtual core XTEST keyboard             	id=5	[slave  keyboard (3)]
<...cut...>
    ↳ AT Translated Set 2 keyboard            	id=12	[slave  keyboard (3)]

@jordansissel gave me the idea with his xinput example.

I'm using Alt+d for minimize/restore hexchat with IceWM, but you can easily adopt the method to any other wm.

xpidfile=/dev/shm/hexchatkey-xinput.pid

icesh -c hexchat minimize 2>/dev/null && exit
xdotool mousemove --sync $(icesh xembed|sed -n '/Hexchat/ s/.*24x24+\([0-9]*\)+\([0-9]*\)/\1 \2/g p') click --clearmodifiers 1 mousemove restore
if xinput query-state 12|grep -q 'key\[64\]=up' ;then
   xdotool keyup Alt
   exit
fi
[ -f $xpidfile ] && exit
(xinput test 12 & echo $! >&3 ) 3>$xpidfile |
   while read line;do
      if [[ $line = 'key release 64' ]]; then
         xdotool keyup Alt
         kill -9 $(<$xpidfile)
      fi
   done
rm $xpidfile

Number 64 is the keycode for left Alt, so I release it on virtual keyboard just right after releasing on the physical.
Device 12 is the physical keyboard input - you shall modify it.

from xdotool.

chylex avatar chylex commented on July 2, 2024

Is there any way to get the keys unstuck when this happens, besides having to log out and losing all open programs?

from xdotool.

wavexx avatar wavexx commented on July 2, 2024

@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.

from xdotool.

chylex avatar chylex commented on July 2, 2024

@wavexx Doesn't work. I use xbindkeys to map shortcuts involving the Super key to F13-F24 using xdotool. If this causes the key to get stuck, then KDE Kickoff completely stops responding to the Super key, i.e. I cannot bring up the "start" menu anymore.

from xdotool.

wavexx avatar wavexx commented on July 2, 2024

@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.

from xdotool.

zevweiss avatar zevweiss commented on July 2, 2024

Is there any way to get the keys unstuck when this happens, besides having to log out and losing all open programs?

Maybe try switching to another VT (e.g. via control-alt-F2), logging in on the console and then running an xdotool keyup command or the like with an appropriate DISPLAY setting? Something like this, say:

$ DISPLAY=:0 xdotool keyup super

VT-switching keystrokes don't depend on X11, and hence should work regardless of what X thinks the state of the modifier keys is.

from xdotool.

ipaqmaster avatar ipaqmaster commented on July 2, 2024

for the moment I solved the issue by wrapping xdotool key --clearmodifiers in a simple script (based on @bbugyi200 solution):

#!/bin/sh -e
xdotool key --clearmodifiers $@
xdotool keyup Meta_L Meta_R Alt_L Alt_R Super_L Super_R

seems to work well without the delay, but I'm using this to emulate macos shortcuts on my i3 setup, so mileage may vary

Thanks for this. Putting this in a key function in my script seems to have stopped xdotool from leaving modifier keys held down when calling keys like ctrl+a and ctrl+shift+e - resulting in a 'seemingly' unresponsive X session when in reality there are phantom keys still being held down and sending keyups for them all makes the keyboard responsive in X again.

Despite having used --clearmodifiers with every invocation it seems to be forgetting to send the depress event for all the keys in a plus combo.

from xdotool.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.