I'm trying to set some CapsLock + arrows keybindings in xkb
Using ArchLinux, KDE, Xorg
What I'm trying to achieve (wishful thinking)
Ultimately, the perfect solution would be
| No modifier | CapsLock as modifier |
|---|---|
| Left | Home |
| Up | PageUp |
| Right | End |
| Down | PageDown |
while pressing just CapsLock would work on key release, as normal latching CapsLock.
Adding Shift into the mix, or any keybind that uses mapped keys for that matter, should still work.
Moreover, for better compatibility, these bindings should work on keysym level and not using (state, key).
The problem
I don't believe this does what I'd like it to do, and probably doesn't even parse
capslock_nav (added to /usr/share/X11/xkb/symbols)
xkb_symbols "lv3-arrow-nav" {
include "level3(caps_switch)"
key.type = "THREE_LEVEL";
key <UP> { [ Up, Up, Prior, NoSymbol] };
key <LEFT> { [ Left, Left, Home, NoSymbol ] };
key <RGHT> { [ Right, Right, End, NoSymbol ] };
key <DOWN> { [ Down, Down, Next, NoSymbol ] };
}
and I've been trying to achieve this by setting CapsLock to ISO_Level3_Shift and using that in symbols declarations, but to no avail.
Progress so far
My changes are visible in KDE's Settings > Keyboard > Advanced list, that was accomplished by adding entry to
evdev.xml, like so
<!-- ... under <optionList> ... -->
<group allowMultipleSelection="true">
<configItem>
<name>capslock_nav</name>
<description>Navigation using CapsLock</description>
</configItem>
<option>
<configItem>
<name>capslock_nav:lv3-arrow-nav</name>
<description>Caps Lock Arrow Navigation</description>
</configItem>
</option>
</group>
and this one to evdev.lst, just to be sure
...
capslock_nav Navigation using CapsLock
capslock_nav:lv3-arrow-nav Caps Lock Arrow Navigation
...
this is also somewhat reflected by setxkbmap:
setxkbmap -print -query
xkb_keymap {
xkb_keycodes { include "evdev+aliases(qwerty)" };
xkb_types { include "complete" };
xkb_compat { include "complete" };
xkb_symbols { include "pc+pl+inet(evdev)" };
xkb_geometry { include "pc(pc86)" };
};
rules: evdev
model: pc86
layout: pl
options: capslock_nav:lv3-arrow-nav
options contain my changes, but it's not included in xkb_symbols.
xkbcomp $DISPLAY - also has no mention of my changes.
I've gone through ArchWiki and various articles online on the topic, but it's a bit complicated. I feel like I'm making some progress, it's just that it's very slow.
EDIT: Progress so far
I've dropped my configs and started working off of xkb#caps hjkl on archwiki
and prepared this config, which I've split into corresponding files
(compat, symbols types)
partial xkb_types "lv3-arrow-nav" {
include "complete";
type "CUST_CAPSLOCK" {
modifiers= Shift+Lock;
map[Shift] = Level2; //maps shift and no Lock. Shift+Alt goes here, too, because Alt isn't in modifiers.
map[Lock] = Level3;
map[Shift+Lock] = Level3; //maps shift and Lock. Shift+Lock+Alt goes here, too.
level_name[Level1]= "Base";
level_name[Level2]= "Shift";
level_name[Level3]= "Lock";
};
}
partial xkb_compatibility "lv3-arrow-nav" {
interpret Caps_Lock {
action= SetMods(modifiers=Lock);
};
augment "complete";
augment "caps(caps_lock)";
}
partial xkb_symbols "lv3-arrow-nav" {
include "pc";
key <LEFT> {
type= "CUST_CAPSLOCK",
symbols[Group1]= [ Left, Left, Home],
actions[Group1]= [ NoAction(), NoAction(), RedirectKey(keycode=<LEFT>, clearmods=Lock) ]
};
key <UP> {
type= "CUST_CAPSLOCK",
symbols[Group1]= [ Up, Up, Prior],
actions[Group1]= [ NoAction(), NoAction(), RedirectKey(keycode=<UP>, clearmods=Lock) ]
};
key <RGHT> {
type= "CUST_CAPSLOCK",
symbols[Group1]= [ Right, Right, End],
actions[Group1]= [ NoAction(), NoAction(), RedirectKey(keycode=<RGHT>, clearmods=Lock) ]
};
key <DOWN> {
type= "CUST_CAPSLOCK",
symbols[Group1]= [ Down, Down, Next],
actions[Group1]= [ NoAction(), NoAction(), RedirectKey(keycode=<DOWN>, clearmods=Lock) ]
};
}
which I've validated using xkbcomp, but it still does not behave in expected way.
EDIT2
Well, at least it does something, because this config,
xkb
├── compat
│ └── capslock_nav
├── rules
│ └── evdev
├── symbols
│ └── capslock_nav
├── types
│ └── capslock_nav
└── xkb_keymap.xkb
applied using
xkbcomp -I$HOME/xkb/ $HOME/xkb/xkb_keymap.xkb $DISPLAY
at least disables caps lock...
EDIT3
Looks like I've made some progress, by making all actions = NoAction() in symbols definition