Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Key remapper for X11 and Wayland

License

NotificationsYou must be signed in to change notification settings

xremap/xremap

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Xremap ⌨️

crates.ioGitHub Actions

xremap is a key remapper for Linux. Unlikexmodmap, it supports app-specific remapping and Wayland.

Table of contents

Concept

  • Fast - Xremap is written in Rust, which is faster than JIT-less interpreters like Python.

  • Cross-platform - Xremap usesevdev anduinput, which works whether you use X11 or Wayland.

  • Language-agnostic - The config is JSON-compatible. Generate it from any language,e.g.Ruby,Python.

Features

  • Remap any keys, e.g. Ctrl or CapsLock.
  • Remap any key combination to another, even to a key sequence.
  • Remap a key sequence as well. You could do something like Emacs'sC-x C-c.
  • Remap a key to two different keys depending on whether it's pressed alone or held.
  • Application-specific remapping. Even if it's not supported by your application, xremap can.
  • Device-specific remapping.
  • Automatically remap newly connected devices by starting xremap with--watch.
  • SupportEmacs-like key remapping, including the mark mode.
  • Trigger commands on key press/release events.
  • Use a non-modifier key as a virtual modifier key.

Installation

Download a binary fromReleases.

If it doesn't work, pleaseinstall Rustand run one of the following commands:

cargo install xremap --features x11# X11cargo install xremap --features gnome# GNOME Waylandcargo install xremap --features kde# KDE-Plasma Waylandcargo install xremap --features wlroots# Sway, Wayfire, etc.cargo install xremap --features hypr# Hyprlandcargo install xremap --features niri# Niricargo install xremap --features cosmic# Cosmiccargo install xremap# Others

You may also need to installlibx11-dev to run thexremap binary for X11.

Arch Linux

If you are on Arch Linux and X11, you can installxremap-x11-bin from AUR.

NixOS

If you are using NixOS, xremap can be installed and configured through aflake.

Fedora Linux

If you are using Fedora, xremap can be installed via thisFedora Copr repository.

Usage

Writea config file directly, or generate it withxremap-ruby orxremap-python.

Then start thexremap daemon by running:

sudo xremap config.yml

(You will need to leave it running for your mappings to take effect.)

If you want to run xremap without sudo, click here.

Running xremap without sudo

To do so, your normal user should be able to useevdev anduinput without sudo.In Ubuntu, this can be configured by running the following commands and rebooting your machine.

sudo gpasswd -a YOUR_USER inputecho'KERNEL=="uinput", GROUP="input", TAG+="uaccess"'| sudo tee /etc/udev/rules.d/input.rules

Arch Linux

The following can be used on Arch.

lsmod| grep uinput

If this module is not loaded, add to/etc/modules-load.d/uinput.conf:

uinput

Then add udev rule.

echo'KERNEL=="uinput", GROUP="input", TAG+="uaccess"'| sudo tee /etc/udev/rules.d/99-input.rules

Then reboot the machine.

Debian

Make sureuinput is loaded same as in Arch:

lsmod | grep uinput

If it shows up empty:

echo uinput| sudo tee /etc/modules-load.d/uinput.conf

Add your user to theinput group and add the same udev rule as in Ubuntu:

sudo gpasswd -a YOUR_USER inputecho'KERNEL=="uinput", GROUP="input", TAG+="uaccess"'| sudo tee /etc/udev/rules.d/input.rules

Reboot the machine afterwards or try:

sudo modprobe uinputsudo udevadm control --reload-rules&& sudo udevadm trigger

NixOS

The following can be used on NixOS.

Ensureuinput is enabled in yourconfiguration.nix:

hardware.uinput.enable=true;boot.kernelModules=["uinput"];

Then add the rule to theudev extra rules in yourconfiguration.nix:

services.udev.extraRules=''  KERNEL=="uinput", GROUP="input", TAG+="uaccess"  '';

