Is it possible to use a custom keyboard layout without sudo access? If so, how?
A quick proper answer since I can't comment yet:
As I mentioned on your other question, you'd create your layout files in your home directory (or somewhere else you have write permissions) as a local version of the XKB database directory tree:
$HOME/.config/xkb/
...
├── rules
│ ├── evdev-local
...
├── symbols
│ ├── my-fun-capslock-options
│ ├── my-US-Dvorak-layout
│ └── my-ZWERTY-layout
...
... and then use the -I
option with setxkbmap
:
setxkbmap -I $HOME/.config/xkb \
-rules evdev-local \
-layout my-ZWERTY-layout \
-option myZWERTY:option1,compose:menu,fun:caps_is_insert
The underlying command for setting the keyboard is setxkbmap
--- now, looking at its manual pages, it seems that it will read keyboard specification from /usr/share/X11/xkb/
, so that you need to write your modified layout there --- system directory, root access needed.
BUT
I tried this:
strace setxkbmap nonexistant |& grep open
to look at what the command is doing, and look: (partial output)
open("/run/user/1153/gdm/Xauthority", O_RDONLY) = 4
open("./rules/evdev-C.lst", O_RDONLY) = -1 ENOENT (No such file or directory)
open("./rules/evdev.lst", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/X11/xkb/rules/evdev-C.lst", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/X11/xkb/rules/evdev.lst", O_RDONLY) = 4
so it seems that setxkbmap
is also looking in the current directory for the file specification. So maybe (I have no time to test) if you copy all the relevant directory structure from /usr/share/X11/xkb/
in, say, $HOME/myxkb
and then try to issue the command
setxbmap -model pc105 -layout myshiny -variant myvariant
or whatever it may work.
PD: the arch help pages are useful, as ever; a nice command that you can use to see what the keyboard you are using is composed from is this one:
[romano:~] % setxkbmap -print -verbose 10
Setting verbose level to 10
locale is C
Trying to load rules file ./rules/evdev...
Trying to load rules file /usr/share/X11/xkb/rules/evdev...
Success.
Applied rules from evdev:
rules: evdev
model: pc105
layout: es,us
variant: standard_tlde,
options: caps:none,compose:caps,terminate:ctrl_alt_bksp
Trying to build keymap using the following components:
keycodes: evdev+aliases(qwerty)
types: complete
compat: complete
symbols: pc+es(standard_tlde)+us:2+inet(evdev)+capslock(none)+compose(caps)+terminate(ctrl_alt_bksp)
geometry: pc(pc105)
xkb_keymap {
xkb_keycodes { include "evdev+aliases(qwerty)" };
xkb_types { include "complete" };
xkb_compat { include "complete" };
xkb_symbols { include "pc+es(standard_tlde)+us:2+inet(evdev)+capslock(none)+compose(caps)+terminate(ctrl_alt_bksp)" };
xkb_geometry { include "pc(pc105)" };
};
I can recommend this guide if you just want to extend an existing keyboard layout.
The answers by quixotic, are complete, functional and probably what you should normally do. However, if you do not want to copy and modify the rules
files, for whatever reason, here is an alternative solution.
In this case, we will be loading an "xkb keymap file", directly using xkbcomp
.
First, create whatever custom layout or option you want, say in file ~/.config/xkb/symbols/option_file
with contents:
partial hidden modifier_keys
xkb_symbols "new_option_1" {
[...]
};
Next, dump your current layout, using setxkbmap -print > ~/.config/xkb/keymap/my_layout
. (Note that this does not, necessarily, have to be in the same directory hierarchy as the symbols
file above (or any other files you add), as we will be specifying the path to it explicitly.) This will be something of the form of:
xkb_keymap {
xkb_keycodes { include "evdev+aliases(qwerty)" };
xkb_types { include "complete" };
xkb_compat { include "complete" };
xkb_symbols { include "pc+us+inet(evdev)" };
xkb_geometry { include "pc(pc105)" };
};
To enable your new option, edit the dumped layout, by adding +option_file(new_option_1)
to the xkb_symbols
line, so our example would have become:
xkb_keymap {
xkb_keycodes { include "evdev+aliases(qwerty)" };
xkb_types { include "complete" };
xkb_compat { include "complete" };
xkb_symbols { include "pc+us+inet(evdev)+option_file(new_option_1)" };
xkb_geometry { include "pc(pc105)" };
};
Finally, load the new keymap with: xkbcomp -I$HOME/.config/xkb ~/.config/xkb/keymap/my_layout $DISPLAY
.
References:
http://madduck.net/docs/extending-xkb/
https://www.vinc17.net/unix/xkb.en.html