Open ddast opened 6 years ago
Thank you for your report.
When diffing the xev
output, I notice that the main difference is that the K sent by pynput is SYNTHETIC, does not have a TIME, is not on the same screen as the ROOT window, and has an unset TIME.
pynput is able to pass all keys defined in Keys directly to XTest using fake_input
. For all other keys, this unfortunately does not work when supporting arbitrary keys.
Keyboard events are passed to XLib here. The event
parameter is one of the event classes listed here.
Perhaps you could try modifying the arguments? same_screen
sounds like it possibly should be set to a non-zero value?
Thank you for the pointers!
I played around a little bit with the arguments but no luck so far. same_screen=1
does change the property reported by xev but does not change the behaviour. Also I tried setting time=Xlib.X.CurrentTime
but this value is just zero, so this does not change anything.
I will probably have no time the next days but I will look into this at the weekend.
Note: The C library libxdo has the desired behaviour, so I will try to compare what is done there. Code for libxdo for reference:
#include <xdo.h>
int main()
{
xdo_t* xdo = xdo_new(NULL);
xdo_send_keysequence_window(xdo, CURRENTWINDOW, "Super+k", 12000);
xdo_free(xdo);
}
I did not succeed to fix this by changing the properties of the event.
I think the property SYNTHETIC is connected to using send_event since this is mentioned in the documentation of this function.
Setting TIME and the coordinates is possible but how to get the desired values I don't know. Nevertheless if the problem is due to one of these values it should be fixable in principle.
I mentioned libxdo in my last post since at first glance it looked like it also uses XSendEvent
. However, it is only used when the key is sent to a different window. In the other case it uses fake_input
.
You wrote that fake_input
does not work for arbitrary keys. I don't understand much of how keys are handled in X11, so the following might be nonsense. Is it correct that fake_input
only works for keys that have a keycode mapped to their keysym? This probably means that it can only be used for the keys that can actually be typed with the keyboard. Reading this function of libxdo
then could explain why it still works for (I think) arbitrary keys. It seems to map an unmapped keysym to an unused keycode.
This seems related to issue #4](https://github.com/moses-palmer/pynput/issues/4).
The problem is that the two different methods maintain different sets of active modifiers.
I noticed an additional problem with synthetic keys when using Gnome3. I am not able to type into the search window that opens with the super key since pynput will continue to write into the last focused window (even clicking into the search field does not change that). I think the problem is that get_input_focus() is still reporting this last focused window.
I'm currently trying to use fake_input
to avoid synthetic keys at all (see this commit). It is not finished, since in case of an KeyError
it still uses synthetc keys but in the other cases it works at least on my (german) keyboard layout. However, my understanding is that keyboard layouts are the tricky part so most likely this does not work in general.
Great to see work on this code!
Do you anticipate problems with your approach? By that I mean the extra sending of keyboard events, altering the global keyboard state and possibly causing applications listening to single modifier key presses to act.
I'm sorry for the late reply.
I don't think this approach sends more keyboard events than necessary but, to be honest, documentation is scarce and I'm far from sure whether this is the right way to do it.
My understanding is that this approach is pretty much the same as using the actual keyboard. This includes sending only a key press. As a result this key is continously typed as it would happen with the actual keyboard. If the pressed key uses a modifier this modifier also stays pressed. A pressed normal key is not much of a problem since typing another key on the actual keyboard seems to interreput this, but a pressed modifier key is not that easy to get rid of (withouth using pynput that is). I'm emphasizing this since the current implementation does not have this behaviour.
Then again what is the intended and expected behaviour when only a keypress is sent?
More problematic is the case of an unexpected termination of the program, since in this case the keyboard should not be left in a strange state, i.e., with some keys pressed.
Furthermore, I encountered a problem with dead keys. I don't understand why the joined key is only used for the keypress but not for the keyrelease. This leads to the keypress problem described above since a fitting keyrelease is missing. Hoewver, the problem is that this logic is not xorg specific but in the platform-independent part. I changed it naively in this commit and now dead keys seem to work too but I would like to hear what you think about this.
Hi, I am also having problems when trying to simulate a shortcut: CTRL + ALT + 0
I checked xev
output for real scenario and the one simulated by pynput and I found that the 0
key was also sent as synthetic YES
when simulating that.
I want to generate a shortcut system-wide, and currently it is only working if I focus the program I want to react to that shortcut.
Do you think it might be related?
Edit: Curious, I am also using i3wm
Setup: Arch Linux xorg-server 1.19.5 Window Manager: i3-wm
I recently started using pynput and I'm trying to type the combination Super+k with the following code
but it does not show the same behaviour as typing it.
To see the difference compared with typing Super+k on the keyboard I used xev:
Furthermore, I noticed that, e.g., using
pynput.keyboard.Key.up
instead of'k'
works as expected and other modifiers likepynput.keyboard.Key.ctrl
+'a'
do also work.If you need more information please let me know.