The new rule will be added to/etc/udev/rules.d/99-local.rules. SeeNixOS documentation for additional information.

Rebuild withnixos-rebuild switch. Note you may also need to reboot your machine.

Other platforms

In other platforms, you might need to create aninput group firstand runecho 'KERNEL=="event*", NAME="input/%k", MODE="660", GROUP="input"' | sudo tee /etc/udev/rules.d/input.rules as well.

If you do this, in some environments,--watch may fail to recognize new devices due to temporary permission issues.Usingsudo might be more useful in such cases.


See the following instructions for your environment to makeapplication-specific remapping work.

X11

If you usesudo to runxremap, you may need to runxhost +SI:localuser:root if you seeNo protocol specified.

GNOME Wayland

Install xremap's GNOME Shell extension fromthis link,switching OFF to ON.

If you usesudo to runxremap, also click here.

Update/usr/share/dbus-1/session.conf as follows, and reboot your machine.

   <policy context="default">+    <allow user="root"/>     <!-- Allow everything to be sent -->     <allow send_destination="*" eavesdrop="true"/>     <!-- Allow everything to be received -->

KDE-Plasma Wayland

Xremap cannot be run as root. Follow the instructions above to run xremap without sudo.

Niri

If you usesudo to runxremap, you need to ensure that theNIRI_SOCKET env var is available to xremap:

sudo NIRI_SOCKET="$NIRI_SOCKET" xremap config.yml

Configuration

Yourconfig.yml should look like this:

modmap:  -name:Except Chromeapplication:not:Google-chromeremap:CapsLock:Esckeymap:  -name:Emacs bindingapplication:only:Slackremap:C-b:leftC-f:rightC-p:upC-n:down

See also:example/config.yml andexample/emacs.yml

modmap

modmap is for key-to-key remapping like xmodmap.Note that remapping a key to a modifier key, e.g. CapsLock to Control_L,is supported only inmodmap sincekeymap handles modifier keys differently.

modmap:  -name:Name# Optionalexact_match:false# Optional, defaults to falseremap:# Required# Replace a key with anotherKEY_XXX1:KEY_YYY# Required# Replace a key with multiple keys (pressed and released simultaneously)KEY_XXX2:[KEY_YYY, KEY_ZZZ]# Dispatch different keys depending on whether you hold it or press it alone# Disable a keyKEY_XXX3:[]KEY_XXX4:held:KEY_YYY# Required, also accepts arraysalone:KEY_ZZZ# Required, also accepts arraysalone_timeout_millis:1000# Optional, defaults to 1000# Hook `keymap` action on key press/release events.KEY_XXX5:skip_key_event:true# Optional, skip original key event, defaults to falsepress:[{ press: KEY_YYY }, { launch: ["xdotool", "mousemove", "0", "7200"] }]# Optional, default to no actionrepeat:{ repeat: KEY_YYY }# Optional, default to no actionrelease:[{ release: KEY_YYY }, { set_mode: my_mode }]# Optional, default to no actionapplication:# Optionalnot:[Application, ...]# oronly:[Application, ...]window:# Optionalnot:[/regex of window title/, ...]# oronly:[/regex of window title/, ...]device:# Optionalnot:[Device, ...]# oronly:[Device, ...]mode:default# Optional# ormode:[ default, my_mode ]default_mode:default# Optional

ForKEY_XXX andKEY_YYY, usethese names.You can skipKEY_ and the name is case-insensitive. SoKEY_CAPSLOCK,CAPSLOCK, andCapsLock are the same thing.Somecustom aliases likeSHIFT_R,CONTROL_L, etc. are provided.

In case you don't know the name of a key, you can find out by enabling the xremap debug output:

RUST_LOG=debug xremap config.yml# orsudo RUST_LOG=debug xremap config.yml

Then press the key you want to know the name of.

Multi-purpose key with alone_timeout_millis

