If you’ve ever poked around in the KDE or GNOME control panels, you know that the X11 keyboard system is very customizable and, as the KDE keyboard controls clearly show, that it’s all done using a little command named setxkbmap
.
The problem is, Google isn’t very helpful if you want to use this tool directly. All the results seem to tell you to read the raw config files or only give you single, purpose-specific examples.
The good news is that your system actually DOES include a single file equivalent to (and probably the source for) the listings you get in the GUI tools:
/usr/share/X11/xkb/rules/base.lst
For those who haven’t used KDE and need an example, here’s the command I run on login (These can also be specified in xorg.conf via Option directives, but I prefer something I can keep in my roaming profile):
setxkbmap \ -variant altgr-intl \ -option \ -option compose:rctrl \ -option lv3:ralt_switch \ -option terminate:ctrl_alt_bkspc \ -option eurosign:e \ -option nbsp:level3n
As usual, the backslashes are only necessary if you’re splitting it across multiple lines. Here’s what they actually do when used with a us104
or us105
layout:
- -variant altgr-intl
- The default variant of the US 104 layout doesn’t have tertiary symbols like ¢ and þ for AltGr to access, so I’m selecting one that does.
- You can also use the
intl
variant here but, for some reason, it maps ² to AltGr+2 and ³ to AltGr+3 but ¹ to AltGr+Shift+1. - -option
- An empty
-option
resets the layout options so I’m starting from a clean slate. - -option compose:rctrl
- This remaps the
Control_R
keysym toCompose
, so I can access glyphs like ½, ±, and é by typing “Ctrl 1 2
” or “Ctrl + -" or "
Ctrl e '
“. - -option lv3:ralt_switch
- This remaps
Alt_R
toAltGr
, granting access to ¬ (AltGr+\) for making ¬_¬ smileys and giving me simpler key combos for commonly-used glyphs like µ (AltGr+m) and © (AltGr+c). - You can also use
ralt_switch_multikey
here to make Shift+AltGr the Compose key on compact keyboards but my muscle memory has already settled onControl_R
. (Note: Make sure you press Shift first or it’ll just send an ordinary AltGr+Shift) - Note:If anyone knows why ¬ is no longer on
AltGr+`
, please leave a comment. - -option terminate:ctrl_alt_bkspc
- Restore Ctrl+Alt+Backspace as the “Kill X Server” shortcut without relying on a superior but root-privileged and Linux-only config tweak.
- (Again, I like settings I can store in my roaming profile)
- -option eurosign:e
- I’m Canadian, so on the occasions I need to type €, it can take me a while to remember that it has two cross-bars so I know to use “
Compose e =
“. Since my muscle memory already uses “Compose e '
” for é anyway, let’s remapAltGr+e
to €. - -option nbsp:level3n
- Lets me type non-breaking spaces with
AltGr+Space
for those times when
doesn’t have special meaning. - Using
level3n
rather thanlevel3
lets me type thin non-breaking spaces withShift+AltGr+Space
.
The beauty of doing things this way is that you’re unlikely to break things badly. It’s nearly impossible to paint yourself into a corner using variants and options alone (It’s models and layouts you have to be careful with) and, if you ever try to apply your settings to a keyboard they weren’t intended for, an unrecognized variant will abort the process and unrecognized options will simply have no effect.
Have fun and, if you’ve got any other interesting keyboard tweaks, share them in the comments. If I like one that applies to us104
enough to use it myself, I’ll update the example in the post body.
Getting your way with setxkbmap by Stephan Sokolow is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
I have us104 and not nice and easy PC edition but mac (it’s like 105 but without menu key and grave/tilde changed position with grater/lesser).
On top of that my native language is polish so i often use ISO level 3.
To make things even more wild I’m using Emacs a lot.
So this is my maping:
I use setxkbmap for swapping caps and control and changing both alt to ISO_level3_shift:
ctrl:swapcaps,lv3:alt_switch
i couldn’t figure out how to make setxkbmap do things from benth and things from setxkbmap didn’t work in xmodmap neither
content of my ~/.Xmodmap:
! left corner keyboard wierdo as asciitilde
keycode 0x5E = grave asciitilde grave asciitilde notsign notsign
! keyboard tilde as alt (on the right side of left shift)
keycode 0x31 = Alt_L Meta_L Alt_L Meta_L
! keyboard cmd as alt
remove Mod4 = Super_R
keycode 0x86 = Alt_L Meta_L Alt_L Meta_L
! register both new alt’s
add Mod1 = Alt_L Alt_L
Thanks for this one! While playing around, I screwed up and couldn’t use AltGr properly anymore (accidently set it as compose key). Running setxkbmap with an empty -option got everything back to normal.
Pingback: The Telnet Mars » Swapping Control and CapsLock
Good post!!!
I bought a Perfect Choice small wireless keyboard, the problem is it does not have AltGr Key, ¿how do I map the useless windows key as AltGr? Please help me!
First, check what your system sees the desired key as by running “
xev
” in a terminal and pressing that key.Mine sees my right Windows key as “
keycode 134 (keysym 0xffec, Super_R)
“. If yours doesn’t, you may need to use “xmodmap
” to remap it if the following instructions don’t work.Second, run “
grep lv3: /usr/share/X11/xkb/rules/base.lst
” and pick the option for that key. (Internally, X11 refers to AltGr as “Level 3 Shift”)Finally, add an appropriate setxkbmap to run at startup in your X11 session. For my example, it would be this:
setxkbmap -option lv3:rwin_switch
If you want both Windows keys to be AltGr (rather than leaving one free for making interesting global keyboard shortcuts like Play/Pause), use
lv3:win_switch
instead.Pingback: Compose Key on Xfce | The One with the Thoughts of Frans
*Thank you* for writing this post.
As a dvorak user, it took me some time to get my head wrapped around the concept of models, layouts, and variants. I eventually got my dual-variant working as follows:
setxkbmap \
-model pc105 \
-layout 'us(dvorak-intl),us(alt-intl)' \
-option \
-option grp:lctrl_lshift_toggle \
-option compose:rwin
I use Ctrl+Shift to toggle between the two variants, so other people can use my keyboard. I am using a 78-key Apple A1314 Bluetooth keyboard on Debian Squeeze.
Note: it seems like you may omit “-option lv3:ralt_switch” as a parameter, as file /usr/share/X11/xkb/symbols/us , variant “altgr-intl,” seems to call “include “level3(ralt_switch)” to do this as a courtesy.
Also, re: “Note:If anyone knows why ¬ is no longer on AltGr+`, please leave a comment.”:
I checked the X.Org repository…the initial 2004-04-10 commit only had basic and intl variants (us layout). At this point, symbol “notsign” mapped to key BKSL (backslash).
Variant altgr-intl inherits from variant intl. The initial altgr-intl commit did not seem to reference symbol notsign…curious to hear if you found the answer why….
Thanks again.
I’m actually not sure if it was the
altgr-intl
variant. All I know is that, several years ago, when I was running Gentoo, I was running some kind of keymap which gave me the standard US 104 keyboard layout but put notsign onAltGr+`
.In fact, now that I think about it, the
intl
variant would probably have been the first one I tried back then, so the question might actually be “Why did AltGr+1 stop being ¹?”Why does this work:
setxkbmap -option caps:backspace
But this does not:
setxkbmap -option caps:underscore
Because that’s not a valid setxkbmap option. If you look in the file I mentioned (
/usr/share/X11/xkb/rules/base.lst
), you’ll see that the only valid options beginning withcaps:
are these:If you want to remap it to an underscore, you can’t use the convenience shortcuts setxkbmap provides.
Hey, I am new to Linux and am using Xubuntu as well.
I looked around but can’t seem to understand this no matter how hard I try.
Can you tell me how I could swap esc with the tilde: “~” or “`” key?
Thanks.
That’s a little too non-standard for setxkbmap to have an option for it.
What you need is Xmodmap. (It lets you change the mappings between the numeric keycodes returned by the keyboard and the keysyms received by applications)
There are more detailed instructions on the Arch Linux Wiki but the gist of it is:
First, run
xev
in a terminal window, press the keys you want to swap, and look at the keycodes and keysyms it reports for them.(On my computer, keycode 66 =
Caps_Lock
and keycode 49 =grave
orasciitilde
, depending on whether a Shift key is being held.)Second, write a
~/.Xmodmap
file which assigns the symbol from the first to the code from the second and vice versa.For my keyboard, it would look like this:
keycode 49 = Caps_Lock
keycode 66 = grave asciitilde
Third, test whether your desktop automatically runs Xmodmap on login and, if not, add it as one of the programs to be run on login.
Hey man thanks for the reply and thanks for repeating yourself and not asking me to RTFM.
I am not cut out for that : (
Thanks!
On a modern Linux like Ubuntu Precise it is actually /usr/share/X11/xkb/rules/evdev.lst that’s being used by setxkbmap. base.lst is another one of these paste-and-rape decoy files.
I should also point out that ‘setxkbmap […] -print’ creates stanzas ready for feeding to xkbcomp, and for me these stanzas were not harder to understand than setxkbmap command line options. I ended up not using setxkbmap at all because it seemed like obfuscation rather than abstraction in the end, and http://madduck.net/docs/extending-xkb/ came to the same conclusion.
I think the main virtue of this setxkbmap spaghetti is the evdev.xml file which was probably meant for some GUI keyboard configurator wallpaper to parse, but I’m being speculative. Anyway I think humans should create an example stanza with ‘setxkbmap […sane options…] -print’, edit _that_ file, and invoke ‘xkbcomp $DISPLAY’ from xinitrc or Xsession or .config/autostart or whatever you use to twiddle new sessions.
Excellent, very useful post.
I tried to change from a caps:swapescape to a ctrl:swapcaps config, but couldn’t make head or tail of why it wasn’t working till I put a -verbose flag there and saw the hideous mess it had made of combining all my past changes. I didn’t know how to reset it, and this post pointed me to it (using an empty -option) 😀
Although now that I see it, it’s mentioned in the setxkbmap man page under -option, so I guess it’s a typical RTFM fail :\
Thanks, I seem to understand a little more now.
It does not seem to work, though.
My caps-key seems to function as “shiftlock”, as it also capitalizes all keys.
I would like it to behave normal, als “capslock”, and only capitalize the alfabethic caracters.
As i understood, i shoud run
setxkbmap -option caps:capslock
So i did, but without any result.
What’s wrong?
Did you try
setxkbmap -option -option caps:capslock
to reset any previous directives?Also,
setxkbmap -verbose
will tell you what state you’re currently in so you can use a bare-option
to reset it and then set only the bits you want to keep.Thank you Stephan, very helpful post. Appreciate you pointing out the symbols file. Cheers.
Can I use this to do something with my FN keys? Xev recognizes the keys, so I know they work. But they all give identical output when I type them in a terminal. I don’t know if that means the OS doesn’t recognize them or if there’s something else going on. But I would like to use the FN keys for various functions… oddly enough.
What do you mean by “they all give identical output when I type them in a terminal”? Do you mean with or without xev?
If they give identical output when pressed outside xev, that’s not surprising for non-standard keys. The terminal doesn’t know what to do with them.
If they give identical output inside xev, then we’ll need to adjust a lower level of the system so that the differences are visible to X.org.
Here’s an example of the relevant bits from xev when I press my left and right Windows keys so you know what to look for in xev’s output:
state 0x50, keycode 133 (keysym 0xffeb, Super_L), same_screen YES,
state 0x10, keycode 134 (keysym 0xffec, Super_R), same_screen YES,
If xev is seeing them as different keys, then you want to do one (or both) of these things:
If xev isn’t seeing them as different keys, then I’ll need to know what hardware you have before I can help further. (eg. Before I moved to a mechanical keyboard, I used to have a first-generation Logitech G15 Gaming Keyboard and I had to install g15daemon to get xev to see events from the macro keys.)
Sorry, I should have been clearer. Xev reads F1-F12 just as you would expect. But the terminal outputs a tilde for every one of them. I tried using the information from xev to map F4 to a function in my window manager’s config file. It obviously picked up the key press because the cursor changed behavior slightly when I pressed the key. The function didn’t work, but that could be another issue altogether.
I’m on a laptop, which complicates things from what I understand. The function keys are also the multimedia keys. But, like I said, xev recognizes the function keys when I use the “fn” modifier.
Yeah, that’s normal. In fact, on my system, F1 through F4 show nothing in the terminal when I press them, as it should be. (The tilde happens because the system is mis-translating input it doesn’t use.)
It’s the same sort of thing as with Print Screen and Pause. There is no typable character that those keys represent and you haven’t bound any action to them, so they do nothing. (By contrast, Home and End have no typable characters, but they do have actions bound to them.)
What do you want them to do?
I don’t have uses for all of them at the moment. Although it would be nice to connect PrtSc to my screenshot tool. There’s an odd concept, right?
I want to connect some of the function keys to a bash script I’m working on. The goal is to have them select sub-directories in my wallpaper directory so that I can choose different “moods” for the changing background. I don’t know if I can use function keys to directly export a value to a variable or if they’d have to call a script that exported. The basic idea is that if I want to look at mountain scenes for a while I press F3. When I get bored staring at mountains through the terminal I can hit F1 and stare at fast cars for a while. It’s just a slightly more focused randomness. I don’t like the contrast of suddenly going from an underwater scene to some bold abstract design. But I also don’t like staring at the same picture for hours or having to jump through hoops to change it when I get bored of it.
Doing some more research it seems I may have to install xbindkeys to make this happen. I haven’t seen a clear way of doing it with either setxkbmap or xmodmap. Why does it take 17 programs to get a single keyboard to function properly?
setxkbmap and xmodmap are needed because, for historical reasons, X11 has two different layers to how it maps raw keycodes (numbers) from the keyboard into names that programs can listen to.
The reason you need something like xbindkeys is because, once you DO have the key mapped to a name, you still need a program to listen for the key and actually do something in response.
As for xbindkeys, you probably don’t need it. Most desktops have global hotkey support built in. (For example, in KDE 4, it’s under System Settings > Shortcuts and Gestures > Global Keyboard Shortcuts.)
As for what you want, it’s not strange at all to bind Print Screen to screenshot-taking. In fact, KDE binds it to “launch KSnapshot” by default.)
The only tricky part is that you’ll probably want to leave your function keys free for some applications to use. For example, F3 for “Find Next”… so i’d suggest binding to something like Win+F3 instead, since no applications bind to the Windows key as far as I know.)
As for setting the background, how to do that depends on which desktop you’re running. (Because, for there to be a standard for it, desktop developers would have to think it’s actually a good idea for programs to be able to change your background without asking.)
I don’t technically run a desktop. I’m using the i3 window manager. It is pretty much strictly a window manager. The mechanism for using key bindings via the WM is pretty klunky and it doesn’t seem to accept function keys anyway.
The script uses feh to display the background. I was calling feh with different arguments for different workspaces from the WM config file. But that just randomly picked an image from a set drectory each time I switched workspaces. So I decided to write a script to do everything I want in a wallpaper-changer. It’s quite a learning experience.
I hadn’t thought about the fact that some programs use the fn keys. That’s definitely a problem. A quick test in the Kate text editor shows at least four fn keys used for things already. And I’m sure it’s not the only one. I’ll definitely need a modifier. I’m already using the Super key to handle all the functions of the WM. I guess it wouldn’t hurt to use it with the fn keys, if I can. Thanks for the tip.
Then, for the purposes of this problem, your desktop could be considered to be a nebulous “homemade” since you pick-and-choose the APIs for binding global hotkeys and setting the desktop background.
For my own cobbled-together desktop environments, I actually prefer a tool named Nitrogen over feh because it gives these nice features:
--save
to your command-line when setting backgrounds and then putnitrogen --restore
in your startup script.(And, for KDE 4.x, I wrote a script to automate the process of extracting properly-positioned rectangles from a multi-monitor background when setting it to force KDE to give the appearance of spanning across all monitors.)
Since you’re piecing together your desktop from single-purpose bits, you will want something like xbindkeys. However, be aware that I ran across a bug in some desktops’ xbindkeys support which required me to
touch ~/.xbindkeys.noauto
and then manually add it to my list of auto-started programs.I actually prefer to do my scripting in Python because I’ve found shell script makes it hard to write clean, robust code. Here are some of the things which make Python a better shell script than Bourne-family shell scripting:
try
/except
for error-handling (Do X. If it raises error Y, run code Z.)try
/finally
for cleanup (eg. Makes it easy to ensure that your temporary files/folders get deleted even if something goes wrong.)shlex.split
function (Parse command-line quoting in untrusted strings without risk of running anything)fnmatch
module (Filter lists or test whether strings match based on shell-style globbing patterns)subprocess
module (Easily call subprocesses, optionally with customized working directories/environment variables/stdin/stdout/etc., without worrying about command-line quoting bugs, and then capture return values/output/etc.)os.walk
(Recursively walk through a tree of folders using a simplefor
loop)shutil
module (Built-in equivalents to commands likemv
andrm -rf
)webbrowser
module (Open a URL in the user’s preferred browser)tempfile.mkdtemp
(A built-in equivalent to themkdtemp
command.)os.path
module (Has functions likecommonprefix
,expandvars
,normpath
,relpath
, andsplit
.)argparse
module (Easily parse command-line input and get--help
for free.)…plus a ton of other useful stuff in the standard library, like gzip, json, csv, hashlib, tarfile, zipfile, etc.
(It also has a nice selection of libraries available that let me do things like D-Bus calls and image manipulation directly rather than waiting for a subprocess to start up and shut down for each one.)
No problem. That’s how I do things. Window management and global hotkeys share Win+… so they don’t collide with application-specific shortcuts. (eg. I have my Audacious Media Player set to pull up the “Jump to Song” dialog when I hit Win+J.)
Nicely formatted response. Wish I knew the code here to do the same. I don’t see a menu to explain the formatting code though.
Anyhow, yes, it seems I am building my own desktop of sorts. Primarily because I don’t really like any of the existing ones. The difference between them is mostly cosmetic. I’m actually enjoying picking the various programs myself and trying to make them appear cohesive. I have a very long way to go. It’s especially fun since this is the first tiling WM I’ve used. I doubt I’ll ever go back to a stacking WM now.
I’ll give Python a look. You’re right about arrays in bash… and that’s a critical part of what I’m working on. I’ve just always considered bash to be the base on which everything else was built. It never occurred to me that it’s just another scripting language. I’m rather new to this level of coding. So I really don’t know the differences between the languages and how one may be more useful for my application than another. I definitely don’t want to spend hours working around the limitations of bash only to discover I could have done it all in three lines with another language.
As far as feh vs nitrogen, I’m not sure it matters. I know I looked at both when I was sorting out what to use to display the background. I don’t recall with certainty, but I think I chose feh precisely because it had fewer options. That sounds odd, I’m sure. But I was looking for something simply to display the background. All the extra features were just added complexity to worry about. If needed, I can use the script to save and restore the current wallpaper. But that isn’t really a concern I have. If I ever decide to share the script I may add that option in case others want to save their spot.
There used to be instructions below the comment box before WordPress upgraded them away. I’d patch the theme to add them back, but I keep meaning to find time to replace WordPress entirely, so I’m not sure if it’d be worth the effort.
Basically, WordPress-based blogs allow you to use a safe subset of raw HTML. (I used “blockquote”, “ul”, “li”, “a”, and “code” tags in that post)
I’ve been meaning to switch over to a tiling WM but I don’t have time to let my productivity dip while I learn a new set of keybinds completely from scratch. To make up for that, I’ve been planning to write an
rc.lua
for AwesomeWM which gives me the behaviour I currently enjoy from Kwin plus support for switching into tiling. Then I can slowly wean myself off the stacking paradigm.It’s getting a little off-topic, so we’ll want to continue this via e-mail, but feel free to ask me about how to accomplish things in Python. (The higher-level, the better)
In fact, if you want to send me some snippets you’ve written in bash, I’d be happy to show you how they’d look in idiomatic Python.
Fair enough. I sort of approached it from the opposite direction, starting with Nitrogen handling everything and then scripting changes to what its
--restore
would do next time I restarted.The caps lock key is positioned exactly as it was on the old mechanical typewriters.
the machines the pinky never was strong enough to accidentally flip on.
Changing the caps lock to escape or control might be useful but so is having a caps lock – but not one that accidentally turns on, so wouldn’t it be sane to have cap_lock act like a shift, but meta+caps_lock = caps_lock ?
How to do that?
It’s certainly possible to toggle the caps_lock state without it being bound to a physical key. For example,
xdotool key Caps_Lock
will cause the key to be pressed on the virtual keyboard used for testing and automation. (You can runxinput
in a terminal to see all the keyboards and mice, physical and virtual.)The problem is that X11 doesn’t really have good support for binding combinations like Ctrl+Alt without blocking access to combinations like Ctrl+Alt+Delete, which means your idea for binding Meta+Caps_Lock would require that either Meta or Caps_Lock be a non-modifier key.
(Or that you’ve got the programming skill to write something which intercepts all use of both of those keys and then re-emits the events via the virtual keyboard if an additional key is pressed before either of those keys are released. That’s basically how you accomplish Microsoft’s approach to the Windows key. Bind the Start Menu to “Release the Windows key without having pressed anything else.”)
Have you considered just using an
xmodmap
directive like this to turn Scroll Lock into Caps Lock, since Scroll Lock is so unused that the distros I’ve tested don’t even hook the key up to the internal modifier signal anymore?You can find the keycode by running
xev
and pressing Scroll Lock. Here’s what it looks like on my system:Good article!
I want to map menu key to ctrl.
I tried setxkbmap -option ctrl:menu_rctrl, but it is not working.
Please help!
I figured it out.
I directly edited X11/symbol/pc file.
Mapped to Control_R, and add to control modifier.