This file contains key overrides to pilot the Keychron K2 on Sway
On X11 you would use xmodmap
(man 1 xmodmap) to do something like:
$ xmodmap -pke | grep Delete
keycode 91 = KP_Delete KP_Decimal KP_Delete KP_Decimal KP_Delete KP_Separator
keycode 119 = Delete Insert Delete Insert Delete Insert
$ xmodmap -e "keycode 119 = Delete Insert Delete NoSymbol Delete"
This command will have no effect on Wayland.
Some troubleshooting for Linux: https://github.com/Kurgol/keychron
Have the F1-12 keys behave like function keys (not sure it persists after a reboot)
echo 0 | sudo tee /sys/module/hid_apple/parameters/fnmode
src: https://github.com/Kurgol/keychron/blob/master/k2.md#f-keys-on-ubuntu
On Sway we have to write a xkb file that overrides in part (or completely replace) the default X11 keybindings. This override file will be parsed and validated by Sway. When editing this file don't forget to reload Sway after any change.
General syntax is detailed here
Fully commented example:
# "partial" indicates that this map doesn't cover a complete keyboard
# "alphanumeric_keys" describes which section of the keyboard is being covered
default partial alphanumeric_keys
# "basic" declares symbol map name
xkb_symbols "basic" {
# define a base layout to inherit
include "us(altgr-intl)"
include "level3(caps_switch)"
# name of the layout
name[Group1] = "Keychron";
# map Del key to delete or insert, i.e.:
# Press delete -> delete
# Press shift+delete -> insert
key <DELE> { [ Delete, Insert ] };
# map left alt to left super (this mapping is always used)
key <LWIN> { [ Alt_L ] };
# map left super to left alt (this mapping is always used)
key <LALT> { [ Super_L ] };
};
# define two options:
# - toggle keyboard layout (e.g. US,DE,IT,FR, ...) on Mod+Space combo press
# - turn Capslock into another Ctrl
xkb_options grp:win_space_toggle,caps:ctrl_modifier
A single key remapping in detail:
<DELE>
is the physical key identifier. These identifiers can be found on the image map in the documentation page.
{ [ Delete, Insert ] }
are symbols emitted on screen. The full list of symbols is mapped is found here. Symbols names are derived from this mapping (removing XL_
). Number and ordering of parameters inside square brackets means:
For available xkb_options
options: see man 7 xkeyboard-config
(jump to "OPTIONS")
When this file will be loaded in Sway, you can check its effect by using xev -event keyboard
(to filter only the keyboard events).
Before:
KeyPress event, serial 42, synthetic NO, window 0x600001,
root 0x2ac, subw 0x0, time 3805675, (264,614), root:(1229,650),
state 0x0, keycode 64 (keysym 0xffe9, Alt_L), same_screen YES,
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
KeyRelease event, serial 42, synthetic NO, window 0x600001,
root 0x2ac, subw 0x0, time 3805714, (264,614), root:(1229,650),
state 0x8, keycode 64 (keysym 0xffe9, Alt_L), same_screen YES,
XLookupString gives 0 bytes:
XFilterEvent returns: False
We have two events KeyPress
and KeyRelease
. Please notice the line with keycode 64
and the resulting key Alt_L
key.
After:
KeyPress event, serial 42, synthetic NO, window 0x600001,
root 0x2ac, subw 0x0, time 3841745, (27,367), root:(992,403),
state 0x4000, keycode 64 (keysym 0xffeb, Super_L), same_screen YES,
XKeysymToKeycode returns keycode: 133
XLookupString gives 0 bytes:
XmbLookupString gives 0 bytes:
XFilterEvent returns: False
KeyRelease event, serial 42, synthetic NO, window 0x600001,
root 0x2ac, subw 0x0, time 3841776, (27,367), root:(992,403),
state 0x4008, keycode 64 (keysym 0xffeb, Super_L), same_screen YES,
XKeysymToKeycode returns keycode: 133
XLookupString gives 0 bytes:
XFilterEvent returns: False
Please notice the new line XKeysymToKeycode
with the remapped keycode 133 and the resulting key Super_L
key.
$ swaymsg -t get_inputs
Input device: Keychron K2 System Control
Type: Keyboard
Identifier: 1452:591:Keychron_K2_System_Control
Product ID: 591
Vendor ID: 1452
Active Keyboard Layout: Keychron
Libinput Send Events: enabled
Input device: Keychron K2 Consumer Control
Type: Mouse
Identifier: 1452:591:Keychron_K2_Consumer_Control
Product ID: 591
Vendor ID: 1452
Libinput Send Events: enabled
Input device: Keychron K2 Consumer Control
Type: Keyboard
Identifier: 1452:591:Keychron_K2_Consumer_Control
Product ID: 591
Vendor ID: 1452
Active Keyboard Layout: Keychron
Libinput Send Events: enabled
Input device: Keychron K2 Keyboard
Type: Keyboard
Identifier: 1452:591:Keychron_K2_Keyboard
Product ID: 591
Vendor ID: 1452
Active Keyboard Layout: Keychron
Libinput Send Events: enabled
sudo apt install libinput-tools
sudo libinput debug-events
See this example:
https://github.com/mpsq/dotfiles/blob/master/.config/libinput-gestures.conf
Sway sees the following "mouse/touchpad" devices on my Thinkpad:
Input device: TPPS/2 IBM TrackPoint
Type: Mouse
Identifier: 2:10:TPPS/2_IBM_TrackPoint
Product ID: 10
Vendor ID: 2
Libinput Send Events: enabled
Input device: Synaptics TM3276-022
Type: Touchpad
Identifier: 1739:0:Synaptics_TM3276-022
Product ID: 0
Vendor ID: 1739
Libinput Send Events: enabled
I see some ways to accomplish this.
Input device: Keychron K2 Consumer Control
Type: Mouse
Identifier: 1452:591:Keychron_K2_Consumer_Control
Product ID: 591
Vendor ID: 1452
Libinput Send Events: enabled
$ libinput list-devices
Device: Keychron Keychron K2
Kernel: /dev/input/event16
Group: 5
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
Device: Keychron Keychron K2
Kernel: /dev/input/event17
Group: 5
Seat: seat0, default
Capabilities: keyboard pointer
Tap-to-click: n/a
Tap-and-drag: n/a
Tap drag lock: n/a
Left-handed: disabled
Nat.scrolling: disabled
Middle emulation: disabled
Calibration: n/a
Scroll methods: button
Click methods: none
Disable-w-typing: n/a
Accel profiles: flat *adaptive
Rotation: n/a
MouseKeys
XKB extension to remap keys to mouse movements (this is an X11 feature, nothing to do with Wayland but in theory wlroots/sway support XKB key customizations so this XKB Option should work)Problem: it is meant to use with the numeric keypad. By default mapped to Shift+Numlock modifier. Customizing these two things looks hard.
References:
https://www.x.org/releases/X11R7.6/doc/kbproto/xkbproto.html#the_mousekeys_control
The MouseKeys control lets a user control all the mouse functions from the keyboard. When MouseKeys are enabled, all keys with MouseKeys actions bound to them generate core pointer events instead of normal key press and release events.
On X11 you enable it with: setxkbmap -option keypad:pointerkeys
and customize the parameters with: https://unix.stackexchange.com/questions/609367/setting-pointerkeys-numpad-as-mouse-keys-parameters-acceleration-delay-etc
KeySyms Used to Control The Core Pointer. To start with, I'm probably interested in: POINTER UP
, POINTER DOWN
, POINTER LEFT
and POINTER RIGHT
.
Controls for Using the Mouse from the Keyboard
What's the difference with Pointer_EnableKeys?
Reference: https://wiki.archlinux.org/index.php/X_KeyBoard_extension#Mouse_control
Problem: could not figure out how to implement the above suggestion
libinput
to remap a key to a POINTER_MOTION eventFor a starting point, see the mousemapper.sh script (uses evemu-tools to simulate a device)
# libinput debug-events
event5 POINTER_MOTION +4.08s -4.74/ 0.00 ( -9.00/ +0.00)
event5 POINTER_MOTION +4.09s -4.74/ 0.00 ( -9.00/ +0.00)
event5 POINTER_MOTION +4.09s -4.21/ 0.53 ( -8.00/ +1.00)
event5 POINTER_MOTION +4.10s -3.68/ 1.05 ( -7.00/ +2.00)
PAGE_DOWN
event (EV_KEY event)evemu-event /dev/input/event16 --sync --type EV_KEY --code KEY_PAGEDOWN --value 1 &&
evemu-event /dev/input/event16 --sync --type EV_KEY --code KEY_PAGEDOWN --value 0
evemu-event /dev/input/event6 --sync --type EV_ABS --code ABS_MT_POSITION_Y --value 600
evemu-event /dev/input/event6 --sync --type EV_REL --code REL_Y --value 10
I wrote a proof of concept script (filter.py
) and talked with the libinput maintainer, this is a dead end.