If you specify a map containingheld andalone, you can use the key for two purposes. By default, the behavior is determined by a timeout:

  • If the key is pressed and released withinalone_timeout_millis (default: 1000) without any other key being pressed, it's consideredalone.
  • If the key is held down longer than the timeout, it's consideredheld.

This can be problematic if you want to use a key as a modifier, as you might trigger theheld action by simply holding the key for too long.

Multi-purpose key with free hold

Thefree_hold: true option provides a different behavior for these multi-purpose keys. When enabled:

  • Theheld action isonly triggered when another key is pressed while the multi-purpose key is being held down. The timeout is ignored for theheld action.
  • If the key is released without any other key being pressed, it triggers thealone action, regardless of how long it was held.

This allows a key to be held indefinitely without triggering itsheld state, which is ideal for keys that also serve as modifiers. For example, you can make theSpace key act asShift when held and combined with another key, but still type a regularSpace when tapped.

modmap:  -name:Space as Shiftremap:Space:held:Shift_Lalone:Spacefree_hold:true# Optional, defaults to false.

keymap

keymap is for remapping a sequence of key combinations to another sequence of key combinations or other actions.Key actions inkeymap will generally press and release keys right awaywhen the last key in the trigger combination is pressed.

keymap:  -name:Name# Optionalexact_match:false# Optional, defaults to falseremap:# Required# Key press -> Key pressMOD1-KEY_XXX1:MOD2-KEY_YYY# Sequence (MOD1-KEY_XXX2, MOD2-KEY_YYY) -> Key press (MOD3-KEY_ZZZ)MOD1-KEY_XXX2:remap:MOD2-KEY_YYY:MOD3-KEY_ZZZtimeout_millis:200# Optional. No timeout by default.timeout_key:KEY_A# Optional. Defaults to nothing. Can also be an array.# Key press (MOD1-KEY_XXX3) -> Sequence (MOD2-KEY_YYY, MOD3-KEY_ZZZ)MOD1-KEY_XXX3:[MOD2-KEY_YYY, MOD3-KEY_ZZZ]# Execute a commandMOD1-KEY_XXX4:launch:["bash", "-c", "echo hello > /tmp/test"]# Let `with_mark` also press a Shift key (useful for Emacs emulation)MOD1-KEY_XXX5:{ set_mark: true }# use { set_mark: false } to disable it# Also press Shift only when { set_mark: true } is used beforeMOD1-KEY_XXX6:{ with_mark: MOD2-KEY_YYY }# After pressing MOD1-KEY_XXX7, the next key press will ignore keymapMOD1-KEY_XXX7:{ escape_next_key: true }# Set mode to configure Vim-like modal remappingMOD1-KEY_XXX8:{ set_mode: default }# Illustrate a nested mapping that times out;# also useful for timing out double-key sequences if the second key is never pressed.space:# Use timeout to fix a bouncy spacebarremap:space:null# make space output nothing; null is equivalent to []timeout_key:space# output space after timeout or a non-mapped key (only space is mapped above)timeout_millis:150# timeout duration in msapplication:# Optionalnot:[Application, ...]# oronly:[Application, ...]window:# Optionalnot:[/regex of window title/, ...]# oronly:[/regex of window title/, ...]device:# Optionalnot:[Device, ...]# oronly:[Device, ...]mode:default# Optional# ormode:[ default, my_mode ]default_mode:default# Optional

ForKEY_XXX, usethese names.You can skipKEY_ and the name is case-insensitive. SoKEY_CAPSLOCK,CAPSLOCK, andCapsLock are the same thing.

For theMOD1- part, the following prefixes can be used (also case-insensitive):

  • Shift:SHIFT-
  • Control:C-,CTRL-,CONTROL-
  • Alt:M-,ALT-
  • Windows:SUPER-,WIN-,WINDOWS-

