Manipulating the windows upon your desktop
Posted by Steve on Thu 19 Jan 2006 at 09:19
If you're like me you'll most likely use a wide variety of desktop applications, and spend a lot of time setting up your desktop first thing in the afternoon when you login. Minimising some applications, setting others up to be visible upon all virtual desktops, etc. Even if you have a basic window manager you can automate this activity using Devil's Pie.
Devil's Pie is a simple utility, inspired by the Sawfish's matched windows option, which allows you to conduct actions upon desktop windows. Using it is a simple matter of creating a configuration file and starting the program when you login.
Note: This introduction only applies to the version of Devil's Pie included in Debian's unstable or testing distribution. The program was rewritten and changed significantly after Sarge was released - so these comments do not apply to Sarge's package.
Installation in the usual Debian manner:
root@itchy:~# apt-get install devilspie Reading package lists... Done Building dependency tree... Done The following extra packages will be installed: libwnck-common libwnck18 The following NEW packages will be installed devilspie libwnck-common libwnck18 0 upgraded, 3 newly installed, 0 to remove and 1 not upgraded. Need to get 208kB of archives. After unpacking 1389kB of additional disk space will be used. Do you want to continue [Y/n]?
Once installed you may configure it by the creation of configuration files saved beneath the directory ~/.devilspie. When the program starts it will execute every file contained in the directory which has a .ds suffix.
As a simple example you can create the file ~/.devilspie/test.ds and insert the following into it:
(debug)
Once you start devilspie this script will be loaded and executed - and you'll see a debug log of every open window upon your desktop as follows:
skx@itchy:~$ mkdir .devilspie/ skx@itchy:~$ echo '(debug)' > .devilspie/test.ds skx@itchy:~$ devilspie Window Title: 'bash'; Application Name: 'bash'; Class: 'XTerm'; Geometry: 739x364+537+24 Window Title: 'emacs@itchy.my.flat'; Application Name: 'emacs@itchy.my.flat'; Class: 'Emacs'; Geometry: 842x639+4+356 Window Title: 'bash'; Application Name: 'bash'; Class: 'XTerm'; Geometry: 739x364+4+416 Window Title: 'bash'; Application Name: 'bash'; Class: 'XTerm'; Geometry: 739x364+4+24
Kill the program via Ctrl-c and we can look at what happened.
As discussed the program reads files named *.ds from the .devilspie subdirectory of your home directory. These files contain "S-Expressions", which are evaluated. What is an S-Expression? Like many things Wikipedia has the answer!
A short overview of S-Expressions is almost certainly going to mention parenthesis "(" and ")", and mention their use in GNU Emacs, Lisp, and Scheme.
Think of them as representations of functions, or data structures, and you'll not be far off.
So, what did (debug) do? Well when the program started it loaded the file containing this setting and evaluated it - calling the debug function built into devil's pie.
Now that we've shown some debug output we'll look at actually using the tool. To repeat some of the output we saw above:
Window Title: 'emacs@itchy.my.flat'; Application Name: 'emacs@itchy.my.flat'; Class: 'Emacs'; Geometry: 842x639+4+356 Window Title: 'XMMS'; Application Name: 'XMMS'; Class: 'xmms'; Geometry: 275x116+894+163
Here we can see several things:
- The title of each open window.
- The "Application Name" of each open window.
- The "Window class" of each open window
- Don't worry about this - if you're familiar with Xlib programming you'll understand, if not you don't really need to know.
- The "Geometry", or dimensions, of the open window(s)
Each of these things can be used by devilspie to identify a window which it can then manipulate.
As a simple example I use the IceWM window manager which supports multiple virtual desktops. When I use that I want to have XMMS appear on each virtual desktop, and be minimised by default.
To do this I can simply match on the application name, "XMMS", which we saw in the output above and will assume is suitably unique. Save the following to the file .devilspie/xmms.ds:
;; ;; Minimise XMMS when it starts and make sure it is visible on ;; all virtual desktops ;; (if (is (application_name) "XMMS") (begin (minimize) (pin) ) )
Whoah that was complicated wasn't it? Actually if you read it through slowly you'll see it isn't so hard. (Especially if you're comfortable with Scheme, or Lisp).
Here we see several things:
- Comments, which are lines starting with ";".
- Function calls
- "(if ...)"
- "(minimize)"
- "(pin)"
- Helpers:
- "(begin ..)"
Function calls are always made with the form "(function Name [additional arguments])", so to call a function "
(foo)
To call it with a single argument it would be:
(foo "test")
Many functions are built into the application, these are what we use to do the job of manipulating windows. Builtin functions include:
Maximise the current window.
Minimize the current window.
Allows you to resize windows.
Set the given window to be fullscreen.
Give the given window the focus.
Center the given window on your screen.
Maximise the given window.
Minimize the given window.
Move the window to workspace number N
- We have an "if" test - to examine all the open windows on the desktop.
- We see if the application name of the given window is the string "XMMS"
- If this condition is true then we wish to begin several operations:
- We minimize the current (matched) window.
- We pin it to all desktops.
- We then close the opening bracket.
- We then close the opening bracket.
- (window_name)
- The name of the window.
- (window_class)
- The class of the window.
- (application_name)
- The name of the application name.
- (maximise)
- (minimize)
- (geometry)
- (fullscreen)
- (focus)
- (center)
- (maximize)
- (minimize)
- (set_workspace N)
To actually limit our operations to a particular window we can use the if function. This works as follows:
(if "test" (first_function) (second_function) )
If the action in "test" succeeds then the first statement is executed, and if it fails the second is executed. Because only a single function may be used in either case we use the helper function "begin" in our example which allows us to nest functions.
With this in mind we can revisit our example and hopefully it will make more sense:
1. (if 2. (is (application_name) "XMMS") 3. (begin 4. (minimize) 5. (pin) 6. ) 7. )
Taking this line by line:
Other tests are available, working with the application name, the application class, or the window name. These are accessed by the functions:
These variables can be tested using the various logical operations, such as the is function we saw previously. We can also use the functions (matches "xx") or (contains "xx")
As a simple example if we wish to match any window containing the word "emacs in it we can use this:
;; Maximise all windows containing Emacs in their title (if (contains (application_name) "emacs") (maximize))
(Here we don't use (begin ..) since we only wish to take one action - the maximisation.)
Save that to the file .devilspie/emacs.ds, start devilspie, then run Emacs and you should find your window maximized.
If you wish the tests to be applied to all existing windows, not just those you open after running devil's pie then start it with the -a flag:
devilspie -a
[ Parent | Reply to this comment ]
[ Send Message | View Steve's Scratchpad | View Weblogs ]
It isn't.
But if you're not using KDE, or something else with built-in support for scripting then this is a good choice.
(e.g. I use IceWM which has some support for window manipulation, etc, but not a huge amount.)Steve
[ Parent | Reply to this comment ]
for example, the version i use on my Ubuntu 'breezy' desktop (0.10 i believe) requires its configuration to be written in a devilspie-specific XML variant, rather different from Steve's examples above.
one other neat program that i use alongside devilspie is wmctrl, which is a command-line tool that can be used to switch workspaces, make windows 'sticky', and do a few other things that devilspie can't manage by itself. for example, using a combination of wmctrl and devilspie, i've written a wrapper script for launching Firefox that ensures my browser windows are always 'undecorated', maximized, and confined to workspace #2. in addition, whenever firefox is launched this way, wmctrl ensures that workspace #2 gets focus immediately, via the command wmctrl -s 1
(NB: wmctrl counts workspaces starting from zero, so "2" becomes "1").
[ Parent | Reply to this comment ]
Cheers,
Filippo Rusconi
[ Parent | Reply to this comment ]
but heres my problem so far (worked on the much older version when config is in 1 file)
(
if (matches (window_name) "Links")
(
begin
(geometry 956x635+0+0)
)
)
Cannot parse /home/deadcat/.devilspie/links.ds: Unexpected token encountered: 257
i believe its complaining about the geometry. my other .ds files work actually except this one
[ Parent | Reply to this comment ]
anyone using the clearlooks gtk themes?
like this guy: http://david.chalkskeletons.com/openbox.html
i am just talking about the scroll bar for now.
when i preview a clearlooks theme with switch2, i get:
/home/deadcat/.themes/Clearlooks2-Simple/gtk-2.0/gtkrc:55: error: unexpected identifier `scrollbar_color', expected character `}'
[ Parent | Reply to this comment ]
(geometry "956+635+0+0")
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
Other tests are available, working with the application name, the application class, or the window name. These are accessed by the functions: ...should be:
Other tests are available, working with the application name, the window class, or the window name. These are accessed by the functions:
[ Parent | Reply to this comment ]
Piotr
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]
[ Parent | Reply to this comment ]