pawelchcki / semicomplete

Automatically exported from code.google.com/p/semicomplete
0 stars 0 forks source link

current modifiers affect resulting key event (bug, feature, or just the way it works?) #6

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. $ sleep 2; xdotool key ctrl+o
2. Hold down alt when xdotool runs

What is the expected output? What do you see instead?
expected ^O   (ctrl+o)
instead  ^[^O (ctrl+alt+o)

(those keyseqs should get echo'ed to the terminal)

What version of the product are you using? On what operating system?
xdotool-r2197 on Arch Linux
xorg-server-1.6.1.901
bash-2.3.48
xterm-243 (with metaSendsEscape set)

Please provide any additional information below.

I'm trying to use xdotool to map and focus a window and then send ctrl+o to
it. This works from the shell, but when I bind a script to Alt+F2 in my
window manager, alt may still be held when xdotool sends the key, and it
ends up being ctrl+alt+o. If I send a 'keyup alt' before sending ctrl+o,
this works fine. But my concern is that now the user may still be holding
down alt, and may want to issue another alt binding. I might 'keydown alt'
after sending my key, but it may as well happen that the user releases alt
before that, so again, the modifier state in X would differ from the
physical state of the keyboard. If tested this setup, and it seems possible
that the user releases the modifier key between xdotool sending key ctrl+o
and sending keyup alt.

Maybe I'm missing something obvious, but it seems to me that it's
impossible to assure that a key send with xdotool will result in the exact
requested key while keeping the modifier state consistent with the physical
keyboard state. I'm aware that xdotool currently doesn't work or even claim
to work this way. But it would be great if it could do this, possibly as an
option, to help in scenarios like the above.

My knowledge of X event handling is rather limited, but wouldn't it be
possible to reset all current modifiers before sending a key, and after
that reset the modifier state to the current physical state of the keyboard?

Original issue reported on code.google.com by h.be...@googlemail.com on 23 Jun 2009 at 1:58

GoogleCodeExporter commented 9 years ago
Confirmed. There may be something we can do here, but it's likely to be hacky 
(and
that's probably OK).

Before we start sending keys with XTestFakeKeyEvent, we should look at the 
current
modifiers and attempt to clear them with fake release events (like faking an 
alt key
release) - this will need testing.

Alternately, xdotool key with a --window target should work. However, checking 
just
now shows the latest version of xdotool fails to do this correctly. Doing 
'xdotool
key --window <window> ctrl+o' only sends 'o' and with no control modifier set. 
I'll
fix that too.

Original comment by jls.semi...@gmail.com on 23 Jun 2009 at 2:48

GoogleCodeExporter commented 9 years ago

Original comment by jls.semi...@gmail.com on 1 Jul 2009 at 5:31

GoogleCodeExporter commented 9 years ago
This now works:
xdotool key --window <windowid> ctrl+shift+n

I tested by targeting gnome-terminal and sending 'ctrl+shift+n' and it popped 
up a
new terminal as expected.

I haven't fixed the other problem you described - when using 'xdotool key' with 
no
target, any active modifiers on the real keyboard are also part of sent keys 
from
xdotool. 

Original comment by jls.semi...@gmail.com on 1 Jul 2009 at 5:44

GoogleCodeExporter commented 9 years ago
That's definitely an improvement, and it'll work fine for my purpose, thanks 
alot!
I'll have to tell my users to AllowSendEvents for their terminals, though.

Concerning the remaining problem, I've looked into Xlib a little and found a 
way to
get the current state of a keycode via XQueryDeviceState. I've attached a small 
test
program that uses this method to query the state of a keycode. I think that 
using
this method it should be possible to:

1. Query the modifier state. If any modifier is held down that isn't requested,
disable it using a keyup.

2. Send the key, now in the requested modifier state.

3. Query the modifier state again and send the necessary events to make the 
logical
modifier state match the current state.

Note that I can barely write c, so I took an easy route in the test program 
(i.e.
simply getting the keyboard device by name).

I hope this can be helpful. If it isn't, please disregard. Unfortunately I 
don't know
enough C to try this method for xdotool myself.

Original comment by h.be...@googlemail.com on 1 Jul 2009 at 5:37

Attachments:

GoogleCodeExporter commented 9 years ago
This feature you propose (clear the modifier state temporarily) sounds like a 
good
hack to get around the problem you're having. I don't know if it should be the
default behavior (I have no preference) but both behaviors should be accessible 
with
a flag or somesuch.

Your code is a good start. I'll look at putting this into xdotool. Thanks a 
bunch for
the code sample :)  

Original comment by jls.semi...@gmail.com on 2 Jul 2009 at 2:38

GoogleCodeExporter commented 9 years ago
Similar with bekel's approach, I also suggest to clear all the pressed modifier 
keys
before send the key event in another post:
https://bugzilla.novell.com/show_bug.cgi?id=491282#c4

BTW, besides XQueryDeviceState. we can also query whether modifier keys are 
pressed
with XQueryKeymap or XQueryPointer.

Original comment by imguo...@gmail.com on 2 Jul 2009 at 7:14

GoogleCodeExporter commented 9 years ago
Clearing the modifiers only seems to be necessary when using XTEST. Sending a
keyboard event with XSendEvent allows you to explicitly set which modifiers are 
active.

I'll publish a new version with this fix when it's ready. Thanks for the 
details :)

Original comment by jls.semi...@gmail.com on 3 Jul 2009 at 2:58

GoogleCodeExporter commented 9 years ago
svn r2200 has fixes for xdotool type and key{up,down,} commands to allow you to 
clear
the active modifier mapping while xdo does it's thing.

% xdotool type --clearmodifiers "hello there"

While holding shift, the above should still type 'hello there'. Remove the
--clearmodifiers and the above should type 'HELLO THERE'

I'm going to test a bit more than push a new release.

Original comment by jls.semi...@gmail.com on 10 Jul 2009 at 7:46

GoogleCodeExporter commented 9 years ago
This works well for my original example, as well as modifiers ctrl and alt, but 
now

sleep 1; ./xdotool type --clearmodifiers "Hello World"

and holding down shift will produce inconsistent results, e.g.

HelLO WoRLD
HeLLO WORLD
etc

(This also happens without --clearmodifiers, so I'm not sure if it's related)

(r2204)

Original comment by h.be...@googlemail.com on 10 Jul 2009 at 8:58

GoogleCodeExporter commented 9 years ago
Weird. Can you run xev and hold shift when the xev window is focused? Your 
report
sounds like your shift key is repeating - xev's output will show you.

It's also possible there's some timing problem, but that seems on the unlikely 
side.

Let me know :)

