Make Terminal recognize PageUp and PageDown when remapped to different keys

I understand Terminal by default doesn't support PgDn and PgUp. I do not have PgDn and PgUp on my keyboard, but have them remapped to different keys currently and therefore Shift+PgDn doesn't work. I have also tried Fn+Up. How can I make Terminal recognize my remapped paging keys?


(comment: you've found XKB! congratulations, it's a hell of a rabbit hole to fall down. note your solution will get blown away the next time ubuntu's xkb-data package updates that file, and will affect any other keyboards you plug in that use the same configuration.)

XKB follows a model called RMLVO -- Rules, Model, Layout, Variant, Options. Your solution alters a system Model file, but a better solution would be to find or create an Option to add your overrides. (evdev is the default Rule for most distributions, and most external keyboards will use a pc model, though laptop internal models may have specific variations that are already close to your usecase. A standard US QWERTY keyboard will use the us layout with no variant, although you might choose the intl or altgr-intl variants if you work with other languages.)

Options are specific overrides to the basic functionality. If you want to turn off CapsLock because that key just sucks, there's already an option for that (caps:none), or you can set it to be an extra Escape key instead (caps:escape). You can see the specific overrides in /usr/share/X11/xkb/symbols/caps; each stanza is a different option you can turn on at runtime.

If you do setxkbmap -print you should get a list of your current XKB setup:

$ setxkbmap -print
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)" };
};

Create your override file:

$ mkdir -p .config/xkb/symbols
$ touch .config/xkb/symbols/pgupdown

Now edit the new file with your favorite editor and throw in the following:

// mapping PgUp and PgDown to other keys
partial alphanumeric_keys
xkb_symbols "rwinmenu" {
    key <RWIN> { [ Prior     ]   };
    key <MENU> { [ Next      ]   };
};

// same but switched
partial alphanumeric_keys
xkb_symbols "menurwin" {
    key <MENU> { [ Prior     ]   };
    key <RWIN> { [ Next      ]   };
};

Now create a base keymap:

$ setxkbmap -print > ~/.config/xkb/mymap

Edit that file, and add your new option into the symbols list in the format +optionfile(function):

xkb_keymap {
    xkb_keycodes  { include "evdev+aliases(qwerty)" };
    xkb_types     { include "complete" };
    xkb_compat    { include "complete"};
    xkb_symbols   { include "pc+us+inet(evdev)+pgupdown(rwinmenu)" };
    xkb_geometry  { include "pc(pc105)" };
};

If you decide later that you prefer PgUp on the Menu key instead, just replace rwinmenu with menurwin there and you're good to go.

Now you can load that file with xkbcomp:

$ xkbcomp -I$HOME/.config/xkb $HOME/.config/xkb/mymap $DISPLAY

Launch xev (from the x11-utils package) and press keys to make sure the changes are loaded:

# sed to scrape out non-kbd events; xev is pretty spammy
$ xev | sed -ne '/^KeyPress/,/^$/p'

If you've gotten everything in the right places, your Menu key should be sending Next events, and the Win_R key sending Prior. If that works, you can add the above xkbcomp command to your .xinitrc or .xprofile so it runs when you log in or start X.

... unless you're running Gnome. (and/or possibly KDE.) Then we get to go further down the rabbit hole, and figure out how to incorporate this new option into system files so the DEs can pick it up as a standard option. Essentially, that will involve

  1. placing your option file in /usr/share/X11/xkb/symbols/ (this is why pgupdown was a good option choice, as there's not a preexisting symbol file with that name)
  2. and then adding lines in /usr/share/X11/xkb/rules/evdev* (to map the optionsfile:function format of the commandline to the +optionsfile(function) used by xkbcomp)
  3. and finally setting the DE to use your preferred layout and options.

Step 2: If you need to go this route, you might need to perform step 2 again after any xkb-related upgrades.

# in /usr/share/X11/xkb/rules/evdev
# find the line that starts "! option = symbols" and add new lines:
  pgupdown:rwinmenu = +pgupdown(rwinmenu)
  pgupdown:menurwin = +pgupdown(menurwin)

# in /usr/share/X11/xkb/rules/evdev.lst
# find the line that starts "! option" and add a new line:
  pgupdown:rwinmenu          PgUp on RWin, PgDown on Menu
  pgupdown:menurwin          PgUp on Menu, PgDown on RWin

# in /usr/share/X11/xkb/rules/evdev.xml
# .... ummm .... ¯\_(ツ)_/¯  .... sorry! ....

Step 3: check to see if localectl is available on your system. localectl can configure the virtual console keyboards as well as setting up a system-default X11 keyboard. Since both options are set up in the rules files, you can use either rwinmenu or menurwin in these commands.

$ localectl set-x11-keymap us pc "" pgupdown:rwinmenu
#  format               [layout] [model] [variant] [option1,...,optionN]

For Gnome, you'll need to use dconf-editor or gsettings:

# set layout/variant
$ gsettings set org.gnome.desktop.input-sources sources "[('xkb', 'us')]"

# set options
$ gsettings set org.gnome.desktop.input-sources xkb-options "['pgupdown:rwinmenu']"

Another option for Gnome might be to disable its keyboard settings; this should allow either the localectl option or the user-config option to remain in effect:

$ gsettings set org.gnome.settings-daemon.plugins.keyboard active false

Troubleshooting: If your changes don't seem to be getting picked up and you're sure you've gotten file formatting right, delete any *.xkm files from /var/lib/xkb/. These are cached precompiled keymaps and may be getting in your way.

Resources:

  • http://madduck.net/docs/extending-xkb/
  • http://apps.jcns.fz-juelich.de/doku/sc/xkbmap
  • https://wiki.archlinux.org/index.php/Keyboard_configuration_in_Xorg
  • https://unix.stackexchange.com/questions/66624/where-is-xkb-getting-its-configuration
  • https://askubuntu.com/questions/451945/permanently-set-keyboard-layout-options-with-setxkbmap-in-gnome-unity

Changing the keys at /usr/share/X11/xkb/symbols/pc seems to work I could not get the other answer above to work. Then you use the new keys with the shift button.

key <RWIN> {    [ Prior     ]   };
key <MENU> {    [ Next          ]   };