You can use multiple prefixes likeC-M-Shift-a.You may also suffix them with_L or_R (case-insensitive) so thatremapping is triggered only on a left or right modifier, e.g.Ctrl_L-a.

If you usevirtual_modifiers explained below, you can use it in theMOD1- part too.

exact_match defines whether to use exact match when matching key presses. Forexample, given a mapping ofC-n: down andexact_match: false (default), andyou pressedC-Shift-n, it will automatically be remapped toShift-down, without you having to define a mapping forC-Shift-n, which you would have to do if you useexact_match: true.

application

application can be used for bothmodmap andkeymap, which allows you to specify application-specific remapping.

application:not:Application# ornot:[Application, ...]# oronly:Application# oronly:[Application, ...]

The application name can be specified as a normal string to exactly match the name,or a regex surrounded by/s like/application/.

To check the application names, you can use the following commands:

X11

$ wmctrl -x -l0x02800003  0 slack.Slack           ubuntu-jammy Slack | general | ruby-jp0x05400003  0 code.Code             ubuntu-jammy application.rs - xremap - Visual Studio Code

You may use the entire string of the third column (slack.Slack,code.Code),or just the last segment after. (Slack,Code).

GNOME Wayland

Use the following command or check windows' WMClass by pressing Alt+F2 and runninglg command inLookingGlass:

busctl --user call org.gnome.Shell /com/k0kubun/Xremap com.k0kubun.Xremap WMClasses

KDE-Plasma Wayland

Xremap prints the active window to the console.However, it will only start printing, once a mapping has been triggered that uses an application filter.So you have to create a mapping with a filter using a dummy application name and trigger it.Then each time you switch to a new window xremap will print its caption, class, and name in the following style:active window: caption: '<caption>', class: '<class>', name: '<name>'Theclass property should be used for application matching, while thecaption property should be used for window matching.

If you use a systemd-daemon to manage xremap, the prints will be visible in the system-logs (Can be opened withjournalctl -f)

Sway

swaymsg -t get_tree

Locateapp_id in the output.

Niri

niri msg windows

LocateApp ID in the output.

application-specific key overrides

Sometimes you want to define a generic key map that is available in all applications, but give specific keys in that map their own definition in specific applications. You can do this by putting the generic map at the bottom of the config, after any specific overrides, as follows.

# Emacs-style word-forward and word-backkeymap:  -name:override to make libreoffice-writer go to end of word but before final space like emacsapplication:only:libreoffice-writterremap:Alt-f:[right, C-right, left]  -name:generic for all appsremap:Alt-f:C-rightAlt-b:C-left

Note how Alt-f and Alt-b work in all apps, but the definition of Alt-f is slightly different in LibreOffice Writer. When that app is active, the first definition overrides the second definition; but for any other app, only the second definition is found. This is because xremap uses the first matching definition that it finds.

device

Much likeapplication, you may specify{keymap,modmap}.device.{not,only} in your configuration for device-specific remapping. Consistent with the global--device flag, device-matching strings may be any of:

  • the full path of the device
  • the filename of the device
  • the device name
  • a substring of the device name

To determine the names and paths of your devices, examinexremap's log output at startup.

device:not:'/dev/input/event0'# ornot:['event0', ...]# oronly:'Some Cool Device Name'# oronly:['Cool Device', ...]# etc...

Unlike forapplication, regexs are not supported fordevice.

mode

You can assign mode(s) to keymap and/or remap which effectively turns them on or offwhen you set the mode.

modmap:  -name:Upremap:W:UPmode:[Up, Up_And_Down]# Mode is optional  -name:Downremap:S:DOWNmode:[Down, Up_And_Down]  -name:Right_And_Leftremap:D:RIGHTA:LEFTmode:Right_And_Left# Mode can be a string or vector of strings  -name:Turn Offremap:L:press:{ set_mode: Off }# Modmap can set mode via press and releaserelease:# If mode is absent the keymap or modmap is always onkeymap:  -name:SetModeremap:CTRL-U:{ set_mode: Up }CTRL-I:{ set_mode: Down }CTRL-O:{ set_mode: Up_And_Down }CTRL-P:{ set_mode: Right_And_Left }mode:[Up, Down, Right_And_Left, Up_And_Down, Off]# You can assign modes to keymap too!default_mode:Up_And_Down# Optional, if absent default mode is "default"

