Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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.

share|improve this question
add comment

4 Answers

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.

share|improve this answer
add comment

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.

share|improve this answer
add comment
#!/bin/bash
if [[ -e ~/.my.kb.not.dvorak ]] ; then
    sextxkbmap dvorak
    touch ~/.my.kb.is.dvorak 
    rm ~/.my.kb.not.dvorak
fi 
if [[ -e ~/.my.kb.is.dvorak ]] ; then
    sextxkbmap <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.

share|improve this answer
    
This sullotion is a bit messy... i can foresee a small glitch when rebooting, and you are cluttering my ~ directory. But otherwise pretty neat :) –  NixNinja 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
add comment

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

share|improve this answer
1  
I want it to work outside of X aswell :) –  NixNinja Oct 8 '10 at 13:24
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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