Monday, July 12, 2010

If you ever wanted to change xkb layout with a simple command

If you have more than 2 keyboard layouts, you would want to switch between them rapidly.
Assigning a shortcut combination to every layout is what you want then.
(I.e. Ctrl+Shift+1 for english, Ctrl+Shift+2 for russian, Ctrl+Shift+3 for german etc).

However, while in Windows this can be done with some simple clicking in the keyboard layout configuration, Linux (at least the one running Gnome/Xfce) by default only provides cycling through the layouts.

Of course, there are always custom key shortcuts to every terminal command. What command would you choose then? After some time in google and man, you would eventually come up with setxkbmap .

I used this approach for a while, actually feeling that the cheese cake was just ordinary, not perfect at all:
1) It's not fast: setxkbmap resets the whole map. It takes some time, up to a second.
2) Setting "setxkbmap ru" would leave you without many standard shortcuts. E.g. Ctrl+t would
not work in browsers, since it would become Ctrl+ะต. For a new tab in a browser you would have to switch to english layout, Ctrl+t, switch back to russian layout.
3) Ok, actually, the problem in 2 can be avoided if you use, say, "setxkbmap ru,us" for russian
and "setxkbmap us,ru" for english. There's a catch: if you switched the layout via some graphical ide (e.g. xfce4-xkb-plugin) or with a standard cycling combination (e.g. smth like Ctrl+Alt), you will get your shortcuts mixed up. The latter action actually increments the index of the current layout (which doesn't get reset with setxkbmap). So after incrementing index from 0 to 1, "setxkbmap ru,us" will activate the "us" layout not the "ru" one.
4) Even if you somehow manage to get things right experimenting with stuff in 3), this is
really evil. What if I want to add another layout? Should I change half of the shortcuts I use? In fact, I just like to define layouts via some graphical settings editor, and not repeat any complex options with setxkbmap's.

Simply setting the above-mentioned index would do the trick. I didn't find any ubuntu util
that would allow me to do that. Looking through the source of e.g. xfce4-xkb-plugin
revealed that XkbLockGroup function would do the trick. And very soon I found a ready code for that here:

Compiling it gives you a nice, little and fast xkbswitch util.
Me, I put it into /usr/bin and use shortcuts to "xkbswitch i" for i=0,...,2 whenever I want to change my layout. Tasty.

P.S. Use -lX11 flag when compiling. The source:

#include <stdlib.h>
#include <stdio.h>
#include <err.h>
#include "X11/Xlib.h"
#include "X11/XKBlib.h"

void PrintUsage();

int
main(int argc, char **argv)
{
int xkbGroup;
if (argc < 2 || (xkbGroup = atoi(argv[1])) < 0 || xkbGroup > 3)
{
PrintUsage();
exit(0);
}


int xkbEventType, xkbError, xkbReason;
int mjr = XkbMajorVersion, mnr = XkbMinorVersion;
Display *display = NULL;

display = XkbOpenDisplay(NULL, &xkbEventType, &xkbError,
&mjr, &mnr, &xkbReason);
if (NULL == display)
{
warnx("Cannot open X display %s", XDisplayName(NULL));
switch (xkbReason)
{
case XkbOD_BadServerVersion:
case XkbOD_BadLibraryVersion:
warnx("Incomatible versions of client and server xkb libraries");
break;
case XkbOD_ConnectionRefused:
warnx("Connection to X server refused");
break;
case XkbOD_NonXkbServer:
warnx("XKB extension is not present");
break;
default:
warnx("Unknown error from XkbOpenDisplay: %d", xkbReason);
break;
}
exit(1);
}

Bool status = XkbLockGroup(display, XkbUseCoreKbd, xkbGroup);

XCloseDisplay(display);

return status ? 0 : 1;
}

void
PrintUsage()
{
printf("Usage: xkbswitch [0-3] sets keyboard layout\n");
}


Update:
In Gnome 3.6+ this does not work anymore. Use instead
"gsettings set org.gnome.desktop.input-sources current i",
where i is the index of your layout.

Wednesday, May 12, 2010

Another one

In an order complete Banach lattice: is any finite-rank positive operator approximable by positive operators having their range in finite-dimensional sublattices?

Nielsen seems to say yes, but I could not repeat the proof.

Wednesday, May 5, 2010

Stupid math question of the day

Sometimes, there are questions that seem to be fairly simple, yet I can't find the answer anywhere:


Will a vector sublattice of a Riesz space generated by a finite set be finite-dimensional?