Skip to content

Commit

Permalink
Implement push, pop(_all) bind commands; user bindings; update README.md
Browse files Browse the repository at this point in the history
These commands may be useful to execute at user session startup.
User bindings are loaded by explicit calling `keyd reload` from user.
User bindings are located at `~/.config/keyd/bindings.conf`.
  • Loading branch information
Nekotekina committed Dec 25, 2024
1 parent be37ebc commit 7b12bdc
Show file tree
Hide file tree
Showing 12 changed files with 166 additions and 198 deletions.
120 changes: 55 additions & 65 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,17 @@
[![Kofi](https://badgen.net/badge/icon/kofi?icon=kofi&label)](https://ko-fi.com/rvaiya)

# Impetus

[![Packaging status](https://repology.org/badge/tiny-repos/keyd.svg)](https://repology.org/project/keyd/versions)
# keyd++

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](docs/CHANGELOG.md).

# Goals

- Speed (a hand tuned input loop written in C that takes <<1ms)
- Speed (event loop that takes <<1ms for input event)
- Simplicity (a [config format](#sample-config) that is intuitive)
- Consistency (modifiers that [play nicely with layers](https://github.com/rvaiya/keyd/blob/6dc2d5c4ea76802fd192b143bdd53b1787fd6deb/docs/keyd.scdoc#L128) by default)
- Modularity (a UNIXy core extensible through the use of an [IPC](https://github.com/rvaiya/keyd/blob/90973686723522c2e44d8e90bb3508a6da625a20/docs/keyd.scdoc#L391) mechanism)
- Consistency (modifiers that [play nicely with layers](docs/keyd.scdoc#L128) by default)
- Modularity (a UNIXy core extensible through the use of an [IPC](docs/keyd.scdoc#L391) mechanism)

# Features

Expand All @@ -33,7 +21,7 @@ as well as some which are unique to keyd.

Some of the more interesting ones include:

- Layers (with support for [hybrid modifiers](https://github.com/rvaiya/keyd/blob/6dc2d5c4ea76802fd192b143bdd53b1787fd6deb/docs/keyd.scdoc#L128)).
- Layers (with support for [hybrid modifiers](docs/keyd.scdoc#L128)).
- Key overloading (different behaviour on tap/hold).
- Keyboard specific configuration.
- Instantaneous remapping (no more flashing :)).
Expand All @@ -42,6 +30,23 @@ Some of the more interesting ones include:
- First class support for modifier overloading.
- Unicode support.

keyd++ has specific features at the moment:

- Virtually unlimited sizes/counts (keyd has had many hardcoded limitations).
- Layer indicator with keyboard led of choice (keyd is somewhat broken).
- **Macro** can now do `type(Hello world)` without worrying about spaces.
- **Macro** can now execute `cmd(gnome-terminal)` and it should **just work**.
- Allow using `ctrl` as an alias for `control` (my personal whim).
- Wildcard for mice `m:` that excludes problematic abs ptr devices(`a:`).
- More flexible text parsing (in progress, eg. 'a+b' now equals 'b+a').
- Memory optimizations (sometimes only 1/5 of what keyd has had).
- Performance optimizations, eg. events from ungrabbed device are ignored.
- Some security improvement: privileged commands shall be in /etc/keyd/ conf.
- Bindings coming from ex. `keyd-application-mapper` inherit uid+gid+environ.
- `keyd reload` from user loads user binds from `~/.config/keyd/bindings.conf`.
- New commands for config control: push, pop, pop_all. Can unload user binds.
- Convenience and safety coming from C++20. Sorry for longer compilation.

### keyd is for people who:

- Would like to experiment with custom [layers](https://docs.qmk.fm/feature_layers) (i.e custom shift keys)
Expand All @@ -59,7 +64,7 @@ Some of the more interesting ones include:

# Dependencies

- Your favourite C compiler
- C++20 compiler starting from clang++-14 or g++-11
- Linux kernel headers (already present on most systems)

## Optional
Expand All @@ -70,15 +75,22 @@ Some of the more interesting ones include:

# Installation

*Note:* master serves as the development branch, things may occasionally break
between releases. Releases are [tagged](https://github.com/rvaiya/keyd/tags), and should be considered stable.
*Note:* master serves as the development branch, things may occasionally break.

## From Source

git clone https://github.com/rvaiya/keyd
cd keyd
make && sudo make install
sudo systemctl enable --now keyd
```bash
# Install dependencies (if necessary)
sudo apt install build-essentials git
# Clone with git clone (.) or download sources manually to keyd directory
cd keyd
# Specify your favourite compiler (optional)
export CXX=clang++-18
# First time install
make && sudo make install && sudo systemctl enable --now keyd
# Second time install (update, contains **example** flags for statically linking libstdc++)
CXX=clang++-18 CXXFLAGS='-static-libgcc -static-libstdc++' make && sudo make install && sudo systemctl daemon-reload && sudo systemctl restart keyd
```

# Quickstart

Expand Down Expand Up @@ -119,6 +131,24 @@ 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.

## User Specific Remapping (experimental)

- Add yourself to the keyd group:

`usermod -aG keyd <user>`

- Create `~/.config/keyd/bindings.conf`:

E.G
meta.t = macro(cmd(gnome-terminal))

- Execute `keyd reload` without sudo (possibly at startup)

- Environment variables whel launching `keyd reload` will be used.

- `/root/keyd/bindings.conf` may be read at `sudo keyd reload`.


## Application Specific Remapping (experimental)

- Add yourself to the keyd group:
Expand Down Expand Up @@ -161,46 +191,6 @@ 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](https://pkgs.alpinelinux.org/packages?name=keyd) package maintained by [@jirutka](https://github.com/jirutka).

### Arch

[Arch Linux](https://archlinux.org/packages/extra/x86_64/keyd/) 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](https://salsa.debian.org/rhansen/keyd):

* [amd64 (64-bit)](https://salsa.debian.org/rhansen/keyd/-/jobs/artifacts/debian/latest/browse/debian/output?job=build)
* [i386 (32-bit)](https://salsa.debian.org/rhansen/keyd/-/jobs/artifacts/debian/latest/browse/debian/output?job=build%20i386)

Any Debian Developer who is willing to review the debianization effort and
sponsor its upload is encouraged to contact
[@rhansen](https://github.com/rhansen) (also see the [Debian ITP
bug](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1060023)).

### Fedora

[COPR](https://copr.fedorainfracloud.org/coprs/alternateved/keyd/) package maintained by [@alternateved](https://github.com/alternateved).

### openSUSE
[opensuse](https://software.opensuse.org//download.html?project=hardware&package=keyd) package maintained by [@bubbleguuum](https://github.com/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](https://launchpad.net/~keyd-team/+archive/ubuntu/ppa).

If you wish to help maintain this PPA, please contact
[@rhansen](https://github.com/rhansen).

# Sample Config

[ids]
Expand All @@ -218,7 +208,7 @@ If you wish to help maintain this PPA, please contact
f = /
...

# Recommended config
# Example 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
Expand Down
Binary file modified data/keyd-application-mapper.1.gz
Binary file not shown.
Binary file modified data/keyd.1.gz
Binary file not shown.
83 changes: 0 additions & 83 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,86 +157,3 @@ See [DESIGN.md](DESIGN.md) for a more thorough description of changes.
# v2.0.0-beta

Major version update.

This breaks 1.x configs. The format may ~~change slightly~~ (see [2.3.0-rc](#v230-rc)) before leaving beta,
but once it does should remain backwards compatible for the foreseeable future.

A non exhaustive list of changes can be found below. It is best to forget
everything you know and read man page anew.

- Eliminate layer inheritance in favour of simple types.
(layouts are now defined with `:layout` instead of `:main`)
- Macros are now repeatable.
- Overload now accepts a hold threshold timeout.
- Config files are now vendor/product id oriented.
- SIGUSR1 now triggers a config reload.
- Modifiers are layers by default and can be extended directly.
- Config files now end in `.conf`.
- `layert()` is now `toggle()`.
- All layers are 'modifier layers' (terminological change)
- Eliminate the dedicated modifer layout.
- Modifiers no longer apply to key sequences defined within a layer.
(Layer entries are now always executed verbatim.)

The old behaviour was unintuitive and can be emulated using nested
layers if necessary.

For most old configs transitioning should be a simple matter of changing
the file extension from `.cfg` to `.conf`, replacing `layert` with
`toggle`, changing `:main` to `:layout` and adding

```
[ids]
*
[main]
```

to the top of the file.

More involved configs may need additional changes, but should be possible
to replicate using the new rules. If not, please file an issue on
[github](https://github.com/rvaiya/keyd/issues).

# v1.1.1

- Make layert behaviour more intuitive when combined with oneshot() and layer().

# v1.1.0

- Add layert() to facilitate semipermanent-activation of occluding layers.
- Resolve layer conflicts by picking the one which was most recently activated.

# v1.0.0

Major version update:

- Introduce support for modifier layers.
- Simplify the config format.
- Improve consistency/expected key behaviour.
- Symbols can now be assigned directly place of their names (e.g `&` instead of `S-7`).
- Macro support.

*This breaks existing configs*. Moving forward the config format is expected to
remain backwards compatible.

Main Config Changes:

- Modifiers are now just treated as layers
- The default layer is now called main
- The modifier layout is distinct from the key layout

Config migration map:

```
mods_on_hold(C, esc) = overload(C, esc)
layer_on_hold(layer, esc) = overload(layer, esc)
layer_toggle(layer) = layout(layer)
layer(layer) = layer(layer)
oneshot(mods) = oneshot(mods)
oneshot_layer(layer) = oneshot(layer)
[dvorak:default] = [dvorak:main]
```

See the [manpage](man.md) for details.
16 changes: 6 additions & 10 deletions docs/keyd.scdoc
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ keyd(1)
*listen*
Print layer state changes of the running keyd daemon to stdout. Useful for scripting.

*bind reset|<binding> [<binding>...]*
*bind reset|push|pop|pop_all<binding> [<binding>...]*
Apply the supplied bindings. See _Bindings_ for details.

*reload*
Reload config files.
Reload config files. Optionally loads bindings from $HOME/.config/keyd/bindings.conf

*list-keys*
List valid key names.
Expand Down Expand Up @@ -797,8 +797,9 @@ The _bind_ command accepts one or more _bindings_, each of which must have the f
Where _<layer>_ is the name of an (existing) layer in which the key is to be bound.

As a special case, the string "reset" may be used in place of a binding, in
which case the current keymap will revert to its original state (all
which case the current keymap will revert to its last pushed state (all
dynamically applied bindings will be dropped).
Commands "push" and "pop|pop_all" maintain additional layers of states.

Examples:

Expand Down Expand Up @@ -970,10 +971,5 @@ Disables the esc and end keys.

# AUTHOR

Written by Raheman Vaiya (2017-).

# BUGS

Please file any bugs or feature requests at the following url:

<https://github.com/rvaiya/keyd/issues>
Written by Raheman Vaiya (2017-) in C.
Port to C++ in progress by Nekotekina.
Loading

0 comments on commit 7b12bdc

Please sign in to comment.