Wednesday, July 8, 2009

Different font sizes on different X screens

One of my trusty pair of Dell 1905FP monitors finally gave up the ghost. A little shopping around showed that, despite my luddite tendencies, 16:9 widescreen is the way forward. Today my shiny new ASUS VH222H arrived. It looks beautiful, and emacs is enjoying spreading out into the extra space.

However, my monitors are no longer a perfectly-matched pair. Trusty old Dell is plodding along at 1280x1024, and new ASUS on the block is showing off at a mind-expanding 1920x1080. Most of the time this is not an issue, since the Dell displays browsers almost all the of time, while almost everything else (i.e. emacs) happens on ASUS. For terminals on the Dell I have always used a 10-point font, but at higher resolution I need 12-point (I'm not getting any younger, I'd like to continue to see, and you kids get off my lawn).

Rather than using Xinerama or Twinview (I have an Nvidia card), I fire up a separate X screen on each monitor (:0.0 and :0.1). Since I use a tiling window manager (dwm) I never want to share windows across monitors, and this way I can switch desktops (tags) on one monitor without affecting the other. There is just one X server, however, so how to have different font sizes on different screens?

For reference, my window managers are started as follows from ~/.xinitrc:

DISPLAY=:0.1 dwm &
DISPLAY=:0.0 dwm


I set fonts in ~/.Xdefaults. Resources are loaded by xrdb, which preprocesses Xdefaults using the C pre-processor cpp. Using the pre-loaded symbol WIDTH we can test resolution and set font accordingly:

#if WIDTH >= 1600
#define FONT -b&h-lucidatypewriter-medium-r-normal-sans-12-*-*-*-*-*-*-*
#else
#define FONT -b&h-lucidatypewriter-medium-r-normal-sans-10-*-*-*-*-*-*-*
#endif

XTerm*font: FONT
Emacs*font: FONT


We could also test on the symbol SCREEN_NUM (see xrdb -symbols for all pre-loaded pre-processor symbols), but the above is more portable.

Finally, reload resources:

xrdb -load ~/.Xdefaults

Friday, July 3, 2009

Simple biff for gmail

Gmail publishes an atom feed for your inbox. This makes it possible to build a trivial client to show the number of unread messages in your inbox, for use in a statusbar (dwm/wmii bar, conky, etc).

The following shell one-liner does the job, but slowly:

wget -qO - https://username:password@mail.google.com/mail/feed/atom --no-check-certificate \
| egrep '[0-9]+' \
| sed -e 's/[^0-9]//g'


Here's a simple perl script that is about twice as fast:

#!/usr/bin/perl
use strict;
use warnings;

use XML::Atom::Client;

my $api = XML::Atom::Client->new;

$api->username('username');
$api->password('password');

my $feed = $api->getFeed('https://mail.google.com/mail/feed/atom')
or die ("Error: ", $api->errstr, "\n");

print(scalar($feed->entries)||0, "\n");


On ArchLinux this required the following packages: perl-xml-atom, perl-libwww, perl-digest-sha1, perl-datetime, perl-crypt-ssleay.

Using Unix date command for timezone conversion

I do a lot of work with developers in Bangalore, and am always wanting to do date calculations to figure out what time it is there. Using the TZ environment variable, it is easy to do this using plain old date (I am using 7.4 from GNU coreutils).

For example, what time is it right now in India?

$ TZ=Asia/Calcutta date
Sat Jul 4 00:40:41 IST 2009


I want to hold a meeting at 9am, what time will it be in India?

$ TZ=Asia/Calcutta date -d '9am EDT'
Sat Jul 4 18:30:00 IST 2009


There's a meeting on Friday at 4pm in India, what time will it be here?

$ date -d 'Fri 4pm IST'
Fri Jul 3 06:30:00 EDT 2009


For extra goodness, if you use zsh, do TZ=[TAB] and the shell will complete available timezones for you.