Archive for May, 2010

How To Remap Caps Lock To Escape

So I think we can all agree that whoever decided the caps lock key should get prime real estate should be stoned.  Seriously, it’s right where an extremely useful key could be placed…like escape!  Keys that can be toggled on and off, especially by software means, should not be given such huge buttons placed where other useful buttons should be in the first place.  I am a heavy Vim user, so I use escape A LOT to change modes.  If you’re an emacs *shuddersss* user you can remap this key to control but I am not going to tell you how as you should be using Vim anyway :p  I’m just kidding, it’s a simple word substitution I will show in a minute.  In order to get this setting to effect both console and X usages we will need to edit two different sets of files, both of which I will demonstrate.  This is a Linux/UNIX specific tutorial so apologize to you poor Windows and OS X users who are stuck out in the cold.  If it is demanded, I can show how to do this in OS X as it is a pain in the ass, but unfortunately I have no idea how to do this in Windows.  Sorry about your luck   :-|   Anyways…

In order to get this to work in the console for all users, stick this in your /etc/rc.local (this is an Arch Linux example, you just need this to be in a file that will be ran as root during startup):

(echo `dumpkeys | grep -i keymaps`; echo keycode 58 = Escape) | loadkeys -

This should make it so Caps Lock is remapped to escape at all times in the virtual consoles. If you wanted it to be remapped to control, just substitute “Control” for “Escape” there towards the end…simple enough.  Or you could just use Vim :)

In order for this to take effect in X, I use Xmodmap to remap the keycodes. The way I do it is to stick these two lines in the file ~/.Xmodmap:

remove Lock = Caps_Lock
keysym Caps_Lock = Escape

Then in my .xinitrc have a line that says:

xmodmap /home/al3k/.Xmodmap &

You can run that command in the console and, since it will be run at every boot, it will be a persistent setting. Having escape at a much more reachable position makes productivity soar…at least for me. It allows me to Vim and Vimperate at a much faster speed. Hope this helps! Post comments if you have any questions, I am happy to help.

Toggling Drivers With Keyboard Shortcuts

I have a Macbook Pro which has a large touchpad that is really sensitive so its always clicking on stuff while I am typing, which is extremely annoying. I have tried going the syndaemon route to disable the touchpad while typing, but it is very unreliable in my experience and I’d rather go about doing this without another process running in the background. This is a Linux specific tutorial, so if you want to know how to do this on Windows or OS X I apologize as this will not work for you. I do most everything in a terminal except web browsing (and even then I use elinks unless I need flash or fancy javascript), DWM is my window manager and I use vimperator with Firefox so I hardly use my mouse as it is.  Who needs a mouse when I already have 100 buttons at my disposal?  Anyway, I was looking for a way to quickly toggle my touchpad driver on and off so I can use it when I need to and then quickly get rid of it again.  While this guide is specifically for DWM and my Macbook touchpad, if you alter the scripts for your particular drivers and set up the keyboard shortcuts with whatever window manager you use, this guide should be fairly universal.

Here is a simple bash script that will determine whether a module is loaded and insert/remove accordingly:

#!/bin/bash
if [ $(lsmod | grep bcm5974 | wc -l) = "0" ]
then
# mouse driver not found, need to load
modprobe bcm5974
swarp 512 300
else
# mouse driver found, need to remove
swarp 9999 9999
rmmod bcm5974
fi

I have this script located in /usr/local/bin/toggletp.  bcm5974 is the name of the macbook’s touchpad driver and swarp is a program that will move your cursor to specific coordinates on the screen.  Unfortunately there is no way to disable the mouse cursor in X so my solution was to move the cursor to the very bottom right corner of the screen where it can’t be seen when the module is disabled.
Now we are going to need a simple sudo wrapper since modprobe/rmmod require root access:

#!/bin/sh
sudo /usr/local/bin/toggletp

Now in order for you to be able to execute this script requiring root access without a password, you will need to edit the sudoers file to allow this. I tried using setuid originally until I realized that setuid doesn’t work on shell scripts :(

Here is the line I use in my sudoers file:

%wheel ALL=(root) NOPASSWD: /usr/local/bin/toggletp

Wheel is just a group that my user belongs to. This is just the bsd style way of managing root access. This line allows you to execute the toggletp script as root without a password. Make sure that you set the executable bit on these scripts and lock down access since they can execute commands as root without passwords.

Now, these are the relevant lines from my DWM config.h so set the keyboard shortcuts for my scripts:

/* commands */
static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL };
static const char *termcmd[]  = { "urxvt", NULL };
static const char *tpcmd[] = { "/home/al3k/build/toggletp", NULL };
static const char *mpdpause[] = { "mpc", "toggle",NULL };
static const char *mpdnext[] = { "mpc", "next", NULL };
static const char *mpdprev[] = { "mpc", "prev", NULL };

static Key keys[] = {
/* modifier                     key        function        argument */
{ MODKEY,                       XK_p,      spawn,          {.v = dmenucmd } },
{ MODKEY,                       XK_Return, spawn,          {.v = termcmd } },
{ MODKEY,                       XK_z,      spawn,          {.v = tpcmd } },

The third line and the last line are the chunks relevant to this guide. Copying these lines into your config.h will make it so that every time you press MODKEY+Z, it will execute the sudo wrapper for toggling your driver (mine is located in the build directory in my home folder). Now recompile dwm, reload, and , if everything worked out correctly, you should be able to toggle your laptop touch pad on and off at will with a simple keyboard shortcut!

Leave comments if you have any questions, I’m happy to help. Also, I cannot take credit for the touchpad driver bash script, a friend of mine came up with it and I modifed it for my use.

Media Keys with MPD and DWM

To continue on my last post about mpd, I went on to figure out how to get my Macbook Pro’s media keys working with MPD and DWM. To catch those up who don’t know the acronyms, MPD is Music Player Daemon which is just a daemon that runs in the background that plays music and is controlled by clients (my personal favorite is ncmpcpp). DWM stands for Dynamic Window Manager, which is a super minimalist tiling window manager that is customized entirely by editing its source code and is also characterized by being super freaking awesome. This technique should work for any extra keys you may have on your keyboard and not necessarily just Macbooks.

What you’re going to need: xmodmap (to map keycodes to octal codes so dwm doesn’t bitch), xev (to get the correct keycodes for the keys you want to use), and mpc (just a simple cli client for mpd that takes simple parameters).

Here we go:

Use this snippet to start xev and get only the info that we need:

xev | grep -A2 --line-buffered '^KeyRelease' | sed -n '/keycode /s/^.*keycode \([0-9]*\).* (.*, \(.*\)).*$/\1 \2/p'

Once that has started, the press the keys you want to use for play, next, previous etc and write down the corresponding keycodes so you remember.

Use your favorite editor to open up .Xmodmap (name doesnt really matter, this is just what I use) and insert something to this effect:

remove Lock = Caps_Lock
keysym Caps_Lock = Escape
keycode 171 = F30
keycode 172 = F31
keycode 173 = F32

Map whatever your keycodes might be to F and then some incremental number (F30,31,31, etc etc. I just used arbitrary numbers). You can ignore those first two line, I use them to remap my capslock key to escape (which is extremely useful if you’re a vim user…or you just realize how useless capslock is).

The run this to make the keymaps stick:

xmodmap ~/.Xmodmap

In order to make that change permanent you will need to add that line to your .xinitrc as well.

Now to editing the dwm code. These are the relavent lines from my config.h:

/* commands */
static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL };
static const char *termcmd[]  = { "urxvt", NULL };
static const char *tpcmd[] = { "/home/al3k/build/toggletp", NULL };  
static const char *mpdpause[] = { "mpc", "toggle",NULL };
static const char *mpdnext[] = { "mpc", "next", NULL };
static const char *mpdprev[] = { "mpc", "prev", NULL };

static Key keys[] = {
    /* modifier                     key        function        argument */
    { MODKEY,                   XK_p,        spawn,          {.v = dmenucmd } },
    { MODKEY,                   XK_Return, spawn,          {.v = termcmd } },
    { MODKEY,                   XK_z,        spawn,          {.v = tpcmd } },
    { 0,                            XK_F31,     spawn,          {.v = mpdpause } },
    { 0,                            XK_F30,     spawn,          {.v = mpdnext } },
    { 0,                            XK_F32,     spawn,          {.v = mpdprev } },

You will want to add the mpc and mpd lines exactly as they look there, carefully minding the ,’s and ;’s since this is C code. The 0′s where the modkey should be just mean that there is no modifier key required. Recomplie DWM, reload, test and voila! The keys you mapped should now control mpd as you wish!

Leave some comments if you have any questions, I’ll be happy to help.