Code Monkey home page Code Monkey logo

keyd's Introduction

Kofi

Impetus

Packaging status

Linux lacks a good key remapping solution. In order to achieve satisfactory results a medley of tools need to be employed (e.g xcape, xmodmap) with the end result often being tethered to a specified environment (X11). keyd attempts to solve this problem by providing a flexible system wide daemon which remaps keys using kernel level input primitives (evdev, uinput).

Note on v2

The config format has undergone several iterations since the first release. For those migrating their configs from v1 it is best to reread the man page.

See also: changelog.

Goals

  • Speed (a hand tuned input loop written in C that takes <<1ms)
  • Simplicity (a config format that is intuitive)
  • Consistency (modifiers that play nicely with layers by default)
  • Modularity (a UNIXy core extensible through the use of an IPC mechanism)

Features

keyd has several unique features many of which are traditionally only found in custom keyboard firmware like QMK as well as some which are unique to keyd.

Some of the more interesting ones include:

  • Layers (with support for hybrid modifiers).
  • Key overloading (different behaviour on tap/hold).
  • Keyboard specific configuration.
  • Instantaneous remapping (no more flashing :)).
  • A client-server model that facilitates scripting and display server agnostic application remapping. (Currently ships with support for X, sway, and gnome (wayland)).
  • System wide config (works in a VT).
  • First class support for modifier overloading.
  • Unicode support.

keyd is for people who:

  • Would like to experiment with custom layers (i.e custom shift keys) and oneshot modifiers.
  • Want to have multiple keyboards with different layouts on the same machine.
  • Want to be able to remap C-1 without breaking modifier semantics.
  • Want a keyboard config format which is easy to grok.
  • Like tiny daemons that adhere to the Unix philosophy.
  • Want to put the control and escape keys where God intended.
  • Wish to be able to switch to a VT to debug something without breaking their keymap.

What keyd isn't:

  • A tool for programming individual key up/down events.

Dependencies

  • Your favourite C compiler
  • Linux kernel headers (already present on most systems)

Optional

  • python (for application specific remapping)
  • python-xlib (only for X support)
  • dbus-python (only for KDE support)

Installation

Note: master serves as the development branch, things may occasionally break between releases. Releases are tagged, and should be considered stable.

From Source

git clone https://github.com/rvaiya/keyd
cd keyd
make && sudo make install
sudo systemctl enable keyd && sudo systemctl start keyd

Quickstart

  1. Install and start keyd (e.g sudo systemctl enable keyd)

  2. Put the following in /etc/keyd/default.conf:

[ids]

*

[main]

# Maps capslock to escape when pressed and control when held.
capslock = overload(control, esc)

# Remaps the escape key to capslock
esc = capslock

Key names can be obtained by using the keyd monitor command. Note that while keyd is running, the output of this command will correspond to keyd's output. The original input events can be seen by first stopping keyd and then running the command. See the man page for more details.

  1. Run sudo keyd reload to reload the config set.

  2. See the man page (man keyd) for a more comprehensive description.

Config errors will appear in the log output and can be accessed in the usual way using your system's service manager (e.g sudo journalctl -eu keyd).

Note: It is possible to render your machine unusable with a bad config file. Should you find yourself in this position, the special key sequence backspace+escape+enter should cause keyd to terminate.

Some mice (e.g the Logitech MX Master) are capable of emitting keys and are consequently matched by the wildcard id. It may be necessary to explicitly blacklist these.

Application Specific Remapping (experimental)

  • Add yourself to the keyd group:

    usermod -aG keyd <user>

  • Populate ~/.config/keyd/app.conf:

E.G

[alacritty]