virtual_modifiers

You can declare keys that should act like a modifier.

virtual_modifiers:  -CapsLockkeymap:  -remap:CapsLock-i:UpCapsLock-j:LeftCapsLock-k:DownCapsLock-l:Right

keypress_delay_ms

Some applications have trouble understanding synthesized key events, especially onWayland.keypress_delay_ms can be used to workaround the issue.

Shared data field

You can declare data that does not directly go into the config under theshared field.
This can be usefull when using Anchors and Aliases.
For more information about the use of Yaml anchors see theYaml specification.

example:

shared:terminals:&terminals# The & Symbol marks this entry as a Anchor    -Gnome-terminal    -Kittysome_remaps:&some_remapsCtrl-f:C-rightAlt-b:C-upkeymap:  -application:only:*terminals# we can reuse the list hereremap:*some_remaps# and we can reuse a map here.

Commandline arguments

Usage for xremap is shown by running the following command:

xremap --help

The result is shown here:

Usage: xremap [OPTIONS] [CONFIGS]...Arguments:  [CONFIGS]...          Config file(s)          When more than one file is given, then will modmap, keymap and virtual_modifiers from the subsequent files be merged into the first configuration file.Options:      --device <DEVICE>          Limit input devices to the given names or paths. Default is all keyboards      --ignore <IGNORE>          Ignore input devices with the given names or paths      --mouse          Listen to mouse devices. Default is false      --watch[=<WATCH>...]          Watch for new devices or changing configuration files.          Default is not watching for either.          Examples          - xremap --watch config.yml               # watch devices          - xremap --watch=config config.yml        # watch configuration files          - xremap --watch=config,device config.yml # watch both          Possible values:          - device: add new devices automatically          - config: reload the config automatically      --output-device-name <OUTPUT_DEVICE_NAME>          Choose the name of the created output device. Default is 'xremap' or 'xremap pid=xx'      --vendor <VENDOR>          Choose the vendor value of the created output device. Default is: 0x1234      --product <PRODUCT>          Choose the product value of the created output device. Default is: 0x5678      --completions <SHELL>          Generate shell completions          You can use them by storing in your shells completion file or by running          - in bash: eval "$(xremap --completions bash)"          - in fish: xremap --completions fish | source          [possible values: bash, elvish, fish, powershell, zsh]  -h, --help          Print help (see a summary with '-h')  -V, --version          Print version

Running xremap as a daemon

Put your config file at~/.config/xremap/config.yml andcopyexample/xremap.service to~/.config/systemd/user/xremap.service.

cp example/xremap.service~/.config/systemd/user/xremap.service

Warning

make surexremap installaion path matchesxremap.service path

then run

systemctl --user start xremap.service

To start the service on boot,systemctl --user enable xremap.service may sometimes work.However, it may fail to recognize the window manager if you start xremap too early.Consider copyingexample/xremap.desktop to~/.config/autostart/xremap.desktop if the platform supports it.

Maintainers

  • @k0kubun
  • @N4tus (KDE client)
  • @jixiuf (wlroots client)
  • @saurabhsharan (Niri client)
  • @hpccc53 (Cosmic client)

Releasing

First, bump the xremap version at Cargo.toml and Cargo.lock, and Update CHANGELOG.md. Then:

git add .git commit -m "Version 0.X.Y"git push origin mastergit tag v0.X.Ygit push origin --tags

License

xremap is available as open source under the terms of theMIT License.

About

Key remapper for X11 and Wayland

Topics

Resources

License

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp