Setting the button order

Old Pink ButtonsUbuntu Lucid Lynx was released last week. It modifies the order of the titlebar buttons so that they all appear on the left-hand side. Some people would like the buttons in another order.

This post explains how to change the order of the buttons.

Firstly, decide which buttons you want:

  • Here are your choices.
  • Only the top four are available in every theme.  Themes which support all the button types include Crux and Bright.

Take all the names and separate them with commas.  However, for the gap in the middle where the title goes, use a colon.  Thus for the traditional order:


Now open a terminal, and type:

gconftool-2 --set /apps/metacity/general/button_layout --type string menu:minimize,maximize,close

or whatever order you prefer.

It has also been suggested that we might allow button order to be set by the theme, so the default theme in Lucid has the buttons on the left and the other themes have them in the traditional order.

Photo © Debora, cc-by-nc-nd.

You can switch in a direction!

BridgeWhen I posted yesterday’s squib, I really didn’t expect six people to say they’d use it. Someone plaintively left a message on the bug saying “Please make it possible for devilspie to add this feature!” Well, it is possible for devilspie or any other addon to add this feature, and for that reason it’s not a big difficulty to write it as an external script.  As an added bonus, it should work with Compiz or KWin or any other EWMH-aware window manager.

To play with the script:

  1. Download the current version from GNOME bug 152661.
  2. Put it in your path as metacity-direction.
  3. Install X11::Protocol by typing:
    sudo cpan X11::Protocol
  4. Open gconf-editor and set /apps/metacity/keybinding_commands/command_n, where n is any set of four unused values, to:
    metacity-direction e
    metacity-direction s
    metacity-direction w
    metacity-direction n
  5. Set /apps/metacity/global_keybindings/run_command_n to an appropriate set of values, like “<Shift><Alt>Right”, etc.
  6. Enjoy.

The algorithm is supposed to be the same as fvwm’s, but if you have suggestions for tweaking it, let me know.  The program should also demonstrate how to do fun EWMH things from Perl.

Photo (c) Katie Sutton, cc-by-nc-sa.

Theme speed

The speed Metacity renders decorations depends on the theme in use. If you want to time all the themes installed and view them, use:

  • for G in $(locate metacity-theme-1|grep /usr/share/themes|cut -d/ -f5); do metacity-theme-viewer $G; done

Mean client-side times on my system to draw each frame, in ascending order of speed:

  • Prelude (the theme given in the previous post): 1.3ms
  • Bright: 1.9ms
  • Atlanta: 2.0ms
  • Mist: 2.1ms
  • AgingGorilla: 2.2ms
  • Metabox: 2.2ms
  • Simple: 2.3ms
  • Esco: 2.4ms
  • Glider: 3.7ms
  • Crux: 3.8ms
  • DarkRoom: 3.9ms
  • ClearlooksClassic: 4.3ms
  • Glossy: 4.5ms
  • Clearlooks: 4.6ms
  • Inverted: 4.6ms
  • Human: 6.0ms

A simple theme: Prelude

This is in answer to Stuart Langridge’s question about how the XFCE theme Prelude can be ported to Metacity.  Here is a quick attempt at porting it; I’ll be referring to that in what follows.  In order to install this theme for yourself, do:

  • mkdir -p ~/.themes/Prelude/metacity-1
  • wget -O ~/.themes/Prelude/metacity-1/metacity-theme-1.xml

I’m not talking about SVG here, because that’s still an experimental technology within Metacity, and I’m not talking much about version 2 of the theme format for simplicity.

We begin with the metadata, which isn’t unusual enough to explain.  Next comes the geometry, which is the key to the whole business: we only have the one, and it has rounded corners and no title.  We have to mark that there’s no title or Metacity will make space for one even though there’s no instruction to draw it.  If we were making a v2 theme, we could specify the degree of rounding, but v1 only allows you to say whether or not rounding is happening on each corner.

After the geometry we declare some draw_ops.  These are lists of instructions about how to draw each item.  All the draw_ops here are simply coloured rectangles.  One of them, “white”, is to draw the whole background of the window, but the entries for buttons stop slightly short in order to give the impression of gaps between the buttons but to leave the gaps clickable.  We declare the button colours twice in order to have a slightly lit-up version for the prelight.

I added a blue button for the menu button, but if you wanted you could use “white” there and have the menu button present but invisible.  In v2 you would need to declare three other button colours, which could get confusing.

Next, we only have one frame_style and it only draws one piece.  The differences between all the possible pieces can get confusing, but here we only wish to draw an enormous white rectangle over the whole window surface, and so we can use the “entire_background” piece and be done with it.

Then we have a frame_style_set which points in all cases to the one frame_style, and after that we simply declare that each window uses this one frame_style_set.  And there we have it.

There are many possible improvements, including dimming the button colours when a window isn’t focussed, and perhaps using the colours from the desktop theme instead of white all the time.

Edit: Stuart has tweaked the theme a little and uploaded it to gnome-look here.

How to get backtraces from a window manager

This may sound obvious, but I only just thought of it.

Suppose you make a change to Metacity which causes it to segfault on startup. What you’d ordinarily do is to load it into gdb and have a look at what’s going on in the backtrace with the bt command. But you can’t do that, because it will keep Metacity suspended and so no new window manager will be spawned, and that means that you’ll be running without a window manager. You can get around the problem by sshing into your computer from elsewhere, or by running Xnest or similar, or by using a virtual machine. But here’s a much, much simpler way.

Firstly, create a file called test.gdb containing the text
run --replace

Then simply give the command
tthurman@haematite:metacity$ gdb src/metacity --batch -x test.gdb
[Thread debugging using libthread_db enabled]
[New Thread 0xb7131720 (LWP 16959)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb7131720 (LWP 16959)]
0xb7943a6e in g_error_free () from /usr/lib/
#0 0xb7943a6e in g_error_free () from /usr/lib/
#1 0xb7943adc in g_clear_error () from /usr/lib/
#2 0x080a70ba in meta_frame_style_draw (style=0x8119c78, widget=0x8122090, drawable=0x80f4e20, x_offset=0, y_offset=0, clip=0x0, fgeom=0xbfc67384, client_width=1365, client_height=718, title_layout=0x80e1850, text_height=17, button_states=0xbfc67784, mini_icon=0x8123418, icon=0x8123398) at ui/theme.c:4553
#21 0xb79561e7 in g_main_loop_run () from /usr/lib/
#22 0x08070992 in main (argc=1, argv=0xbfc68514) at core/main.c:479

Easy as that.

Justifying window titles

It was said that Metacity doesn’t let you decide whether titles of windows are left-justified (as in modern versions of MS Windows) or centre-justified (as on the Mac). But actually, it’s a theme issue to decide how a title is drawn. Here’s how to change your theme from centre-justified to left-justified.

First, find out what theme you’re using. We’ll use gconftool to do this, because it’s the easiest to demonstrate.

$ gconftool -g /apps/metacity/general/theme

Okay, so we’re using Ubuntu’s Human theme here (you may well be using something else, of course; substitute its name for Human in what follows). Presumably you don’t want to work on the main system version of the theme, so take a personal copy and tell Metacity to use it:

$ cp -R /usr/share/themes/Human ~/.themes/LeftHuman
$ gconftool --type=string -s /apps/metacity/general/theme LeftHuman

It will switch to the new theme, but obviously it will look identical at present.

Unfortunately, as I mentioned the other day, there’s no fancy editor for Metacity theme files: you’ll have to edit the file by hand. But it only needs to be done once. So, open ~/.themes/LeftHuman/metacity-1/metacity-theme-1.xml in your favourite editor and search for <title (“title” preceded by a less-than sign, i.e. the opening of a “title” tag in XML). You will see that any of these you find have a formula for their x attribute that involves taking widths and halving them, which screams about centring. All you have to do is change this formula to zero for all the title tags in the file.

However, in the Ubuntu Human theme they obtain a shadow effect on the letters by printing the title multiple times at different tiny offsets. For cases like these, you need to keep the offsets in order to keep the shadow effect. So you’d change
<title color="shade/gtk:bg[SELECTED]/0.75"
x="(3 `max` (width-title_width)) / 2 + 1"
y="(((height - title_height) / 2) `max` 0) + 2"/>
<title color="shade/gtk:bg[SELECTED]/0.7"
x="(3 `max` (width-title_width)) / 2 + 2"
y="(((height - title_height) / 2) `max` 0) + 2"/>
<title color="shade/gtk:bg[SELECTED]/0.4"
x="(3 `max` (width-title_width)) / 2 + 1"
y="(((height - title_height) / 2) `max` 0) + 1"/>
<title color="#ffffff"
x="(3 `max` (width-title_width)) / 2"
y="(((height - title_height) / 2) `max` 0)"/>


<title color="shade/gtk:bg[SELECTED]/0.75"
y="(((height - title_height) / 2) `max` 0) + 2"/>
<title color="shade/gtk:bg[SELECTED]/0.7"
y="(((height - title_height) / 2) `max` 0) + 2"/>
<title color="shade/gtk:bg[SELECTED]/0.4"
y="(((height - title_height) / 2) `max` 0) + 1"/>
<title color="#ffffff"
y="(((height - title_height) / 2) `max` 0)"/>

and so on throughout the file.

When you’re done:

$ metacity-message reload-theme

and presto!

You might say that this is a lot of work compared to just selecting a “left justify” button somewhere, and it is, but assuming your original theme file was free software, you can distribute derivatives of it. So you should feel free to give your new left-justified version to your friends or stick it up on the web somewhere. Don’t forget to add your name and copyright in the <info> section first.

Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported.