burning broccoli

keyboard shortcuts to focus applications using python-wnck

In a previous post I fiddled a bit with python-wnck and made a small script that bound <Super>P key to activating previous focused window, i.e. last app you where looking at. This was kind of useful since I often find myself spending way to much time and effort jumping between applications. Window lists,pagers and good looking compiz effects that does the same thing all have one thing in common, I have to identify a name, image or icon and select it. In short, I have to search for it.

You may think I have very little patience, pressing TAB a couple of times to find the window of an app can’t take that much time, can it? Well, no, not really - but since I’m programmer I tend to work with multiple applications at the same time (email,browser,eclipse,spotify,terminal(s),nautilus etc) and I switch between them a lot in one day. Actually it’s not the speed that bothers me, more that I already know which window/application I want and it’s frustrating to have to search for it every damn time!

So what’s my brilliant solution to this? Well my first thought (obviously) was some kind of direct neural interface so that the computer could just infer what I wanted before I even knew wanted it. But since that is a bit too much to engineer on one lunch break I opted for a simpler solution: creating a couple of shortcuts for my most used apps.

The script below does half of the job, it tries to find a window matching the supplied application name. If it does gives it focus. If not it will try to start it.

The script takes one or two arguments, the first is the application name as it is in the window list. If that is the same as the executable your’re all set. Otherwise the second argument is the executables name.

A couple of examples

$ ./activate.py evolution
$ ./activate.py Terminal gnome-terminal

I use CompizConfig Settings Manager and to set global key bindings, so now whenever I tap <Super>T the gnome-terminal springs to life.

Here’s the script, the only requirement is python-wnck.

#!/usr/bin/python2.6
import wnck
import sys
import time
import subprocess as sub

if len(sys.argv)  []"
    sys.exit(1)

name = sys.argv[1]
timestamp = int(time.time())

screen = wnck.screen_get_default();
screen.force_update()
wins = screen.get_windows()
for win in wins:
    app = win.get_application()
    if app is not None:
        if name == app.get_name():
            geo = win.get_geometry()
            screen.move_viewport(max(geo[0],0),max(geo[1],0)) #bugs a bit, unclear why
            win.activate(timestamp)
            sys.exit(0)
            
#if we get this far we didn't find the program, let's start it
if len(sys.argv) >= 3:
    sub.Popen(sys.argv[2],shell=True)
else:
    sub.Popen(sys.argv[1],shell=True)
comments    Add a comment    Posted 2 years ago

listing windows with python-wnck

So as I said in my previous post I’ve recently found the nice litte libwnck and it’s python bindings.

There are lots of fun things you can do with it, try exploring it with ipython and you’ll see what I mean.

Anyways I wanted to share a little snippet of code with you, this will list all windows and print out their name in the form application name:window name

#!/usr/bin/python2.6
import wnck

screen = wnck.screen_get_default()
screen.force_update() #updates the window list
wins = screen.get_windows()
for win in wins:
    app = win.get_application()
    win_name  = win.get_name() or ''
    app_name = app and app.get_name() or ''
    print '%s: %s' % (app_name,win_name)

comments    Add a comment    Posted 2 years ago

python-wnck

I just found out about a nifty litlle library called libwnck and it’s python bindings are in the ubuntu repositories under the name python-wnck. Its all about window management. It’s meant to be used for applications like window lists and workspace switchers etc. You can maximize windows, change current workspace etc.

So the first thing I did (naturally) was to write a little script that can change to previously activated window, which is nice to have when jumping frequently between two windows (like eclipse and chromium). To bind a global key it uses a library from Project Hamster which in turn uses a lib from Tomboy, don’t ask me why… Anyway, this means that you also need to install the package hamster-applet to try out this script. It also has some other problems, activating a window on a different workspace doesn’t work. I’ll fix that later.

Installing and running

Just copy the script into a text editor, save it as focus_last.py or and run it with python focus_last.py

The keycode for focusing the last window is <Super>P

#!/usr/bin/python2.6
#   Copyright David Jensen 2009
#   This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <>.

import gtk
import gobject
import wnck
import hamster.keybinder as keybinder
import sys

import time
KEY_COMBINATION = '<Super>P'

class FocusShifter(object):
    def __init__(self):
        self.last_window = None       
        try:
            print 'Binding shortcut %s to focus last window' % KEY_COMBINATION
            keybinder.tomboy_keybinder_bind(KEY_COMBINATION, self.focus_last) 
        except KeyError:
            # if the requested keybinding conflicts with an existing one, a KeyError will be thrown
            print 'Key binding conflict, exiting'
            sys.exit(1)
        self.screen = wnck.screen_get_default();
        
    def focus_last(self):
        timestamp = int(time.time())
        win = self.screen.get_previously_active_window()
        #print "Prev win",win
        if win is not None:
            win.activate(timestamp) #not sure what timestamp should be, but this seems to work
            
f = FocusShifter()
gobject.MainLoop().run()
 
comments    Add a comment    Posted 2 years ago

ELIZA

Eliza is a neat little program created in the 60s by Joseph Weizenbaum. It’s been around a long time. I heard about it the first time during my university studies and the first version i tried was the ‘doctor’ in emacs (Emacs rules, vim should die!).

Anyway, a long story short, a friend of mine starting to talk about it one night while we where chucking down some beers and listening to stand up comedy. I don’t know why but it stuck in my mind so I googled it a bit. My first idea was to see if there where a python implementation (I’m python biased when I have the luxury to choose), and sure thing there was one, eliza.py, with BSD license. It was nice and simple, using regular expressions for most of the work. A bit old though, had to change a import from ‘whrandom’ to ‘random’.

After tinkering around a bit it struck me that the simplest and most portable solution (webwise) would be a javascript implementation. So I made a simple jQuery plugin of it.

To try or download go to http://davidlgj.github.com/eliza-jquery/

comments    Add a comment    Posted 2 years ago

OK so I stayed

Yep. Finally decided. I’m staying here.

comments    Add a comment    Posted 2 years ago