mooz / xkeysnail Goto Github PK
View Code? Open in Web Editor NEWYet another keyboard remapping tool for X environment
Yet another keyboard remapping tool for X environment
First of all, let me express my absolute gratitude for this package. I have been looking for something like this for the longest time and your package is absolutely amazing.
I am using the default configuration and I noticed that C-g
is bound to esc
followed by set_mark(False)
. This works as intended in most cases. However, in some cases this has undesirable effects. For example, in Firefox when editing the location bar if I select some text using C-SPC
then press C-g
to unset the mark, esc
is pressed which cancels all editing.
I would like to bound C-g
to set_mark(False)
if a mark is set and esc
otherwise. Or, if not possible, maybe bound C-g
to set_mark(False)
and C-g C-g
to esc
. Would that be doable?
Hey, Mr. mooz, I install xkeysnail
as what README guides, but I still could not set it up. There is an error I try sudo xkeysnail examples/config.py
:
Traceback (most recent call last):
File "/usr/local/bin/xkeysnail", line 6, in <module>
cli_main()
File "/usr/local/lib/python3.6/site-packages/xkeysnail/__init__.py", line 44, in cli_main
eval_file(args.config)
File "/usr/local/lib/python3.6/site-packages/xkeysnail/__init__.py", line 5, in eval_file
exec(compile(file.read(), path, 'exec'), globals())
File "config.py", line 4, in <module>
from xkeysnail.transform import *
File "/usr/local/lib/python3.6/site-packages/xkeysnail/transform.py", line 13, in <module>
def get_active_window_wm_class(display=Xlib.display.Display()):
File "/usr/local/lib/python3.6/site-packages/Xlib/display.py", line 89, in __init__
self.display = _BaseDisplay(display)
File "/usr/local/lib/python3.6/site-packages/Xlib/display.py", line 71, in __init__
protocol_display.Display.__init__(self, *args, **keys)
File "/usr/local/lib/python3.6/site-packages/Xlib/protocol/display.py", line 167, in __init__
raise error.DisplayConnectionError(self.display_name, r.reason)
Xlib.error.DisplayConnectionError: Can't connect to display ":0.0": b'No protocol specified\n'
Information about my OS:
Is there something wrong with my environment ?
I was thinking it could be very useful to have a cheatsheet like view while in an app.
Something along the lines of this app but instead of showing the original keymaps of the app have it parse through the xkeysnail python file for the current shortcut keys and maybe use any "# comment" either directly above or to the right of the key remap entry as the description.
https://mediaatelier.com/CheatSheet/
Would be interesting to combine it with the actual keymaps of the app as well, and simply overwrite the original if one is remapped.
I want to use muhenkan key as an extra modifier key like this:
muhenkan
+ (h
j
k
l
) -> left
down
up
right
Shift
+muhenkan
+ (h
j
k
l
) -> Shift
+ (left
down
up
right
)C
+muhenkan
+ (h
j
k
l
) -> C
+ (left
down
up
right
)M
+muhenkan
+ (h
j
k
l
) -> M
+ (left
down
up
right
)Super
+muhenkan
+ (h
j
k
l
) -> Super
+ (left
down
up
right
)It is impossible to write K("Muhenkan-h"): K("left")
. But if define_modmap()
receives a condition, the demand is satisfied.
For example (pseudo code):
define_modmap({
Key.H: Key.LEFT,
Key.J: Key.DOWN,
Key.K: Key.UP,
Key.L: Key.RIGHT,
}, condition=WHILE_MUHENKAN_PRESSED)
:)
Hi,
executing the command: "sudo xkeysnail config.py" results in (default config.py):
Traceback (most recent call last):
File "/usr/bin/xkeysnail", line 6, in
cli_main()
File "/usr/lib/python3.4/site-packages/xkeysnail/init.py", line 44, in cli_main
eval_file(args.config)
File "/usr/lib/python3.4/site-packages/xkeysnail/init.py", line 5, in eval_file
exec(compile(file.read(), path, 'exec'), globals())
File "config.py", line 84, in
K("C-M-space"): with_or_set_mark(K("C-right")),
NameError: name 'with_or_set_mark' is not defined
Mr. mooz , I just open an new issue to say thanks for your work and can't wait for xkeysnail, I am a big fan of the tools you build, including percol
,js2-mode
,and keysnail
.I am here to express my appreciation and how excited I am :)
Does this have support for a second keyboard? So it can tell the difference between the two
key down key up の処理を記述したい
key down -> KD()
key up -> KU()
のような、設定項目を追加できないでしょうか?
下記の設定の場合、
TAB
キーをダウンしている間は、A
を送信し続ける
TAB
キーをアップしたら、B
を送信
define_keymap(re.compile("Foo"), {
KD("TAB"): K("A"),
KU("TAB"): K("B"),
}, "Foo")
現在時刻の秒数が、偶数ならX、奇数ならY
など細かい制御を入れたいなと思っています
キーを押ししていると、XXXXXX... -> YYYYYY.... など
キーをアップせずに、途中で変えるのが目的です
下記の様に、設定したいです。
define_keymap(re.compile("Foo"), {
KD("TAB"): myFunc1(),
KU("TAB"): myFunc2(),
}, "Foo")
def myFunc1(self):
if (datetime.now().strftime("%S") % 2 == 0)
K('X')
return
K('Y')
def myFunc1(self):
if (datetime.now().strftime("%S") % 2 == 0)
K('A')
return
K('B')
Now, I know this isn't a bug, per se, but more of a lack of user fault tolerance. As a newish Linux user, as I was trying to find a way to make the process run in the background, I hit Ctrl-Z and it suspended the process. Little did I know at the time that meant everything stopped and didn't run in the background. Because everything stopped my keyboard and mouse ceased to function. I had no known way to resume the process or fully quit it, so I held down the power button to force a restart.
Is there a workaround or trick to avoid that if I accidentally do that again in the future? Maybe there's something I can include in the command to help?
I don't know if there is a possible solution based on the way this is currently implemented, but I would have expected that if the process was suspended, all keys go back to their original function. I'm very curious.
Side note: This is an awesome tool. I was fed up with Xmodmap and its complexity. I'm glad I found this.
Not working like this:
define_modmap({
Key.RIGHT_SHIFT: Key.LEFT_BRACE
})
I'm trying to remap multiple keyboards' keybinding in a background process. I found that the --device
option is suited in such a case. This option expects device file, e.g. /dev/input/event[:id].
However, this "id" file pattern changes every OS booting so that xkeysnail could not remap proper devices.
Is there any way to select "id" automatically from device name?
Start up script
#!/bin/bash
xkeysnail device.py --devices /dev/input/event2 &
pid=$!
trap "kill ${pid}" 2
# This is foreground process for experimental purposes
xkeysnail another_device.py --devices /dev/input/event5
Device Name mapping
❯ xkeysnail conf.py
:
Device Name Phys
------------------------------------------------------------------------------------
/dev/input/event2 AT Translated Set 2 keyboard isa0060/serio0/input0
/dev/input/event7 SEMITEK USB-HID Gaming Keyboard usb-0000:00:14.0-3.4/input0
# ^
# changed this time
Hello,
I have tried xkeysnail and works like a charm, however I could not find any link hint functionality like the HoK plugin of keysnail. Are there plans to implement that?
Martí
I am having a weird issue that I am trying to troubleshoot. Every once in a while, while running xkeysnail with the default config, the Ctrl key becomes stuck, in that all keys that I pressed are passed with a Ctrl modifier on all apps. After sometime (of me trying different combinations to unpress Ctrl), everything turns back to normal. I am sure that this is a problem with xkeysnail because I managed once to get to the terminal window that runs xkeysnail and pressed C
(which was coupled with the stuck Ctrl) and that killed xkeysnail and everything went back to normal.
Any ideas? Or perhaps some way to debug this?
In python, function call for default value is evaluated only once as the following:
$ python
Python 3.7.4 (default, Oct 13 2019, 09:39:19)
[GCC 7.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import random
>>> def f(x=random.random()):
... return x
...
>>> f()
0.5294147256361105
>>> f()
0.5294147256361105
https://github.com/mooz/xkeysnail/blob/master/xkeysnail/transform.py#L15 uses this parttern.
IMHO, the following code is more predictable (or, if what really you mean is evaluate every time, I recommend to write that code).
DEFAULT_DISPLAY = Xlib.display.Display()
def get_active_window_wm_class(display=DEFAULT_DISPLAY):
"""Get active window's WM_CLASS"""
Hi mooz, am trying out xkeysnail and am loving it. Thank you!
I'd like to know if there can be a setup where this could run in the background, as a daemon, rather than on the terminal which needs to be kept open? Is there already an option to do that? If not, perhaps some flag like: sudo xkeysnail -d config.py
to run it as a daemon in the background, with options to move it back to the foreground etc would be great!
Let me know your thoughts.
Thanks again.
In .xmodmap it is possible to define multiple layers that gives control over what symbol appears when using modifiers like Shift or AltGR. A good example of what this allows to do is the .xmodmap used by the german neo_de layout (see: https://neo-layout.org/index_en.html and https://neo-layout.org/neo_de.xmodmap).
Looking at the provided example and the code I don't see the ability to define multiple layers for an individual key. Is there a way to do this using xkeysnail that I am missing?
I wanted to use Control_R to emacs key-binds and Control_L to standard key-binds.
I modified the key.py like following and successfully realized what I wanted.
@classmethod
def _get_modifier_map(cls):
return {
# cls.CONTROL: {Key.LEFT_CTRL, Key.RIGHT_CTRL},
cls.CONTROL: {Key.RIGHT_CTRL},
cls.ALT: {Key.LEFT_ALT, Key.RIGHT_ALT},
.....
However, it will be better if we can specify right/left modifiers separately like: CR-a / CL-a, ShiftR-a/ShiftL-a, and so on.
When I unplug (or reset) my keyboard, xkeysnail first notices that the keyboard is gone and outputs:
Device removed: <my keyboard name>
But when the keyboard is re-attached, it doesn't add the keyboard back, and so I need to restart xkeysnail. Please allow xkeysnail to automatically add keyboards when they are plugged in.
Alt-shift doesn't work when xkeysnail runs. I've tried changing the shortcut with setxkbmap but it still doesn't work.
att, whats the escape char of -
Hi,
I help make Tridactyl and I recommend xkeysnail to our users for working around the fact that we can't rebind some keys (e.g, Ctrl-N).
I'd like to be able to use xkeysnail to rebind keys per-mode in Tridactyl, so that I can bind e.g, d
to Ctrl-W in Tridactyl's normal mode and then disable that bind in other modes, via e.g.
xkeysnail-remote --mode="normal"
<- d
bind activated
xkeysnail-remote --mode="insert"
<- d
bind deactivated
Is this something you'd be interested in adding? (Relevant-ish Tridactyl issue: tridactyl/tridactyl#359)
I'm keen to avoid people having to give sudo permissions to Tridactyl and I want to keep latency to a minimum (typing in a textbox and having the tab close would be lame), so I suspect killall xkeysnail; xkeysnail ignore.py
wouldn't be good enough.
Thanks.
Hi, thank you for this great product!
I have a problem, I made below config.py
as xkeysnail.py
import re
from xkeysnail.transform import *
def char_to_string_of_a_stroke(x):
return 'Shift-' + x.lower() if x.isupper() else x
def strokes(key_chars):
xs = list(key_chars)
xs = map(char_to_string_of_a_stroke, xs)
xs = map(K, xs)
return list(xs)
define_keymap(re.compile('Vivaldi-stable'), {
K('C-n'): strokes('gt'),
K('C-p'): strokes('gT'),
}, 'vivaldi')
and got
$ >>> sudo xkeysnail xkeysnail.py --devices /dev/input/event14
██╗ ██╗██╗ ██╗███████╗██╗ ██╗
╚██╗██╔╝██║ ██╔╝██╔════╝╚██╗ ██╔╝
╚███╔╝ █████╔╝ █████╗ ╚████╔╝
██╔██╗ ██╔═██╗ ██╔══╝ ╚██╔╝
██╔╝ ██╗██║ ██╗███████╗ ██║
╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═╝
███████╗███╗ ██╗ █████╗ ██╗██╗
██╔════╝████╗ ██║██╔══██╗██║██║
███████╗██╔██╗ ██║███████║██║██║
╚════██║██║╚██╗██║██╔══██║██║██║
███████║██║ ╚████║██║ ██║██║███████╗
╚══════╝╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝╚══════╝
v0.0.9
Traceback (most recent call last):
File "/bin/xkeysnail", line 6, in <module>
cli_main()
File "/usr/lib/python3.6/site-packages/xkeysnail/__init__.py", line 44, in cli_main
eval_file(args.config)
File "/usr/lib/python3.6/site-packages/xkeysnail/__init__.py", line 5, in eval_file
exec(compile(file.read(), path, 'exec'))
File "xkeysnail.py", line 16, in <module>
K('C-n'): strokes('gt'),
File "xkeysnail.py", line 11, in strokes
xs = map(char_to_string_of_a_stroke, xs)
NameError: name 'char_to_string_of_a_stroke' is not defined
Is my strokes
function supported ?
When trying to get emacs like key bindings in firefox the alt key is captured by firefox before xkeysnail. What follows is that every time you try to give (M-_) command the Firefox opens up some sort of file options menu and commands are lost in that.
Users should be informed this will happen because with this I can't really use xkeysnail for the main thing I wanted it for. I have run into this issue before with autohotkey on windows for example but I thought it might work under linux.
kozo2@kozo2-XPS-13-9343:~/Downloads/xkeysnail-master/example$ which python3
/usr/bin/python3
kozo2@kozo2-XPS-13-9343:~/Downloads/xkeysnail-master/example$ python3 -V
Python 3.6.6
kozo2@kozo2-XPS-13-9343:~/Downloads/xkeysnail-master/example$ python3 -m pip -V
pip 18.1 from /usr/local/lib/python3.6/dist-packages/pip (python 3.6)
kozo2@kozo2-XPS-13-9343:~/Downloads/xkeysnail-master/example$ python3 -m pip list
Package Version
--------------------- ---------
apturl 0.5.2
asn1crypto 0.24.0
Brlapi 0.6.6
certifi 2018.1.18
chardet 3.0.4
command-not-found 0.3
cryptography 2.1.4
cupshelpers 1.0
defer 1.0.6
distro-info 0.18
evdev 1.1.2
httplib2 0.9.2
idna 2.6
keyring 10.6.0
keyrings.alt 3.0
language-selector 0.1
launchpadlib 1.10.6
lazr.restfulclient 0.13.5
lazr.uri 1.0.3
louis 3.5.0
macaroonbakery 1.1.3
Mako 1.0.7
MarkupSafe 1.0
oauth 1.0.1
olefile 0.45.1
pexpect 4.2.1
Pillow 5.1.0
pip 18.1
protobuf 3.0.0
pycairo 1.16.2
pycrypto 2.6.1
pycups 1.9.73
pygobject 3.26.1
pymacaroons 0.13.0
PyNaCl 1.1.2
pyRFC3339 1.0
python-apt 1.6.3
python-debian 0.1.32
python-xlib 0.23
pytz 2018.3
pyxdg 0.25
PyYAML 3.12
reportlab 3.4.0
requests 2.18.4
requests-unixsocket 0.1.5
SecretStorage 2.3.1
setuptools 39.0.1
simplejson 3.13.2
six 1.11.0
system-service 0.3
systemd-python 234
ubuntu-drivers-common 0.0.0
ufw 0.35
unattended-upgrades 0.1
urllib3 1.22
usb-creator 0.3.3
wadllib 1.3.2
wheel 0.30.0
xkeysnail 0.1.0
xkit 0.0.0
zope.interface 4.3.2
kozo2@kozo2-XPS-13-9343:~/Downloads/xkeysnail-master/example$ which xkeysnail
/usr/local/bin/xkeysnail
kozo2@kozo2-XPS-13-9343:~/Downloads/xkeysnail-master/example$ sudo xkeysnail config.py
[sudo] password for kozo2:
██╗ ██╗██╗ ██╗███████╗██╗ ██╗
╚██╗██╔╝██║ ██╔╝██╔════╝╚██╗ ██╔╝
╚███╔╝ █████╔╝ █████╗ ╚████╔╝
██╔██╗ ██╔═██╗ ██╔══╝ ╚██╔╝
██╔╝ ██╗██║ ██╗███████╗ ██║
╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝ ╚═╝
███████╗███╗ ██╗ █████╗ ██╗██╗
██╔════╝████╗ ██║██╔══██╗██║██║
███████╗██╔██╗ ██║███████║██║██║
╚════██║██║╚██╗██║██╔══██║██║██║
███████║██║ ╚████║██║ ██║██║███████╗
╚══════╝╚═╝ ╚═══╝╚═╝ ╚═╝╚═╝╚══════╝
v0.1.0
Traceback (most recent call last):
File "/usr/local/bin/xkeysnail", line 6, in <module>
cli_main()
File "/usr/local/lib/python3.6/dist-packages/xkeysnail/__init__.py", line 44, in cli_main
eval_file(args.config)
File "/usr/local/lib/python3.6/dist-packages/xkeysnail/__init__.py", line 5, in eval_file
exec(compile(file.read(), path, 'exec'), globals())
File "config.py", line 4, in <module>
from xkeysnail.transform import *
File "/usr/local/lib/python3.6/dist-packages/xkeysnail/transform.py", line 13, in <module>
def get_active_window_wm_class(display=Xlib.display.Display()):
File "/usr/local/lib/python3.6/dist-packages/Xlib/display.py", line 89, in __init__
self.display = _BaseDisplay(display)
File "/usr/local/lib/python3.6/dist-packages/Xlib/display.py", line 71, in __init__
protocol_display.Display.__init__(self, *args, **keys)
File "/usr/local/lib/python3.6/dist-packages/Xlib/protocol/display.py", line 167, in __init__
raise error.DisplayConnectionError(self.display_name, r.reason)
Xlib.error.DisplayConnectionError: Can't connect to display ":0": b'No protocol specified\n'
kozo2@kozo2-XPS-13-9343:~/Downloads/xkeysnail-master/example$ cat config.py
# -*- coding: utf-8 -*-
import re
from xkeysnail.transform import *
# [Global modemap] Change modifier keys as in xmodmap
define_modmap({
Key.CAPSLOCK: Key.LEFT_CTRL
})
# [Conditional modmap] Change modifier keys in certain applications
define_conditional_modmap(re.compile(r'Emacs'), {
Key.RIGHT_CTRL: Key.ESC,
})
# [Multipurpose modmap] Give a key two meanings. A normal key when pressed and
# released, and a modifier key when held down with another key. See Xcape,
# Carabiner and caps2esc for ideas and concept.
define_multipurpose_modmap(
# Enter is enter when pressed and released. Control when held down.
{Key.ENTER: [Key.ENTER, Key.RIGHT_CTRL]}
# Capslock is escape when pressed and released. Control when held down.
# {Key.CAPSLOCK: [Key.ESC, Key.LEFT_CTRL]
# To use this example, you can't remap capslock with define_modmap.
)
# Keybindings for Firefox/Chrome
define_keymap(re.compile("Firefox|Google-chrome"), {
# Ctrl+Alt+j/k to switch next/previous tab
K("C-M-j"): K("C-TAB"),
K("C-M-k"): K("C-Shift-TAB"),
# Type C-j to focus to the content
K("C-j"): K("C-f6"),
# very naive "Edit in editor" feature (just an example)
K("C-o"): [K("C-a"), K("C-c"), launch(["gedit"]), sleep(0.5), K("C-v")]
}, "Firefox and Chrome")
kozo2@kozo2-XPS-13-9343:~/Downloads/xkeysnail-master/example$
I use the EXWM window manager, for example, if you have this config:
define_keymap(lambda wm_class: wm_class not in ("Emacs",), {
# C-x YYY
K("C-x"): {
# C-x C-f (open)
K("C-f"): K("C-o"),
# C-x C-s (save)
K("C-s"): K("C-s"),
# C-x k (kill tab)
K("k"): K("C-f4"),
# C-x C-c (exit)
K("C-c"): K("C-q"),
}
}, "Emacs-like keys")
Press C-x b, the combination is not sent to the window manager, and we have to set it explicitly
define_keymap(lambda wm_class: wm_class not in ("Emacs",), {
# C-x YYY
K("C-x"): {
K("b"): [K("C-x"), K("b")],
}
}, "Emacs-like keys")
Why not make all not specified key bindings just send themselves default?
Hi, last years i can't use emacs-style key bindings without this - https://gitlab.com/at-home-modifier/at-home-modifier-evdev/wikis/home
With this utility my "space" sends Ctrl keycode when pressed with another key (so, space+b == ctrl+b for example). But seems like this is not working with keysnail. It seeing space+b as space and b, not like ctrl-b. Is it possible to fix it, or add similiar functionality to xkeysnail?
Is this supported on the MAC platform?
I run several different Java based applications, and for all of these, xkeysnail reports the WM_CLASS as 'FocusProxy' rather than the correct application specific WM_CLASS that gets reported by xprop WM_CLASS
on that window.
For example, xkeysnail output when over JetBrains IntelliJ IDE:
WM_CLASS 'FocusProxy' | active keymaps = []
and xprop on that window gives:
$ xprop WM_CLASS
WM_CLASS(STRING) = "sun-awt-X11-XFramePeer", "jetbrains-idea-ce"
This makes it impossible to have different bindings for the different applications.
Autokey apparently also has a similar problem with Java apps: autokey/autokey#113
I use setxkbmap to remap Caps_lock as Ctrl (setxkbmap -option ctrl:nocaps
). However, this does not work if I use xkeysnail.
So, how can I do setxkbmap's work in xkeysnail? Or, is there any workaround?
Hey Mr. Mooz, I have a werid issue. As title, sometimes when I just stop typing for a while, xkeysnail will say:
Device removed: SIGMACHIP USB Keyboard
But my USE keyboard hasn't been removed, then xkeysnail just doesn't work. So I just restart xkeysnail, and it works again. I have no idea how to sovle this issue!
Environment information:
OS: Arch Linux
WM: i3wm
Given that xkeysnail watches hot-plug keyboards I'd think implementing something that triggers a refresh/reload of the currently used config file for xkeysnail would be easy enough to implement.
I am starting to use xkeysnail
instead of setxkbmap
and xbindkeys
. I really appreciate your work, but there is one potential bug that is blocking my way:
I want to bind PRINT_SCREEN
key to launch my script and take a screenshot, configured as below:
define_keymap(None, {
K("SYSRQ"): launch(["screenshot"])
}, "Global")
However instead of invoking the program, my keyboard got removed and I had to switch to another keyboard to stop the program. Please see logs below:
WM_CLASS 'URxvt' | active keymaps = [Global]
SYSRQ
Device removed: Topre Corporation HHKB Professional
Is it a bug of xkeysnail
, or a stupid error in my config file?
Thanks!
> sudo xkeysnail config.py
Traceback (most recent call last):
File "/usr/bin/xkeysnail", line 6, in <module>
cli_main()
File "/usr/lib/python3.6/site-packages/xkeysnail/__init__.py", line 34, in cli_main
if not has_access_to_uinput():
File "/usr/lib/python3.6/site-packages/xkeysnail/__init__.py", line 11, in
has_access_to_uinput from xkeysnail.output import _uinput
File "/usr/lib/python3.6/site-packages/xkeysnail/output.py", line 10, in <module>
_uinput = UInput()
File "/usr/lib/python3.6/site-packages/evdev/uinput.py", line 129, in __init__
self.fd = _uinput.open(devnode)
OSError: could not open uinput device in write mode
Tested on ArchLinux.
Random rant: The sad thing is, I'm trying to replace xkeysnail and Firefox with cVim and Chromium, but Chromium is stubborn in keeping the shortcuts to himself.
I run
xkeysnail config.py
where config.py is the one from the examples folder. I'm added to the input and uinput group, so that I don't need to run it as root.
It crashes, printing the following stacktrace:
[...] (omitted)
Okay, now enable remapping on the following device(s):
-------------------------------------------------------------------------------------
Device Name Phys
-------------------------------------------------------------------------------------
/dev/input/event3 Logitech USB Keyboard usb-0000:00:14.0-2/input0
/dev/input/event5 Corsair Corsair K70R Gaming Keyboard usb-0000:00:1a.0-1.5/input0
/dev/input/event8 Corsair Corsair K70R Gaming Keyboard usb-0000:00:1a.0-1.5/input2
Traceback (most recent call last):
File "/usr/bin/xkeysnail", line 6, in <module>
cli_main()
File "/usr/lib/python3.4/site-packages/xkeysnail/__init__.py", line 48, in cli_main
loop(select_device(args.devices))
File "/usr/lib/python3.4/site-packages/xkeysnail/input.py", line 89, in loop
on_event(event, device.name)
File "/usr/lib/python3.4/site-packages/xkeysnail/transform.py", line 261, in on_event
if len(signature(condition).parameters) == 2:
File "/usr/lib64/python3.4/inspect.py", line 2063, in signature
return _signature_internal(obj)
File "/usr/lib64/python3.4/inspect.py", line 1965, in _signature_internal
skip_bound_arg=skip_bound_arg)
File "/usr/lib64/python3.4/inspect.py", line 1890, in _signature_from_builtin
raise ValueError("no signature found for builtin {!r}".format(func))
ValueError: no signature found for builtin <built-in method search of _sre.SRE_Pattern object at 0x7fb303281e00>
Please tell me if I need to provide additional debugging information.
Edit:
Seems to be a python 3.4 problem. Works flawlessly with python 3.6
I try to configure Ctrl
+j
to be left arrow key (LEFT
). To do this I apply this configuration:
from xkeysnail.transform import *
define_keymap(None, {
K("C-j"): (K("left")),
})
It works fine, but when I want to generate Shift
+Left
, I press Ctrl
+Shift
+j
, but Shift
is not transfering - only LEFT
is written.
I'm trying to run xkeysnail as a systemd service. However, xkeysnail outputs key events to stdout to be logged to systemd journald. It would be nice to have some options like -q
/ --quiet
to suppress key activities when running as a daemon. Or suppressing key activities by default and adding another option like -v
/ --verbose
would also work.
From systemd point of view, StandardOutput=null
to the unit file works though.
$ sudo systemctl status xkeysnail
● xkeysnail.service - Service for xkeysnail
Loaded: loaded (/etc/systemd/system/xkeysnail.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2018-06-24 17:34:43 JST; 3min 33s ago
Main PID: 5116 (xkeysnail)
Tasks: 1 (limit: 4915)
CGroup: /system.slice/xkeysnail.service
└─5116 /usr/bin/python3 /usr/local/bin/xkeysnail /etc/xkeysnail/config.py
Jun 24 17:37:17 lifebook xkeysnail[5116]: WM_CLASS 'Gnome-terminal' | active keymaps = []
Jun 24 17:37:17 lifebook xkeysnail[5116]: G
Jun 24 17:37:17 lifebook xkeysnail[5116]: WM_CLASS 'Gnome-terminal' | active keymaps = []
Jun 24 17:37:17 lifebook xkeysnail[5116]: I
Jun 24 17:37:17 lifebook xkeysnail[5116]: WM_CLASS 'Gnome-terminal' | active keymaps = []
Jun 24 17:37:17 lifebook xkeysnail[5116]: T
Jun 24 17:37:17 lifebook xkeysnail[5116]: WM_CLASS 'Gnome-terminal' | active keymaps = []
Jun 24 17:37:17 lifebook xkeysnail[5116]: SPACE
Current press alone and press together with other keys are different.
The not cover use case: user intends to press a key combination, and the modifier is pressed first, then user changes mind, and abort the operation, the modifier is released, but the key corresponding to press alone is sent by mistake.
The correct behavior is: if the single modifier is pressed longer than the elapsed time, don't do anything.
It's over 1 year since xkeysnail has been released to PyPI. Latest xkeysnail got many features like --watch, --quiet. Advices written in README is not applicable to released version. Why not release a new version, say 0.1.1?
I would like to define xkeysnail transformations that just apply to certain keyboards (e.g different depending on whether using laptop built-in vs external keyboard).
define_conditional_modmap()
already lets us create a modmap that can be controlled by a condition that includes the device_name
It would be great if we had define_conditional_multipurpose_modmap()
so that multipurpose modmaps could similarly be controlled by a condition.
So in firefox, the extra Alt always bring the menu bar up.
I have confirmed this through a lot of testing that xkeysnail releases the held down modifier once a standard key has been pressed and released instead of also keeping the modifier (possibly remapped modifier) held until the original modifier is released. I have been trying to go through the code to understand where I might be able to modify the K function to support holding down the modifier keys until they are truly released, but I have not been able to find this thus far.
There are three very common modifiers used under Linux (and other OS's too) that require this ability if there is any hope to properly remap them - Alt-Tab, Ctrl-Tab and Super-Tab.
During my testing I am wondering if the evdev library xkeysnail uses could be the limitation or how evtest operates even. They show the modifier keys repeating input up until another key is pressed then they become quiet - however they have never emitted a release signal (for the modifier until it is physically released), so in that context my assumption is the key is still being held and should be visible to the underlying OS, but perhaps that is not true or xkeysnail is somehow sending the modifier again on top of itself. I can't seem to verify that xkeysnail is doing that though with evtest or via "python -m evdev.evtest".
From what I can tell it behaves more like the modifier is being released with the combo of whatever other key is released and then the modifier is repeated if the key is pressed again. This is based on observation inside Sublime Text and opened files. It changes tabs as though I am tapping both keys but not holding down Ctrl - which causes it to only change between 2 files instead of all files.
Possible Workaround
If it is not possible to remap to a totally different modifier key while listening to the original's release signal then can we possibly just pass the modifier key through only while still remapping a destination key? That could also satisfy what I am after.
Here is an example of my script that is failing to work. The Ctrl+Alt+G to Alt+F3 remap works as long as an F row key is not used. I think this may be a bug of some sort in xkeysnail? There is not conditional set on it at the moment so I could test with xbindkeys -mk.
I've commented out the other parts of my script that don't really matter. (Still does not work when ran.)
# -*- coding: utf-8 -*-
import re
from xkeysnail.transform import *
# [Global modemap] Change modifier keys as in xmodmap
# define_modmap({
# Key.LEFT_ALT: Key.LEFT_CTRL,
# Key.LEFT_CTRL: Key.LEFT_ALT,
# })
# [Conditional modmap] Change modifier keys in certain applications
# define_conditional_modmap(re.compile("Gnome-terminal|konsole|io.elementary.terminal|terminator|sakura|guake|tilda|xterm|eterm|kitty"), {
# Key.LEFT_ALT: Key.LEFT_META,
# Key.LEFT_META: Key.LEFT_ALT,
# })
# Keybindings for Sublime Text
# re.compile("Sublime_text")
define_keymap(None,{
# Select All Matches
K("M-C-g"): K("M-f3"),
}, "Sublime_text")
I want to run some scripts with xkeysnail but don't know how.
xkbsetというbounceなどを指定できるツールがあります.
Linux(X11)でキーボードのチャタリングをGnomeなどのアクセシビリティツールを使わずに抑止するにはxkbsetを使う - ncaq
この設定をxkeysnailは何故か消去してしまいます.
2019-04-24T12:08:20 ncaq@indigo/pts/0(0) ~/Desktop
% xkbset bouncekeys 50
2019-04-24T12:09:09 ncaq@indigo/pts/0(0) ~/Desktop
% xkbset q|rg Bounce
Bounce-Keys = On
Beep if Slow/Bounce-Keys about to be turned off = On
Beep on Bounce-Key Reject = On
2019-04-24T12:09:16 ncaq@indigo/pts/0(0) ~/Desktop
% systemctl --user restart xkeysnail.service
2019-04-24T12:09:31 ncaq@indigo/pts/0(0) ~/Desktop
% xkbset q|rg Bounce
Bounce-Keys = Off
Beep if Slow/Bounce-Keys about to be turned off = On
Beep on Bounce-Key Reject = On
ならばxkeysnailをxkbsetの後に起動すれば良いのかと思うのですがそうもいかなくて,
何故かxkbsetを起動していると私の以下の設定が効かなくなります.
define_keymap(re.compile("Slack|discord"), {
# j
K("M-c"): [K("M-Down")],
K("C-M-c"): [K("C-M-Down")],
# k
K("M-v"): [K("M-Up")],
K("C-M-v"): [K("C-M-Up")],
}, "Slack and Discord switch channel")
デバッガ使って原因を探ってみましたが原因不明でした.
ひとまず諦めてissueだけ立てておきます.
I need to remap my second spacebar, which is recognized as MENU key to HYPER (or SUPER). In xmodmap I use keycode 135 = Hyper_R
. Since xmodmap doesn't work with xkeysnail, is it possible to do this in define_modmap
?
Hi there!
This is a great package. One issue I've noticed though is that keyboard repeat rates are changed when using py-evdev-uinput
. For example, normally when I press and hold down "a", I get a lot of repeating A's. With xkeysnail, though, there's a noticeable delay from when the repetitions start happening.
Using the utility xset -q
, I can see that my initial settings are:
auto repeat delay: 200 repeat rate: 62
But with xkeysnail it gets set to:
auto repeat delay: 660 repeat rate: 25
.
The workaround for me right now is to set it manually after starting xkeysnail using xset r rate 200 62
.
There should be a way to set the repeat rate in evdev with a specific KbdInfo, but I haven't as of yet gotten it to work.
I'll try looking into it more.
Thanks again for this useful software!
It seems we have to specify keys seeing english keyboard's layout.
It will be better if it can specify the keyboard layout information and use the key notations as it is.
Anyway, it's a great tool. Thank you.
This is a nit picking, but there is a tag named as "HEAD" which gives a warning in git.
$ git clone https://github.com/mooz/xkeysnail.git
$ cd xkeysnail/
$ git status
warning: refname 'HEAD' is ambiguous.
warning: refname 'HEAD' is ambiguous.
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean
$ git tag
HEAD
Breaking changes in xkeysnail 0.3.0.
The behavior is very different when you operate the keyboard in the following order.
press Ctrl
press Alt
release Ctrl
press W
xkeysnail 0.2.0: perform Alt-w
xkeysnail 0.3.0: perform w
This behavior is especially problematic when you are operating Emacs.
I perform C-SPC
→ C-e
→ M-w
.
When performing an operation such as, I have to be careful not to release the Ctrl key before hitting the Alt key but w
will be typed.
I think this breaking change because
Release mapped modifiers after the original is released. closes #70. by rbreaves - Pull Request #71 - mooz/xkeysnail
I'm not sure why this change was necessary in the first place when I look at the issue.
I'd like to ask @rbreaves what his intentions were in making the change to fix the disruptive change while maintaining the significance of the change.
original strings
xkeysnail 0.3.0の破壊的変更について.
以下の順にキーボードを操作したとき動作が大きく異なります.
press Ctrl
press Alt
release Ctrl
press w
xkeysnail 0.2.0: perform Alt-w
xkeysnail 0.3.0: perform w
この動作は特にEmacsを操作している時に問題になります.
C-SPC
→ C-e
→ M-w
のような操作をした時に,
Altキーを押す前にCtrlキーを離さないように慎重に気をつけないとw
が入力されてしまいます.
私はこの破壊的変更が
Release mapped modifiers after the original is released. Closes #70. by rbreaves · Pull Request #71 · mooz/xkeysnail
によって引き起こされたと思っていますが,
そもそもこの変更が何故必要だったのかissueを見てもよく分かりませんでした.
この変更の意義を保ったまま破壊的変更を修正するために @rbreaves に変更の意図を聞きたいです.
I tried running xkeysnail with --watch and plugged in a keyboard, but nothing happened.
After some easy debugging, I found that at plugging in a keyboard, add_new_devices()
is called properly and getting event.name
is ok, but no code after new_device = InputDevice("/dev/input/" + event.name)
is not working.
My environment is as below.
Ubuntu: 16.0.4
xkeysnail: 0.1.0
python: 3.6.4
pip: 19.0.3
Thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.