I've recently started to learn the dvorak keyboard layout, but I still need to use qwerty sometimes.

I'm looking for a script to toggle between the two keyboard layouts.

Also, I'd like to invoke this script with a hotkey that will work everywhere ( in my DE and in my console. ) Like pressing shutdown in this post.

  • Why would you ever want to change back to QWERTY? ;-) – Kusalananda Jun 9 '17 at 3:51
up vote 3 down vote accepted

You'll have to do this separately for X and for every kind of text console you care about.

If you want to switch between arbitrary keymaps, you need to maintain state, as typically the console won't do it for you. That's what layout switchers such as Gnome's and KDE's do. But if you only want to switch between some well-known keymaps, you can query the console (assuming this feature is available on your console type), obtain the current code sent by a key and decide what to switch to based on that. Here are a few possibilities:

  • If keycode 24 (the number will vary between console types) currently sends q, the current keymap looks like qwerty, so switch to dvorak, otherwise switch to qwerty.
  • If Q and W have adjacent keycodes, it's probably a qwerty layout.
  • Add a fake key in the keymaps and look up its binding.

Here's an implementation for X and Linux, using the W=Q+1 test. Beware, I haven't tested it. Note that the script will usually not be usable through text mode remote logins.

if [ -n "$DISPLAY" ]; then
  if xmodmap -pke | awk '$3=="=" && $4=="q" {q=$2}
                         $3=="=" && $4=="w" {w=$2}
                         END {exit w-q==1}'; then
    setxkbmap us
  else
    setxkbmap dvorak
  fi
elif [ "$TERM" = "linux" ]; then
  if dumpkeys | awk '$3=="=" && $4=="q" {q=$2}
                     $3=="=" && $4=="w" {w=$2}
                     END {exit w-q==1}'; then
    loadkeys us
  else
    loadkeys dvorak
  fi
fi

On X Window, the best place to bind this to a key is using your desktop environment or window manager's key binding feature. You can make the key execute the X-specific part only. Of course, if your DE/WM has a layout switching feature, you might as well use it.

On the Linux console, the possibilities for key bindings are very limited. You can bind a key to the KeyboardSignal symbol. If you're using SysVinit, put kb::kbrequest:/path/to/script in /etc/inittab to run your script (as root!) when the signal is pressed. I don't know how to configure this key's action with Upstart.

Does setxkbmap not work outside X?

setxkbmap \
  -model pc105 \
  -layout 'us(dvorak-intl),us(alt-intl)' \
  -option \
  -option grp:alt_shift_toggle \
  -option compose:rwin

I use it in X and in my terminals. Text "-option grp:alt_shift_toggle" tells setxkbmap to switch layouts when you press Alt+Shift. See /usr/share/X11/xkb/rules/base.lst (Debian Squeeze...ymmv) for more toggle/switch options for switching layouts on the fly.

Create a script:

#!/bin/bash
if [[ -e ~/.my.kb.not.dvorak ]] ; then
    setxkbmap dvorak
    touch ~/.my.kb.is.dvorak 
    rm ~/.my.kb.not.dvorak
fi 
if [[ -e ~/.my.kb.is.dvorak ]] ; then
    setxkbmap <YOURLAYOUT>
    touch ~/.my.kb.not.dvorak 
    rm ~/.my.kb.is.dvorak
fi 

Replace <YOURLAYOUT> with relevant data. Now set up an xbindkeys hotkey-combo to run this script.

  • This sullotion is a bit messy... i can foresee a small glitch when rebooting, and you are cluttering my ~ directory. But otherwise pretty neat :) – Stefan Oct 8 '10 at 13:24
  • I think you probably meant setxkbmap. There's probably a way to find out the current layout instead of trying to track it with dotfiles; possibly setxkbmap -print? – Michael Mrozek Oct 8 '10 at 15:53

Since the keyboard layout is a property of the input device you could set it via xinput. Use xbindkeys to define arbitrary X hotkeys.

  • 1
    I want it to work outside of X aswell :) – Stefan Oct 8 '10 at 13:24

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.