Original comment by jls.semi...@gmail.com on 11 Jul 2009 at 12:22

GoogleCodeExporter commented 9 years ago
That was my first thought, too, but my shift key is fine, it doesn't repeat at 
all.
I've noticed that this doesn't happen if I run the above command with 
Shift-Return
and keep holding down Shift (in which case readline seems to ignore the shift 
and
just gets accept-line), i.e. the shift key is held throughout the sleep, too. 
Maybe
it's just because of using sleep beforehand, but I don't really have a clue 
here...

Original comment by h.be...@googlemail.com on 11 Jul 2009 at 9:44

GoogleCodeExporter commented 9 years ago
The clearmodifiers option would also be useful for button presses (and maybe 
even in
general for all inputs).  For instance, I'm using XMonad and trying to emulate 
mouse
button presses with the keyboard (because the mouse buttons on my laptop 
keyboard
stopped working), and I'd like to reuse the modifier key for XMonad, but it 
sends
both the modifier and the button click, when I only want the button click. 

Original comment by andrew.a...@gmail.com on 30 Jul 2009 at 4:39

GoogleCodeExporter commented 9 years ago
I'll see what I can do about clearing mouse buttons. Should be roughly the same 
hack
as clearing key modifiers.

Original comment by jls.semi...@gmail.com on 15 Aug 2009 at 11:48

GoogleCodeExporter commented 9 years ago
svn r2655 makes --clearmodifiers clear button states during typing and 'key' 
commands 
and restores them the same way buttons are restored.

Original comment by jls.semi...@gmail.com on 24 Feb 2010 at 5:44

GoogleCodeExporter commented 9 years ago
@h.bekel, Are you still seeing weird shift behavior?

Original comment by jls.semi...@gmail.com on 24 Feb 2010 at 5:44

GoogleCodeExporter commented 9 years ago
At least in r2660 I don't see weird shift behavior as described above any more.

Original comment by h.be...@googlemail.com on 25 Feb 2010 at 11:08

GoogleCodeExporter commented 9 years ago
Sweet. Thanks for confirming :)

New release should go out in a few days once I squash a few more bugs and 
feature 
requests.

Original comment by jls.semi...@gmail.com on 25 Feb 2010 at 5:08