alt.] = macro(C-g n)
alt.[ = macro(C-g p)

[chromium]

alt.[ = C-S-tab
alt.] = macro(C-tab)
  • Run:

    keyd-application-mapper

You will probably want to put keyd-application-mapper -d somewhere in your display server initialization logic (e.g ~/.xinitrc) unless you are running Gnome.

See the man page for more details.

SBC support

Experimental support for single board computers (SBCs) via usb-gadget has been added courtesy of Giorgi Chavchanidze.

See usb-gadget.md for details.

Packages

Third party packages for the some distributions also exist. If you wish to add yours to the list please file a PR. These are kindly maintained by community members, no personal responsibility is taken for them.

Alpine Linux

keyd package maintained by @jirutka.

Arch

Arch Linux package maintained by Arch packagers.

Debian

Experimental keyd and keyd-application-mapper packages can be found in the CI build artifacts of the work-in-progress Debian package repository:

Any Debian Developer who is willing to review the debianization effort and sponsor its upload is encouraged to contact @rhansen (also see the Debian ITP bug).

Fedora

COPR package maintained by @alternateved.

openSUSE

opensuse package maintained by @bubbleguuum.

Easy install with sudo zypper in keyd.

Ubuntu

Experimental keyd and keyd-application-mapper packages can be found in the ppa:keyd-team/ppa archive.

If you wish to help maintain this PPA, please contact @rhansen.

Sample Config

[ids]

*

[main]

leftshift = oneshot(shift)
capslock = overload(symbols, esc)

[symbols]

d = ~
f = /
...

Recommended config

Many users will probably not be interested in taking full advantage of keyd. For those who seek simple quality of life improvements I can recommend the following config:

[ids]

*

[main]

shift = oneshot(shift)
meta = oneshot(meta)
control = oneshot(control)

leftalt = oneshot(alt)
rightalt = oneshot(altgr)

capslock = overload(control, esc)
insert = S-insert

This overloads the capslock key to function as both escape (when tapped) and control (when held) and remaps all modifiers to 'oneshot' keys. Thus to produce the letter A you can now simply tap shift and then a instead of having to hold it. Finally it remaps insert to S-insert (paste on X11).

FAQS

What about xmodmap/setxkbmap/*?

xmodmap and friends are display server level tools with limited functionality. keyd is a system level solution which implements advanced features like layering and oneshot modifiers. While some X tools offer similar functionality I am not aware of anything that is as flexible as keyd.

What about kmonad?

keyd was written several years ago to allow me to easily experiment with different layouts on my growing keyboard collection. At the time kmonad did not exist and custom keyboard firmware like QMK (which inspired keyd) was the only way to get comparable features. I became aware of kmonad after having published keyd. While kmonad is a fine project with similar goals, it takes a different approach and has a different design philosophy.

Notably keyd was written entirely in C with performance and simplicitly in mind and will likely never be as configurable as kmonad (which is extensible in Haskell). Having said that, it supplies (in the author's opinion) the most valuable features in less than 2000 lines of C while providing a simple language agnostic config format.

Why doesn't keyd implement feature X?

If you feel something is missing or find a bug you are welcome to file an issue on github. keyd has a minimalist (but sane) design philosophy which intentionally omits certain features (e.g execing arbitrary executables as root). Things which already exist in custom keyboard firmware like QMK are good candidates for inclusion.

Contributing

See CONTRIBUTING. IRC Channel: #keyd on oftc

keyd's People

Contributors

ainola avatar alternateved avatar briceburg avatar canadaduane avatar cblock avatar codelongandprosper90 avatar echawk avatar env25 avatar gkbd avatar halimnaim avatar herrsimon avatar heyzec avatar jbeich avatar jirutka avatar joihn avatar jsr-p avatar ljden avatar loops avatar mamg22 avatar mateuszwieloch avatar matthiasgrandl avatar maxgyver83 avatar nazya avatar raploz avatar rhansen avatar rvaiya avatar simoneruffini avatar tchajed avatar tkna91 avatar webern avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

keyd's Issues

[Usage Question] Possibility to use this to simulate mac-like keyboard function?

I know this would be possible to use to swap the modifier keys, but in terms of the way those keys change when interacting with certain applications (i.e, terminals), is that something that's within the scope of this project? Or is that something that's going to be limited to display servers? Basically can this project do something similar to Kinto?

Use plaintext uncompressed man pages (`.1` not `.1.gz`)

Man pages don't need to be compressed the work the same as long as they are installed to somewhere in $MANPATH.

Most software in my experience always deal with plaintext uncompressed man pages. The man page compression is always done by distro packagers.

It will also be better because git won't need to deal with binary files.

This should be simple to fix by amending the Makefile. I can make a PR if you agree.

Freebsd support

FreeBSD is one of the few (only?) BSDs that implement evdev and uinput. It may be possible to port keyd to it with minimal (no?) changes. If anyone has success compiling and running it please post here. I might this give this a go later.

Unable to bind PrintScreen and ISO Extra Key ( / | ) for UK Layout

Having some trouble binding these two keys. My config is

pageup = home
pagedown = prtsc
rightshift = \

The Pageup key is changed correctly, but Pagedown has no effect. Curiously, it does type a Tilde if I press it while in a terminal. I couldn't see PrtSc mentioned anywhere in the keyd -l command, is it not usable?

And as for the Right Shift bind, my keyboard is set to UK Layout in my system settings, which seems to make the backslash key register as the Hash/Tilde key instead. I tried binding the key to Hash to see how that would affect things, and then it would only print a pound sign.
The binding works on Windows using SharpKeys, and it names the key I have it bound to as "ISO Extra Key 00_56". Any way I could bind that key properly as well?

Interaction between modifier, layer, and parent layer triggers parent incorrectly

When I create a layer triggered on leftalt, with a parent layout as modifier 'M', with key mappings that trigger leftalt-* combinations, I get a strange effect where the original parent layer ('M' in this case) is triggered in addition to the A-1 or A-2 keys:

leftalt = layer(macmeta)

[macmeta:M]
1 = A-1
2 = A-2

When I run keyd -m I see that there are indeed multiple keydown and keyup events--the meta key goes down/up, then alt goes down and 1 goes down, then alt goes up. (Note that only Alt-1 is being pressed physically):

keyd virtual keyboard: meta down
keyd virtual keyboard: meta up
keyd virtual keyboard: alt down
keyd virtual keyboard: 1 down
^[1keyd virtual keyboard: alt up
keyd virtual keyboard: 1 up

I'm going to reboot and see if anything changes, but I wanted to leave this here in case the data has value in replication for anyone else.

keyd disables mouse buttons

Hi, I was using keyd successfully for a long time now, but it started disabling mouse buttons.

Config

# Turns capslock into an escape key when pressed and a control key when held.
capslock = overload(M, esc)

Env

OS: Arch Linux - rolling
keyd version:

pacman -Q keyd-git                                                                                     
keyd-git 1.1.2.r14.95e1d89-1

Mouse HW: Logitech MX Master 3 (doesn't work with neither bluetooth nor unifying receiver)

sudo keyd -m and clicking with the mouse

sudo keyd -m  
keyd: src/main.c:764: evdev_monitor_loop: Assertion `keycode_table[ev.code].name' failed.
[1]    8299 abort      sudo keyd -m

SpaceFN is a bit too slow

First of all: as a user with a QMK keyboard that also has to regularly type on a laptop your keyd is a blessing.

As a diehard vim guy I quickly was able to translate the most important stuff of my qmk setup to keyd:

# Turns capslock into an escape key when pressed and a control key when held.
capslock = overload(C, esc)

# Remaps the escape key to capslock
# esc = capslock

# space when tapped, spacefn when held
space = overload(spacefn, space)
tab = overload(tabfn, tab)

[spacefn]
h = left
j = down
k = up
l = right

[tabfn]
h = home
j = pagedown
k = pageup
l = end
  • caps as ctrl/esc works like a charm, bye xcape
  • initial tests with SpaceFn and TabFn work: nice, bye xmodmap+setxkbmap

Then I started to write an email and realizedthatthespace keyddoesnt work asreliable :/
My typing speed is non-spectacular (75-80 wpm according to monkeytype.com) but a space doesnt come through two thirds of the time.

Is there anything I can do to make this more accurate? Did I configure something wrong?

Appreciation for keyd

Just installed keyd and used it to remap home to delete, because my keyboard manufacturer thinks that one is more important than the other. And it only took me 2 minutes. -- ImJustPassinBy

I use keyd for everything and love it! -- that1communist

I have been having a play with keyd today and it's really neat... It's making the capslock key, which has been mapped to esc as a default for vim, into a much more versatile key triggering the different modes and using esc to return to the main mapping. Super simple configuration and potential to be open the keyboard up a bit without having to buy a Planck just yet. -- textandmetal

Assign left <, >

When I try to reassign < and >, keyd only considers the buttons located at , and . and not the buttons located at the left of my z key.

keyd -m reports AT Translated Set 2 keyboard: 102nd down/up for this button.

Is there a way to use the numeric code for assignment?

Macro Repetitions

Hi

The keys remapped to a macro( .. ) are triggered once per press and do not get repeated as normal keys when the key sequence is held down.

To reproduce:

leftshift = macro(xx)

Pressing and holding leftshift will print "xx" only once and will never repeat.

Expected behavior:

Repeating is expected by default.

In case of macros (IMHO) repeating the whole macro would be logical, also by default.

Would be nice to be able to control in config:

  • toggle repeating for a key,
  • for macros set key sequence (or sequences) to be repeated.

Thanks for a great piece of software!


P.S. I'm not suggesting a specific syntax here as I both do not have the feel for it yet and I did not dive into the implementation (yet)...

Update Readme

In the Readme, Recommended Config where you have capslock = overload(esc, C) I actually had to switch it to capslock = overload(C, esc) to get it to work! Just wanted to let you know

"Stuck" oneshot layer

Sometimes keyd gets "stuck" on an oneshot layer. This causes every key press to have the stuck oneshot layer applied to
it. This problem is reproducible with the following config:

# Makes the shift key sticky for one keystroke.
leftshift = oneshot(S)
rightshift = oneshot(S)

To trigger the stuck state, the following can be done:

  1. Hold down left shift and right shift
  2. Press any letter on the keyboard once
  3. Release left shift and right shift

Now every key press will have the shift modifier applied which looks like caps lock is enabled. To get out of the stuck
state either left shift or right shift has to be pressed again.

This stuck effect is not specific to left and right shift. I have managed to trigger this effect on oneshot mappings for
AltGr aswell sometimes. However, I only found left shift and right shift to consistently trigger this effect for me.

So I would guess, that there is some issue when two oneshot layers are triggered at the same time or with a small time difference to each other.

Tested with keyd version: 1.1.2 (8131320)

f keys

i want to remap F1 to esc because my escape key is broken but F1 = esc doesnt work

What if `keyd` used libinput?

Hot off the heels of #66... :)

I'm curious if you've considered using libinput rather than interfacing directly with evdev? I know this would imply a large rewrite of some key parts of the code, but for the sake of imagining possibilities, perhaps we could consider it just for a moment?

(This is also related to linuxtouchpad discussion -- the last question in particular, "should key remappers be implemented at the same level as touchpad remappers (like Touchégg and Gebaar)?")

  1. I learned recently about how gesture remappers like gebaar and Touchegg are similar to key remappers. I've diagrammed the "overview" from the perspective of a touchpad here (the idea is exactly the same for keyboards). In essence, instead of opening evdev file descriptors directly, gesture remappers have to rely on libinput to detect the gestures before they can be remapped. Then, the next layer in the stack opens their "virtual device" and uses that input instead of the "real" device.
  2. libinput handles keyboard events, mouse events, touchpad events, touch screen events, and tablet events. These events are all at a fairly "low level" in the sense that there is some normalization going on, but not a lot of interpretation. And yet, it seems like input devices generally are often related--sometimes multiple kernel devices are the same physical device, and sometimes two or more devices interact. In fact, #42 and #66 are sort of proof of how they are related in sometimes surprising ways.
  3. libinput is now used almost universally in X.Org (Xserver) and Wayland compositors (Weston, mutter, KWin). The one place it may not be universal is in text terminals.

So there are clearly some benefits to using libinput as a source of events, at least at the boundary around something like keyd:

  1. You get some normalization for free (for example if combining a keyboard with a mouse--libinput has a hardware database that provides accel curves and other benefits to make mice behave)
  2. You get beneficial device interactions for free (e.g. touchpad "disable while typing")
  3. You get support for both major graphical desktop systems (granted, this is true of evdev too)
  4. You can start to piece together advanced remapping scenarios where gestures and keys combine to make other possibilities (imagine "Ctrl + 3-finger-swipe right" for instance).

So I guess I'm just spitballing a bit here, but am I missing anything important? Let's say keyd 3.0 uses libinput and we're all done. Is it a net improvement?

Config is only applied sometimes.

Hello, I am running version 1.1.2 and my config is:

capslock = overload(arrows, esc)

[arrows:main]
h = left
j = down
k = up
l = right

But this config seems to only be applied sometimes.
The config is stored in '/etc/keyd/AT Translated Set 2 keyboard.cfg' and the device name is AT Translated Set 2 keyboard.

When the config is applied properly the logs are:

-- Boot 9322d9a7267e4abfacc26c60cd9beb1f --
ago 29 16:36:21 amos systemd[1]: Started key remapping daemon.
ago 29 16:36:21 amos keyd[366]: Starting keyd v1.1.2 (8df75b749b9131faeb551c84efebca9762047649).
ago 29 16:36:22 amos keyd[366]: Managing AT Translated Set 2 keyboard

Otherwise they are:

-- Boot a83ee4fbd1ad4e1d8866ad2c8c2dedd7 --
ago 29 16:38:45 amos systemd[1]: Started key remapping daemon.
ago 29 16:38:45 amos keyd[365]: Starting keyd v1.1.2 (8df75b749b9131faeb551c84efebca9762047649).

Restarting the daemon fixes part of the problem.
While the capslock is pressed the arrows layer is available, but when it is tapped, it does not work like escape.

The logs are:

-- Boot a83ee4fbd1ad4e1d8866ad2c8c2dedd7 --
ago 29 16:38:45 amos systemd[1]: Started key remapping daemon.
ago 29 16:38:45 amos keyd[365]: Starting keyd v1.1.2 (8df75b749b9131faeb551c84efebca9762047649).
ago 29 16:45:08 amos keyd[365]: SIGTERM received, cleaning up and terminating...
ago 29 16:45:08 amos systemd[1]: Stopping key remapping daemon...
ago 29 16:45:09 amos systemd[1]: keyd.service: Deactivated successfully.
ago 29 16:45:09 amos systemd[1]: Stopped key remapping daemon.
ago 29 16:45:09 amos systemd[1]: Started key remapping daemon.
ago 29 16:45:09 amos keyd[3378]: Starting keyd v1.1.2 (8df75b749b9131faeb551c84efebca9762047649).
ago 29 16:45:09 amos keyd[3378]: Managing AT Translated Set 2 keyboard

Do you know how to fix this issue?

Thank you for your amazing work.

Does not compile

~/repos/keyd (master|✔) [2] ▶ make
mkdir -p bin
cc -DVERSION=\"1.1.2\" -DGIT_COMMIT_HASH=\"231e3ebd1cb58607e21952a0ab93030970d22010\" -DCONFIG_DIR=\""/etc/keyd"\" -DLOG_FILE=\""/var/log/keyd.log"\" -DLOCK_FILE=\""/var/lock/keyd.lock"\" -I/usr/local/include -L/usr/local/lib -O3 src/*.c -o bin/keyd -ludev
src/main.c: In function ‘monitor_exit’:
src/main.c:827:26: error: parameter name omitted
  827 | static void monitor_exit(int)
      |                          ^~~

It looks like a parameter name is missing for monitor_exit.

Line comments in kbd config files

Add ability to comment a line, maybe ';' or '//' ?

  • It would be nice during testing to be able to comment out a line
  • Actual comments above a line or section would be helpful for future readers

App Specific Bindings

I'm curious if there's interest in supporting getting the current active window, and automatically switching to different keyboard layers.

A simple use case: VSCode uses Ctrl+, as the "preferences" shortcut key, but Firefox uses "Alt+e, n" (and can't be configured without a special plugin). I'd like to unify this behavior so that Ctrl+, always gets me to preferences.

Two other key remapping tools accomplish this in X11: xkeysnail and autokey. Unfortunately, they both do not support Wayland.

It turns out that in Wayland, getting the "current active window" is not supported. Instead, they punt on it and ask that a layer above handles that task, e.g. at gnome-shell:

gdbus call --session \
  --dest org.gnome.Shell \
  --object-path /org/gnome/Shell \
  --method org.gnome.Shell.Eval "global.display.focus_window.get_wm_class()"

It may also be possible to write a dbus listener that gets notified of window focus changes in gnome. That seems like it could be a separate project--one that perhaps ties in to keyd. Perhaps such a daemon could tap into each of the major shells/window managers and report the necessary information?

I think the "key remapping community" is in need of a solution here, because in general, I don't think it has been solved.

dead keys / compose keys

Is it possible to have dead and compose keys (e.g. AltGr+[ for ¨ to create characters like ü etc.) with keyd? The compose option does not seem to do this.

(I could probably create a new layer, but then I think that such characters are not available?!)

Can i remap mouse buttons now?

Hey man. Been using keyd for about a month now and have zero (no) complains, works like a charm.
I see you've added mouse button support? How can I use this?

I have had this ugly dirthack in my i3 config for years, that triggers xdotool key f5 when i press forward button (btn 5?) and xdotool key backspace on backbutton. Would be awesome if that could be configured with keyd instead.

Could you give me an example on how this can be done, if it can be done?

Also, this is kind of related. Back when i was using windows i had this Autohotkey script that made the left and right buttons act kind of like the overload function. So holding f.i. right mousebutton and scrolling would send control+PageUp/Down. It was amazing, is that possible with keyd, maybe, please ;)

Here is my old mouse remapping script:
https://gist.github.com/budRich/6044613

I also had stuff like tripple click and double click right/middle button for copy,paste and enter. good times.

Keep up the awesome work!

Use \t to separate monitor output?

I know you just said that hopefully the output format wouldn't change, but ... since it's so fresh, perhaps I can suggest this?

What if we use tab ("\t") to separate the three fields? I think it would be easier to parse.

So this:

AT Translated Set 2 keyboard(0001:0001): a down
AT Translated Set 2 keyboard(0001:0001): a up

Would become:

AT Translated Set 2 keyboard     0001:0001       a down
AT Translated Set 2 keyboard     0001:0001       a up

This solves several potential problems:

  1. It's possible to have parens in keyboard names
  2. The : (colon) separator is no longer ambiguous
  3. "\t" should be a "safe" separator character
  4. It's easier to use a separator than create a regex to pull info out of a line

keyd and russian layout

Hello, I use dvp and russian layout.

keyd didn't work with setxkbmap -option ctrl:nocaps -option grp:win_space_toggle us,ru -variant dvp,typewriter

I disable dvp and create dvp in default.cfg:

layout(dvorak)

[mylayer]
; = $
a = 0
s = 1
d = 2
f = 3
q = $
z = grave
w = 7
e = 8
r = 9
x = 4
c = 5
v = 6

[dvorak]
meta = meta
space = space
rightalt = layer(mylayer)
leftalt = leftcontrol
compose = compose
esc = esc
capslock = leftalt
leftcontrol = leftalt
rightcontrol = rightcontrol
leftshift = leftshift
rightshift = rightshift
enter = enter
tab = tab
backspace = backspace
up = up
down = down
left = left
right = right
mode = mode
q = semicolon
w = comma
e = dot
r = p
t = y
y = f
u = g
i = c
#....etc

after I chose Russian setxkbmap -option grp:win_space_toggle us,ru -variant ,typewriterwith , keymap use old (US). How implement Russian in cfg and change layout without setxkbmap? Only keyd?

Question about generating custom keysims

Hi,

I have the following settings in my xkbmap:

clear mod1
keycode 108 = Mode_switch
keycode 64 = Super_L
keysym e = e E EuroSign
keysym c = c C cent
keysym w = w W adiaeresis Adiaeresis
keysym o = o O odiaeresis Odiaeresis
keysym u = u U udiaeresis Udiaeresis
keysym r = r R ssharp
keysym q = q Q acircumflex Acircumflex
keysym a = a A abreve Abreve
keysym s = s S U0219 U0218
keysym t = t T U021B U021A
keysym i = i I U00EE U00CE

and I've tried using keyd to generate the same:

rightalt = layer(dia)

[dia]
r = ß
u = ü
o = ö
e = €
...etc...

As I understand I cannot use r = G-r and so on because keyd resets all the xkbmap mappings. is it possible to generate these keysims with keyd? perhaps via a macro calling xdotool or something like that?

Thanks.

Create an FAQ

It seems like it's absolutely worth spending all my efforts and I'd have loved to find this nice tool a long time ago right now, but at least for today, I've run into some problems that I cannot resolve easily and could not find solutions in the documentation. Probably some FAQ would help.

Additionally to the previous issues reported, I have the following two issues that I could not figure yet.

First: keyd overwrites the keys I have defined in my compositor (and it does not - as I had imagined at first - work in a way that it would only change the keys that I assign in /etc/keyd/* and leave the rest be). I've yet to exactly figure out how to apply setxkbmap or other options on top, or how to re-configure them.

Second (could be more abstract, but I'd like to show the use case here also): I have meta+shift+2 assigned in my compositor, and I've also assigned S-2 = " in keyd. keyd seems to take priority, i.e. I receive " instead of moving my current window to another tag when pressing meta+shift+2. Do I have to define another symbol for this combination, or even do something like M-S-" = 2?

(Second point five: when I have G-2 and S-2 assigned, which one takes priority?)

Support for modifying timings?

Hello, first of all, thanks for the project, it steps up the usability and automation scene in Linux a lot!

I was wondering if it would be possible to add support to configure the timings that keyd uses in order to consider when a key is held or not.

There's a similar tool for MacOS called Karabiner, and it let's you configure the following parameters:

:alone   80 ; hold for .. ms to register single tap
:held    50 ; If it has been held for this time and no other simultaneous key has been pressed, it considers this as a tap 
:delay   0  ; time after which the key press is delayed
:sim     30 ; keys need to be pressed within this threshold to be considered simultaneous

I'm trying to migrate my MacOS workflow to my Linux machine, but currently I'm having trouble due to this, as I use regular keys to enable layers.

For example: holding space enables the symbols layer, so I can press space + t and it will act as the = key, but with the current timings of keyd it makes very difficult to type, as I have to pause in order to type words, as space is constantly triggering the hold if I type too fast.

I'd really love to get this into keyd and of course, I'm volunteering to try implementing it myself, I just would need some guidelines on where to start.

Thanks again!

international characters

Hello!, or as we say in Sweden hallå!

I have been using a very hackish method for years to make a custom layout with setxkb. It has worked fine, but you know only in x. The gist of the layout is that i can use the "extra" key on nordic QWERTY keyboards to act as a modifier for a special layer, and without it i am completely lost.

It seems like i can get all functionality i had before with this keyd except remapping keys to swedish characters. I want this to work:

# Turns capslock into an escape key when pressed and a control key when held.
capslock = overload(C, esc)

# Remaps the escape key to capslock
esc = grave

102nd = layer(bud)

[bud]

h = left
j = down
k = up
l = right

[ = macro(å)
' = macro(ä)
; = macro(ö)

(i also tried without using macro [ = å, but that didn't work either.
When i press f.i å (with normal swedish layout active) when keyd -m is running it just prints [.

I haven't looked that closely at the source. And I imagine this gets tricky since supporting every single foreign character might make the keys.h gigantic? But for me it would be acceptable if macro made a Unicode translation of the chars added and printed that.

Anyways, thanks for a very cool program.

didn't work with dvp

Debian 10, DWM.
tty = dvorak-programmer

/etc/keyd/default.cfg

rightalt = layer(mylayer)

[mylayer]
a = 0
o = 1
e = 2
u = 3

/etc/X11/xorg.conf.d/00-keyboard.conf

Section "InputClass"
        Identifier "system-keyboard"
        MatchIsKeyboard "on"
        Option "XkbLayout" "us,ru"
        Option "XkbModel" "pc104"
        Option "XkbVariant" "dvp,typewriter"
        Option "XkbOptions" "ctrl:nocaps, grp:win_space_toggle"
EndSection

capslock = overload(C, esc) and keybindings with control+escape(capslock)

I have noticed this strange issue that everytime i opened htop it seemed like the control key got "stuck". And today I noticed the same thing when opening whiskermeny. it is when i press Control (actual control key) and Escape (actual capslock) in a key combination while having:
capslock = overload(C, esc) in my keyd config, but i think i fixed it with this hack:

capslock = overload(C, esc)

leftcontrol = layer(control)

[control:C]
capslock = C-escape

This might be related to other "overload" issues when using the both of the keys in the overload together.

*edit
the keybinding for whiskermenu is: Control+Esc
htop: Control+Shift+Esc

<, > not assignable

When I remap < and >, keyd only considers the buttons located at , and . and not the button left to my z key. This one is reported as [keyboard]: 102nd.

How do I assign this key?

< = \

Inconsistency in manpage documentation

In the manpage an example is given to overload the escape key by using the overload action like this: overload(C, esc). However, under the "Actions" section the manpage states that the overload action takes the keyseq as the first argument and a layer as the second argument: overload(<keyseq>,<layer>)

I noticed this inconsistency while migrating my config where the overload action works in the format overload(<layer>, <keyseq>).
I don't know if there are other inconsistencies in the manpage, since I only noticed this issue explicitly. It probably is a good idea to have a look over it to see if everything is correct.

Autodetection of Keyboard & Keys

My goal is to bundle keyd in a deb, and then depend on it as part of a higher level app that makes a Mac-like experience easier on X11 & Wayland. To achieve this, there are two autodetection features that I've been thinking about. This relates to part of the discussion in #55 as well.

  1. Get key left of spacebar: To detect whether the user has a Mac keyboard or a Windows keyboard plugged in, it seems a "best practice" is to ask the user to press the key "to the left of the spacebar".

  2. Figure out which keyboard is being used: To detect which keyboard the user expects to have remapping applied, it would be user friendly to listen for all keyboards, and then check which one is the source of a key press event.

To accomplish both of the above, would it be possible to start keyd in monitor mode, but end after just one key press? I'm thinking I could tell the user "Please press the key to the left of spacebar" (like kinto does) and start keyd in monitor mode / autodetect mode. The keyd would respond with its usual line:

keyd virtual keyboard: alt down

it would then quit and the stdout could be parsed ("keyd virtual keyboard" and "alt down" would be enough to go on... although a device ID would be better).

AltGr modifier ignored by default.

Description

Typing something with AltGr modifier (eg. in the English UK layout in X11) does not work while running keyd with empty config. All other modifiers like Alt and Ctrl work with empty config.

AltGr only works when adding the following to config:

rightalt = layer(G)

I am using X11 to change the keyboard layout. I'm not use if that changes anything.

Steps to reproduce

  • Set keyboard layout to English UK (it has AltGr)
  • Type AltGr+4 to try to type .

Expected result

Type .

Actual result

Type 4. AltGr is ignored.

keyd monitor logs

All of them are with the English UK layout set in X11.

Without running keyd

AT Translated Set 2 keyboard: rightalt down
AT Translated Set 2 keyboard: 4 down
€AT Translated Set 2 keyboard: 4 up
AT Translated Set 2 keyboard: rightalt up

Without rightalt = layer(G) in config and running keyd

keyd virtual keyboard: rightalt down
keyd virtual keyboard: rightalt up
keyd virtual keyboard: 4 down
4keyd virtual keyboard: 4 up

With rightalt = layer(G) in config and running keyd

keyd virtual keyboard: rightalt down
keyd virtual keyboard: 4 down
€keyd virtual keyboard: 4 up
keyd virtual keyboard: rightalt up

How to map capslock to work as meta key?

What I want:

ckb1: Corsair Gaming K95 RGB PLATINUM Keyboard vKB: leftmeta down
ckb1: Corsair Gaming K95 RGB PLATINUM Keyboard vKB: left down
ckb1: Corsair Gaming K95 RGB PLATINUM Keyboard vKB: left up
ckb1: Corsair Gaming K95 RGB PLATINUM Keyboard vKB: leftmeta up

My attempt:

capslock = mods_on_hold(M, leftmeta)

results in

keyd virtual keyboard: leftmeta down
keyd virtual keyboard: leftmeta up
keyd virtual keyboard: leftmeta down
keyd virtual keyboard: leftmeta up

I held capslock, pressed once left arrow and released capslock. But arrow is missing and (slow) hold&release of capslock lead to leftmeta down (hold started), nothing (here should be left arrow down and up) and leftmeta up, leftmeta down, leftmeta up (all tree events fired when key was released).

Some keys (mostly letters on first and second row) are not dropped, but meta goes "up and down" around them which isn't good (also there are excessive meta presses). This is from capslock down, a key down and up, capslock up (both keys pressed only once):

keyd virtual keyboard: leftmeta down
keyd virtual keyboard: leftmeta up
keyd virtual keyboard: leftmeta down
keyd virtual keyboard: leftmeta up
keyd virtual keyboard: a down
akeyd virtual keyboard: a up
keyd virtual keyboard: leftmeta down
keyd virtual keyboard: leftmeta up
keyd virtual keyboard: leftmeta down
keyd virtual keyboard: leftmeta up

I also tried simpler capslock = leftmeta, but that didn't work too (one less down+up of meta, but still meta key was mapped as held, was released when other key was pressed and then pressed down again on its own).

It this a bug, or do I have something wrong in the configuration?

Config not loaded on startup

On startup, the daemon sometimes does not load the config.
This is a log of when that happened:

-- Boot a83ee4fbd1ad4e1d8866ad2c8c2dedd7 --
ago 29 16:38:45 amos systemd[1]: Started key remapping daemon.
ago 29 16:38:45 amos keyd[365]: Starting keyd v1.1.2 (8df75b749b9131faeb551c84efebca9762047649).

I am using the keyboard from a Thinkpad T480.

I do not know whether this is relevant or not but this is the output of libinput list-devices regarding the keyboard in question.

Device:           AT Translated Set 2 keyboard
Kernel:           /dev/input/event3
Group:            6
Seat:             seat0, default
Capabilities:     keyboard
Tap-to-click:     n/a
Tap-and-drag:     n/a
Tap drag lock:    n/a
Left-handed:      n/a
Nat.scrolling:    n/a
Middle emulation: n/a
Calibration:      n/a
Scroll methods:   none
Click methods:    none
Disable-w-typing: n/a
Accel profiles:   n/a
Rotation:         n/a

(This issue originated from #22)

Configure via device ids

I'm having problems creating a config file.
My keyboard is listed as "Apple Inc. Apple Internal Keyboard / Trackpad".
Since this keyboard name contains a forward slash, I'm unable to create a config file, since it's not following the UNIX philosophy:

touch Apple\ Inc.\ Apple\ Internal\ Keyboard\ \/\ Trackpad.cfg
touch: cannot touch 'Apple Inc. Apple Internal Keyboard / Trackpad.cfg': No such file or directory

Do you have any ideas supporting different ways of specifying keyboard id-s? Like the path of a device?:
Apple Inc. Apple Internal Keyboard / Trackpad

Can't use touchpad while keyd is running

I'm using the AUR package on my Framework laptop, and whenever the keyd service is running, the touchpad doesn't work at all. After stopping keyd, I can move my cursor again. Am I doing it wrong?

Env

  • Arch Linux rolling
  • SwayWM
  • Framework laptop
pacman -Q keyd-git
keyd-git 1.1.2.r23.c7ee833-1

Config

cat /etc/keyd/AT\ Translated\ Set\ 2\ keyboard.cfg
capslock = overload(C, esc)

Output

sudo keyd
Starting keyd v1.1.2 (c7ee83350dc0064e9f03a780995efce18266ea4d).
Managing AT Translated Set 2 keyboard

...at this point, there is no more output and it's impossible to move the cursor or click any buttons with the touchpad.

Repeating enter key/Occasional mouse freeze when starting under wayland.

When starting keyd the last keyevent gets dropped. This usually has the benign manifestation of sending enter until it is pressed again but in the case of certain input devices coupled with libinput has the additional implication of rendering the mouse unusuable.

It seems libinput stops generating mouse events for a certain class of devices while the enter key is held. This can be observed by holding enter and trying to move the cursor around. The problem is easily avoidable by simply starting keyd before wayland as intended or switching VTs to force a device reload. Prepending a timeout is also a possibility (E.G sleep 1s;sudo systemctl start keyd). A simple fix would be to bake a timeout of a few ms into the code to allow the user to release any keys but this is ugly and involves a race condition. A more elegant solution is in the pipeline.

Duplicate entries in `keyd -l`

I see some dups in the list of keys available via keyd -l (e.g. up, down, menu, record):

prevgroup
nextgroup
accept
cancel
up
down
up
down
menu
menu
11
12
desc
mode
favorite
record
record
vod
unmute

Allow for config/log/lock file paths customization

Hi,

Some distros like Nixos use non-standard paths, so it would be cool if the paths for the config file, log file and lock file could be customized. Currently I've patched the source code & Makefile but obviously another option would be to allow the user to pass these as arguments to the program.

diff --git a/Makefile b/Makefile
index 8f90462..3563b80 100644
--- a/Makefile
+++ b/Makefile
@@ -3,9 +3,13 @@
 DESTDIR=
 PREFIX=/usr
 
+CONFIG_DIR=/etc/keyd
+LOCK_FILE=/var/lock/keyd.lock
+LOG_FILE=/var/log/keyd.log
+
 VERSION=1.1.2
 GIT_HASH=$(shell git describe --no-match --always --abbrev=40 --dirty)
-CFLAGS=-DVERSION=\"$(VERSION)\" -DGIT_COMMIT_HASH=\"$(GIT_HASH)\"
+CFLAGS=-DVERSION=\"$(VERSION)\" -DGIT_COMMIT_HASH=\"$(GIT_HASH)\" -DLOCK_FILE=\"$(LOCK_FILE)\" -DLOG_FILE=\"$(LOG_FILE)\" -DCONFIG_DIR=\"$(CONFIG_DIR)\"
 
 all:
 	mkdir -p bin
diff --git a/src/config.h b/src/config.h
index a6465b8..3a53043 100644
--- a/src/config.h
+++ b/src/config.h
@@ -29,7 +29,11 @@
 #include "keys.h"
 
 #define MAX_LAYERS 32
+
+#ifndef CONFIG_DIR
 #define CONFIG_DIR "/etc/keyd"
+#endif
+
 #define MAX_LAYER_NAME_LEN 256
 #define MAX_MACRO_SIZE 256
 #define MAX_MACROS 256
diff --git a/src/main.c b/src/main.c
index 86dbc7e..a697170 100644
--- a/src/main.c
+++ b/src/main.c
@@ -42,8 +42,14 @@
 
 #define UINPUT_DEVICE_NAME "keyd virtual keyboard"
 #define MAX_KEYBOARDS 256
+
+#ifndef LOCK_FILE
 #define LOCK_FILE "/var/lock/keyd.lock"
+#endif
+
+#ifndef LOG_FILE
 #define LOG_FILE "/var/log/keyd.log" //Only used when running as a daemon.
+#endif
 
 #ifdef DEBUG
 	#define dbg(fmt, ...) warn("%s:%d: "fmt, __FILE__, __LINE__, ## __VA_ARGS__)

Thanks.

Warn on invalid options, or at least add -h / --help options

Today I was trying to remember how to enter monitor mode, and kept trying options that didn't work but were silently ignored. What further fooled me is that monitor mode and non-daemon "main loop" mode are similar in that they mention the name of the keyboard and wait.

It would be handy to have a --help option for a quick reminder of the options.

And/or warn on invalid options.

Simulate or pass through App Switching

I mistakenly thought I'd encountered an error state via #47. Thank you to the @rvaiya for the help there. I'm opening this new ticket to discuss what I actually want to achieve, so I can be clearer and potentially get better advice :)

I'm trying to make Linux shortcuts behave like Mac OS:

  • I have a Win (Meta) key that can be used for application switching, e.g. Meta-Tab and Meta-Shift-Tab
  • I have an Alt key to the left of the spacebar where Cmd normally is, so I'm thinking of Alt as the "do everything" modifier, like Cmd is in Mac OS.
  • When I press Alt-C I want to simulate the Linux system-wide "Copy" shortcut key: Ctrl-Insert
  • When I press Alt-V I want to simulate the Linux system-wide "Paste" shortcut key: Shift-Insert
  • When I press and hold Alt, followed by any sequence of Tab or Grave (tilde) I want to simulate Meta-Tab (for each Tab press/release) or Meta-Shift-Tab (for each Grave press/release), until Alt is released. (In this "held" state, after an initial Tab or Grave has been pressed, it's ok--maybe even desirable?--to do nothing when C or V are pressed, even though technically Alt is also being pressed and that could be considered an Alt-C or Alt-V sequence).

How can I achieve this "dual nature" Alt key in keyd?

(Note: the important part here is that once we enter the "app switching" state, the Alt key cannot be released, or else the app switcher will be shut off and lose its state)

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.