Open zw963 opened 2 years ago
We're literally generating input on a keyboard device... I think you may want to file this upstream as a bug with Gnome and see what they say...
Yes, this issue still exits since i last use xkeysnail, i leave it because this issue too, because i use on my laptop, if no disable-while-typing
feature, my cursor always jump on anywhere in screen, it annoy.
after disable it, disable-while-typing
work well.
Please file this upstream as a bug against Gnome and then link us to that and I'd be happy to have a discussion with the Gnome people and see what the options might be (if any)...
I have a feeling it's something only Gnome can fix (or tell us how)... either they count input from uinput as keyboard input, or perhaps there is a flag we need to set on the device to make them see it as a "keyboard worthy of note"... but only they would know.
I create a issue here.
https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5530
though, don't sure if correct place.
All that gnome does with this setting is forward it to libinput, which is what actually handles ignoring the events.
Sounds like now you're off to file a report against libinput and see what they say. :)
Create a new issue here.
https://gitlab.freedesktop.org/libinput/libinput/-/issues/778
Related: https://gitlab.freedesktop.org/libinput/libinput/-/issues/727
The answer over on libinput seems highly relevant. This is something we could probably fix in the future. We need to either:
This is made more complex by the fact that some users may be mapping MULTIPLE real keyboards onto a single virtual output keyboard - not all of them internal... so the trackpad should be disabled only for SOME inputs but not others.
Until then I'd suggest reading the linked issue and trying what it suggests with local-overrides.quirks
to tell it the keyboard that we're generating is internal, not external and see if that helps. If so please report back here.
Or if you're comfortable hacking the source you could try changing the constructor on output.py#27
, see the UInput constructor in evdev:
def __init__(self,
events=None,
name='py-evdev-uinput',
vendor=0x1, product=0x1, version=0x1, bustype=0x3,
evnode='/dev/uinput', phys='py-evdev-uinput', input_props=None):
You'd want to try passing the same vendor/product/version/bus as your existing internal hardware keyboard. Sorry I'm not 100% sure where you get all those numbers. lsusb
should help with the vendor/product IDs... Bustype 3 (the default) us USB - not sure if that would need to change... I'd start with just vendor/product ID and see how far that gets you.
Or if you're comfortable hacking the source you could try changing the constructor on
output.py#27
, see the UInput constructor in evdev:
Sorry, could not find same code in this file in git version or 0.4.0 package install version.
I guess following tree device is about keyboard, touchpad and Mouse.
/dev/input/event4: AT Translated Set 2 keyboard (BUS_I8042)
/dev/input/event8: 04CA00B1:00 04CA:00B1 Touchpad (BUS_I2C)
/dev/input/event9: 04CA00B1:00 04CA:00B1 Mouse (BUS_I2C)
If there is info needed? @joshgoebel
Thank you.
could not find same code in this file in git version or 0.4.0 package install
It's in the keysnail directory... https://github.com/mooz/xkeysnail/blob/master/xkeysnail/output.py
could not find same code in this file in git version or 0.4.0 package install
It's in the keysnail directory... https://github.com/mooz/xkeysnail/blob/master/xkeysnail/output.py
Sorry, where is the python constructor? please see following screenshot.
UInput constructor on line 30...
UInput constructor on line 30...
Sorry, still don't know what you means, i am not clear to change what for which file ...
If I knew exactly what to do I'd show you, but I'd have to figure it out myself... the constructor is on line 30...
_uinput = UInput( ... )
if you Google the evdev Python docs you should see what arguments the constructor wants, how to pass configuration information to it such that is pretends to be a different type of keyboard, etc...
At that point you'd have to play with it... if that's all greek to you then you're probably not going to make progress here and will have to wait for someone else to come along to asist.
If I knew exactly what to do I'd show you, but I'd have to figure it out myself... the constructor is on line 30...
_uinput = UInput( ... )
if you Google the evdev Python docs you should see what arguments the constructor wants, how to pass configuration information to it such that is pretends to be a different type of keyboard, etc...
At that point you'd have to play with it... if that's all greek to you then you're probably not going to make progress here and will have to wait for someone else to come along to asist.
Sorry, i guess i have ability to do this, but, i don't know what you means exactly where to do those changes.
UInput constructor on line 30...
This should be which file, which line?
What ever evdev/uinput.py:30
, or xkeysnail/output.py:27
, none of them, i can see code like this: _uinput = UInput( ... )
please check following screenshot.
https://github.com/mooz/xkeysnail/blob/master/xkeysnail/output.py#L30
It's right there, line 30.
Following is my interal keyboard " AT Translated Set 2 keyboard (BUS_I8042)" info, which use
/dev/input/event3: AT Translated Set 2 keyboard (BUS_I8042)
╰─ $ udevadm info --query=property --name=/dev/input/event3
DEVPATH=/devices/platform/i8042/serio0/input/input3/event3
DEVNAME=/dev/input/event3
MAJOR=13
MINOR=67
SUBSYSTEM=input
USEC_INITIALIZED=8899367
KEYBOARD_KEY_81=f20
KEYBOARD_KEY_89=battery
KEYBOARD_KEY_8a=screenlock
KEYBOARD_KEY_8b=camera
KEYBOARD_KEY_8c=media
KEYBOARD_KEY_8e=dvd
KEYBOARD_KEY_92=brightnessdown
KEYBOARD_KEY_97=brightnessup
KEYBOARD_KEY_b1=help
KEYBOARD_KEY_b3=unknown
KEYBOARD_KEY_d7=wlan
KEYBOARD_KEY_ee=switchvideomode
KEYBOARD_KEY_f8=wlan
ID_INPUT=1
ID_INPUT_KEY=1
ID_INPUT_KEYBOARD=1
ID_BUS=i8042
ID_SERIAL=noserial
ID_PATH=platform-i8042-serio-0
ID_PATH_TAG=platform-i8042-serio-0
LIBINPUT_DEVICE_GROUP=11/1/1:isa0060/serio0
DEVLINKS=/dev/input/by-path/platform-i8042-serio-0-event-kbd
TAGS=:power-switch:
CURRENT_TAGS=:power-switch:
╰─ $ 130 xinput
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ MOSART Semi. wireless dongle Consumer Control id=11 [slave pointer (2)]
⎜ ↳ SynPS/2 Synaptics TouchPad id=17 [slave pointer (2)]
⎜ ↳ MOSART Semi. wireless dongle Mouse id=13 [slave pointer (2)]
⎜ ↳ PS/2 Generic Mouse id=16 [slave pointer (2)]
⎣ Virtual core keyboard id=3 [master keyboard (2)]
↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)]
↳ Power Button id=6 [slave keyboard (3)]
↳ Video Bus id=8 [slave keyboard (3)]
↳ Sleep Button id=9 [slave keyboard (3)]
↳ MOSART Semi. wireless dongle id=10 [slave keyboard (3)]
↳ MOSART Semi. wireless dongle System Control id=12 [slave keyboard (3)]
↳ HP HD Webcam: HP HD Webcam id=14 [slave keyboard (3)]
↳ Wireless hotkeys id=18 [slave keyboard (3)]
↳ MOSART Semi. wireless dongle Consumer Control id=20 [slave keyboard (3)]
↳ Video Bus id=7 [slave keyboard (3)]
↳ HP WMI hotkeys id=19 [slave keyboard (3)]
↳ AT Translated Set 2 keyboard id=15 [slave keyboard (3)]
It seem like not recognize my internal keyboard as usb device. because sudo usb-devices
not include it.
@zw963 Try this (and post info here):
import evdev
device = evdev.InputDevice("/dev/input/event3")
device.phys
device.info.vendor
device.info.product
device.info.version
device.info.bustype
device.input_props()
Then try copying all those details into the new UInput device... see an example here:
What they are doing automatically you are just wanting to do by hand... and see if it helps... Or if you're familiar enough with Python you could try just hacking it to manually copy from your keyboard device (as I show you at the top of this message).
It might be all you need is phys and bustype, I'm not really sure... one thing I read said that it just needs to think the keyboard is internal, which should happen if you switch the bustype to PS/2 (maybe?).
If you manage to get it working we can see about adding this "cloning" functionality, but we'd need a way to specify WHICH keyboard to clone since technically a user can have LOTS of keyboards... and for people with more than 1 there might not be a correct answer - but I'm not sure we could solve that.
Following is my output result:
import evdev
# this is my interal keyboard device
device = evdev.InputDevice("/dev/input/event3")
print(device.phys)
print(device.info.vendor)
print(device.info.product)
print(device.info.version)
print(device.info.bustype)
print(device.input_props())
isa0060/serio0/input0
1
1
43841
17
[]
Then i change code in xkeysnail/output.py#L30
to: please see following screenshot.
Could you please check to ensure i do correct changes?
Thank you very much.
BTW: i run above same python script on my two different laptop, one hp zbook, one lg gram, even, one use Xorg, another use Wayland, and different event device, but all get exact same value, why?
And, both laptop install latest arch linux + GNOME, but, one xorg, another wayland.
Looks right, did it help any? Is xkeysnail being started BEFORE the desktop environment or after?
Looks right, did it help any? Is xkeysnail being started BEFORE the desktop environment or after?
i use a user systemd file, correct?
[Unit]
Description=xkeysnail
[Service]
# Environment=DISPLAY=:0
# ExecStartPre=-xhost +SI:localuser:root
ExecStart=/home/zw963/utils/xkeysnail/bin/xkeysnail -q --watch /home/zw963/utils/xkeysnail/config.py
Type=simple
Restart=always
RestartSec=2
[Install]
WantedBy=graphical.target
Hmmm... so it's needed by the graphics target, but does it load first? I don't know - also not sure if that matters...
Okay, thank you very much, i will testt this config in recent days, will report here
I have to change to following to make xkeysnail start to work
_uinput = UInput(events={ecodes.EV_KEY: _keyboard_codes,
ecodes.EV_REL: set([0,1,6,8,9]),
},
name="mykeyboarddevice",
phys="isa0060/serio0/input0",
vendor=1,
product=1,
version=43841,
bustype=17,
input_props=[])
Now, service is started.
● xkeysnail.service - xkeysnail
Loaded: loaded (/home/zw963/.config/systemd/user/xkeysnail.service; disabled; vendor preset: enabled)
Active: active (running) since Tue 2022-06-07 18:12:16 CST; 4s ago
Main PID: 70172 (xkeysnail)
Tasks: 2 (limit: 28477)
Memory: 14.2M
CPU: 143ms
CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/xkeysnail.service
├─70172 /bin/sh /home/zw963/utils/xkeysnail/bin/xkeysnail -q --watch /home/zw963/utils/xkeysnail/config.py
└─70183 python /home/zw963/utils/xkeysnail/bin/..//bin.real/xkeysnail -q --watch /home/zw963/utils/xkeysnail/config.py
Jun 07 18:12:16 lggram systemd[1087]: Started xkeysnail.
Jun 07 18:12:16 lggram sudo[70175]: pam_systemd_home(sudo:account): systemd-homed is not available: Unit dbus-org.freedesktop.home1.service not found.
Jun 07 18:12:16 lggram sudo[70175]: zw963 : PWD=/home/zw963 ; USER=root ; COMMAND=/usr/sbin/chmod 0666 /dev/input/event0 /dev/input/event1 /dev/input/event10 /dev/input/event11 /dev/input/event12 /dev/input/event13 /dev/input/event14 /dev/input/event>
Jun 07 18:12:16 lggram sudo[70175]: pam_unix(sudo:session): session opened for user root(uid=0) by (uid=1000)
Jun 07 18:12:16 lggram sudo[70175]: pam_unix(sudo:session): session closed for user root
@joshgoebel , could you please give me some clue about how to make xkeysnail start when system is boot?
current the issue is, i use a user systemd, after reboot, it start failed because
Jun 07 19:44:07 lggram xkeysnail[3645]: ██╗ ██╗██╗ ██╗███████╗██╗ ██╗
Jun 07 19:44:07 lggram xkeysnail[3645]: ╚██╗██╔╝██║ ██╔╝██╔════╝╚██╗ ██╔╝
Jun 07 19:44:07 lggram xkeysnail[3645]: ╚███╔╝ █████╔╝ █████╗ ╚████╔╝
Jun 07 19:44:07 lggram xkeysnail[3645]: ██╔██╗ ██╔═██╗ ██╔══╝ ╚██╔╝
Jun 07 19:44:07 lggram xkeysnail[3645]: ██╔╝ ██╗██║ ██╗███████╗ ██║
Jun 07 19:44:07 lggram xkeysnail[3645]: ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═╝
Jun 07 19:44:07 lggram xkeysnail[3645]: ███████╗███╗ ██╗ █████╗ ██╗██╗
Jun 07 19:44:07 lggram xkeysnail[3645]: ██╔════╝████╗ ██║██╔══██╗██║██║
Jun 07 19:44:07 lggram xkeysnail[3645]: ███████╗██╔██╗ ██║███████║██║██║
Jun 07 19:44:07 lggram xkeysnail[3645]: ╚════██║██║╚██╗██║██╔══██║██║██║
Jun 07 19:44:07 lggram xkeysnail[3645]: ███████║██║ ╚████║██║ ██║██║███████╗
Jun 07 19:44:07 lggram xkeysnail[3645]: ╚══════╝╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝╚══════╝
Jun 07 19:44:07 lggram xkeysnail[3645]: v0.4.0
Jun 07 19:44:07 lggram xkeysnail[3645]: Failed to open `uinput` in write mode.
Jun 07 19:44:07 lggram xkeysnail[3645]: Make sure that you have executed xkeysnail with root privilege such as
Jun 07 19:44:07 lggram xkeysnail[3645]: $ sudo xkeysnail config.py
Jun 07 19:44:07 lggram systemd[878]: xkeysnail.service: Main process exited, code=exited, status=1/FAILURE
Jun 07 19:44:07 lggram systemd[878]: xkeysnail.service: Failed with result 'exit-code'.
Jun 07 19:44:09 lggram systemd[878]: xkeysnail.service: Scheduled restart job, restart counter is at 2.
Jun 07 19:44:09 lggram systemd[878]: Stopped xkeysnail.
Jun 07 19:44:09 lggram systemd[878]: Starting xkeysnail...
Jun 07 19:44:09 lggram xhost[3646]: localuser:root being added to access control list
Jun 07 19:44:09 lggram systemd[878]: Started xkeysnail.
Yes, i consider this is a file permission issue, so, i have to wrap xkeysnail use another bash wrapper script, and run following command before really run xkeysnail.
sudo chmod 0666 /dev/input/event* /dev/uinput
But, this bash wrapper script could not start correct because possible sudo , it not work, get above error.
But, i can correct up manually use systemctl --user start xkeysnail
after user login.
Following is my systemd file
[Unit]
Description=xkeysnail
[Service]
# DISPLAY 的值应该和 `echo $DISPLAY` 的值相同
# Environment=DISPLAY=:0
# ExecStartPre=-xhost +SI:localuser:root
# ExecStartPre=-
ExecStart=/home/zw963/utils/xkeysnail/bin/xkeysnail -q --watch /home/zw963/utils/xkeysnail/config.py
Type=simple
Restart=always
RestartSec=2
[Install]
WantedBy=multi-user.target
sudo chmod 0666 /dev/input/event* /dev/uinput
I would not recommend that.
I think optimally the best way to do this is to let udev
do it for you... and I'd recommend running as a user in an input group, NOT yourself, and not root... but sadly this is a part of things I haven't had much time to play with yet - developing the library (my fork) it's definitely easier to just fire it up as myself and run it in a window... I suspect after it's a bit more stable though this will change and I'll use a systemd service running as a semi-privileged (non-root) user.
I'll probably have more to say here next week. I believe I've just gotten my fork to the point where it's usable so pretty soon I'll be figuring out solid ideas on how people SHOULD run it...
I have to change to following to make xkeysnail start to work
Did making those changes indeed help with your Gnome ignore input issue or is the jury still out?
In fact, my $USER is a member of input, and /dev/uinput group is input too, but still not start correct, but, whatever, i start it my my ~/.profile, only once, it works anyway, thank you very much.
Did making those changes indeed help with your Gnome ignore input issue or is the jury still out?
i just try to use it in my another laptop very few time yesterday, it seem like fixed, but i still need more time to ensure this.
In fact, my $USER is a member of input, and /dev/uinput group is input too
I don't recommend that either - that allows any software on your computer to potentially log all your keystrokes, passwords, emails, etc... there is a reason users don't usually have access to the raw input devices.
but still not start correct,
If Failed to open 'uinput' in write mode.
is the error you're getting it definitely means at the time the service is running it does not have proper permission to uinput...
@joshgoebel , Hi, though, recent days, because busy, not used to much my another laptop for test this issue, but, i think this hack works! because, if not do this hack, my another laptop (big touchpad LGRAM 17) will skip almost make people crazy. but it not since a enable this hack.
Thank you very much for you help, so, when we will fix this in xkeysnail?
Thank you very much for you help, so, when we will fix this in xkeysnail?
Possibly never. For all intents and purposes xkeysnail seems effectively unmaintained. I am however the maintainer of the fork/reboot keyszer... so if you wanted to open an issue against that project (and link back here).... I think there is definitely room for something like this long-term... a "masquerade as" option... I wouldn't say it's a super high priority though.
However, I think my fork actually has the hook you would need to fix this from just your config file... look at output.py
... it exports a setup_uinput
function... this is used so that the test suite can inject a mock... BUT you could use that to pass your own custom UInput instance... something like:
my_uinput = UInput(events={ecodes.EV_KEY: _keyboard_codes,
ecodes.EV_REL: set([0,1,6,8,9]),
},
name="mykeyboarddevice",
phys="isa0060/serio0/input0",
vendor=1,
product=1,
version=43841,
bustype=17,
input_props=[])
from keyszer.output import setup_uinput
setup_uinput(my_uinput)
Just put that at the top of your config and I think it might work. It's still a bit early but I've been using my fork 24/7 for several days... there are still some unresolved issues ( you may want to look thru them)... if you'd like to give it a shot, feel free. You can install it from pypi
now... I just published 0.5.0 today.
You'd obviously have to import ecodes
and include the code for _keyboard_codes
also... so yes, it's a little ugly... if you open an issue we could talk about how to do it nicer.
When enable xkeysnail, following GNOME settings will become invalid.
this feature very useful for user who use laptop which exists a big touchpad, and user use laptop keyboard typing directly.