Showing posts with label xbindkeys. Show all posts
Showing posts with label xbindkeys. Show all posts

Wednesday, July 09, 2014

Debugging and fixing a wmctrl bug in NixOS

Without wmctrl I'm lost. I use it together with xbindkeys so that pressing a combination of keys will raise a window of the desktop (editor, shell, browser, chat, ...).

It turns out however that in NixOS wmctrl didn't work well. I had 3 windows opened, and wmctrl -l only showed one. Since gnome3 is still young in nixos, the first thought was that mutter did something wrong when returning the list of clients, due to some possible packaging mistake.

However, xprop -root correctly listed 3 window ids for the _NET_CLIENT_LIST atom, so mutter did its job.

Therefore it might be a problem of wmctrl. I'm always sure in these cases Debian has a patch, however I wanted to find out by myself.

Let's prepare an environment for hacking wmctrl:

$ nix-shell ~/nixpkgs -A wmctrl
$ unpackPhase
$ cd $sourceRoot
$ configurePhase
$ buildPhase
$ ./wmctrl -l

Ok it runs. Now let's dive into the code.
  1. Open main.c
  2. Search for _NET_CLIENT_LIST
  3. Note the for loop in list_windows function right below, it uses client_list_size / sizeof(Window) in the condition. That may be the culprit. 
  4. We make use of the most advanced debugging technique: before the for loop add a printf("%lu\n%lu\n", client_list_size, sizeof(Window));
Now let's rebuild and run wmctrl:

$ buildPhase
$ ./wmctrl -l

Bingo! client_list_size is 12 (3 windows x 4 byte) while sizeof(Window) is 8 instead of 4. Definitely a bug for 64-bit systems.
Of course Debian has the patch: http://ftp.de.debian.org/debian/pool/main/w/wmctrl/wmctrl_1.07-7.debian.tar.gz

  1. Exit the nix-shell and delete the wmctrl source directory.
  2. Copy debian/patches/01_64-bit-data.patch under ~/nixpkgs/pkgs/tools/X11/wmctrl/64-bit-data.patch.
  3. Edit ~/nixpkgs/pkgs/tools/X11/wmctrl/default and add patches = [ ./64-bit-data.patch ]; in the derivation.
  4. Finally install the patched wmctrl with nix-env ~/nixpkgs -iA wmctrl and see that wmctrl -l now works.
  5. Commit, push to nixpkgs master, profit.

Thursday, March 28, 2013

Switch window by name on Linux - alternative to Alt+Tab

Today I want to share a very simple script that works with most Linux window managers: switch window by name.
It works like this: you press Ctrl+Alt+M, then a dialog appears where you write part of the name of the window, and you'll get switched to the window that matches the provided name.The string your provide will match part of window names in case-insensitive mode.
That means if you have "Foo - Mozilla Firefox" and type in "fire" you'll switch to firefox.

Note: it probably doesn't work with your configuration of awesome wm due to weird focus management.

The first step is to install the necessary packages:
apt-get install xbindkeys wmctrl zenity

With wmctrl we're able to switch to a window by specifying the name, while with xbindkeys we can bind Ctrl+Alt+M to open a zenity dialog then call wmctrl with the provided window name.

The only thing you need is the following file somewhere, let's call it keys.rc:
"WINDOWID='' app=$(zenity --text "App" --title "App" --entry) && wmctrl -R $app"
  control+alt + m

Now run xbindkeys -f keys.rc and we're done! Press Ctrl+Alt+M then type in the name of the window you want to switch to.

We can also add simpler bindings like this:
"wmctrl -R Firefox"
  control+alt + f

Now pressing Ctrl+Alt+F will switch to a firefox window.

Note that if it matches more window, only one of the window will be chosen obviously. The choice depends on xbindkeys.

I'm not using Alt+Tab anymore.