10

I have been using a custom keyboard for a while, using the instructions detailed in the Help.Ubuntu tutorial Custom keyboard layout definitions and further explained in this question. I have grown quite fond of this keyboard, but I have recently started using a machine where I don't really have sudo access (or rather, I do have some amount of access, but it is really awkward).

So: is it possible to do an equivalent installation that is only for my user, and which does not rely on administrative privileges? More specifically, if it comes to installing specific packages I'm OK with that, but if it requires substituting files outside of my home directory it gets a lot harder.

4 Answers 4

7

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
1
  • 1
    In the answer to the other question you do list the .lst file explicitly, but, not here — after some testing, it seems that evdev-local.lst is actually necessary for setxkbmap (though evdev-local.xml is apparently not) — so I'd suggest adding it to the tree, here, in case somebody does not read your aforementioned other answer. Btw, the other answer is really amazingly comprehensive!
    – aplaice
    Jul 3, 2017 at 22:22
4

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)" };
};
4

I can recommend this guide if you just want to extend an existing keyboard layout.

2
  • Thank you. It was very easy and works perfectly. Note, however, xkb_symbols "fr" { ... } shall be xkb_symbols "fr" { ... }; (the last semicolon is needed). Otherwise xkbcomp fails due to a syntax error.
    – ynn
    Jun 7, 2020 at 9:18
  • +1, this is the only thing which works for me now. Before it just worked with setxkbmap -v xxx. So at last I used this: setxkbmap <layout-name> <option> -option -print | xkbcomp -I. - $DISPLAY under /usr/share/X11/xkb. I put my layout xxx under symbols and modified evdev.lst file under rules. option is the word you put after xkb_symbols in `the xxx layout file.
    – WesternGun
    Feb 27 at 13:53
3

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

1
  • Sorry, but it expects ~/.config/xkb file, which is nowhere to find.
    – WesternGun
    Feb 27 at 13:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .