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
bt

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/libglib-2.0.so.0
#0 0xb7943a6e in g_error_free () from /usr/lib/libglib-2.0.so.0
#1 0xb7943adc in g_clear_error () from /usr/lib/libglib-2.0.so.0
#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/libglib-2.0.so.0
#22 0x08070992 in main (argc=1, argv=0xbfc68514) at core/main.c:479
tthurman@haematite:metacity$

Easy as that.

If the user will not come to the window, the window shall come to the user

KissingSuppose you have two workspaces, and a window on each one. You’re looking at window A, so clearly window B is offscreen. You click something on window A, and window A attempts to present window B to you. What does that mean?

Let’s have two concrete examples:

  • 0x01: You’ve clicked a link in Pidgin’s buddy window, and it’s attempting to present the chat window to you.
  • 0x02: You’ve clicked a link in Evolution, and it’s attempting to present Firefox to you.

In 0x01, you want to stop looking at the old workspace and look at the new one.  But you don’t want the windows to move off their workspaces.  You want everything to stay where it is.

This is the way upstream Metacity currently works throughout.  However, since Firefox is a tabbed browser,((I know Firefox has had tabs since 2002)) people have been asking whether this is the wisest course all the time.  In case 0x02 above, in the old days, the browser would just have launched a new window in your workspace.  People don’t like that now, because they want all their tabs in the same window.  But if the user gets shoved onto the workspace of the existing window and then we add a new tab, eventually they’ll close it and then wonder where their mail went. (At least, that’s how I understand their argument; perhaps I’m mistaken.)  As a compromise, downstream Metacity has now been patched in Ubuntu, Fedora, and possibly other places to make the window demand attention when this happens (i.e. go pulsy on the taskbar).

So we have multiple options when this happens:

  • Bring the window to the user, always.
  • Bring the user to the window, always.  (This is what we do now.)
  • Make the window demand attention– in other words, apply the downstream patch.  This is not the path of least resistance, since judging by recent feedback it appears to really annoy anyone using, say, Pidgin.
  • Tell the target application to deal with it.  This would mean that Firefox could open a new window if you were on a workspace where it had no windows open and open a new tab if you were on a workspace where it had one already.  It would mean finding some way of dealing with windows that didn’t co-operate.  It would also mean, alone among all these solutions, that we’d have to find a way of communicating with the target application.
  • Ask the summoning application to give us a hint as to which of these it would like.  This is my (Thomas’s) favourite solution.  It will need a change to the EWMH.

Things which are not solutions:

  • Allowing the user to pick one and then requiring them to stick with it.  As Havoc said, this is basically giving them a choice between “break Pidgin” and “break Firefox”.
  • Window matching.  We do not do window matching.  We are not about to start for an issue as small as this.  That’s what devilspie is for.

Want to join in the argument fun?  Dive in at GNOME bug 482354.  The water’s lovely.

Photo credit: rofanator.

2.23.55 released

Thanks to Elijah Newren and Thomas Thurman for improvements in this version.

Contrary to rumour, this release does not add tabbing to everything.

  • Display theme name in title bar of theme viewer (Thomas) (GNOME bug 430198)
  • Allow toggling of non-compositor effects (Thomas) (GNOME bug 92867)
  • Add some extra null checks (Thomas) (GNOME bug 422242)
  • Check for double-freeing at the time of workspace freeing (Elijah) (GNOME bug 361804)
  • Don’t generate log messages unless we’re logging (Thomas)
  • Two windows which don’t belong to any application can’t be considered to belong to the same application (Thomas)
  • Various tidyings (Thomas)

Translations
Yavor Doganov (bg), Gabor Kelemen (hu), Kjartan Maraas (nb), Matej Urbančič (sl), Daniel Nylander (sv), Theppitak Karoonboonyanan (th)

2.23.34 out (mainly for the release day)

2.23.34
=======

Thanks to Thomas Thurman for improvements in this version.

– Commenting and tidying (Thomas)
– Fix possible compositor crash (Thomas) (#530702)

Translations
Khaled Hosny (ar), Yavor Doganov (bg), Jorge González (es), Kjartan Maraas (nb),
Yannig Marchegay (Kokoyaya) (oc), Theppitak Karoonboonyanan (th), Clytie
Siddall (vi)

The overview series: Drag and drop. You complain, we explain.

drag onIf there are two overlapping windows on the screen, people would like to be able to pick up an object from the lower window and drag it to the upper without bringing the lower window to the front, because if that happens the lower window will obscure the upper, and you won’t have anywhere to drag to. In this instance, we would like the same behaviour as Microsoft Windows: if the click starts a drag, raise the lower window on button release; if it doesn’t, raise the window on button press as normal.

However, Metacity (along with most other window managers) doesn’t currently do this, for want of a way to know whether the click starts a drag. This is really something that only the application owning that window can tell us. (It is possible for the user to tell us what they think, by holding down AltGr at the start of the drag. That may not be an official feature. It’s not really ideal either way.)

This whole question is something we’ve been batting around for six years now and it probably ought to be fixed one way or another. Over that time, there are also a few other reasons people have asked to be able to pick stuff up from lower windows, such as the ability to copy text from the lower window and paste it into the upper, or scrolling the lower window’s scrollbars: GNOME bug 76672 deals with this more general case, which we shan’t discuss further here now. Let’s concentrate on the most common problem, represented by GNOME bug 80984: not raising the source window when a drag and drop begins. What isn’t a solution to our problem?

What isn’t a solution

  • Always raising the lower window only on release, not on click (suggested by many people). This would solve the problem at the cost of weirding everyone out, not just breaking the expectations of existing Metacity users and users from other window managers in the world of free software, but also the expectations of Mac and Windows people.
  • Only raising a window when you click on the frame and not the insides, which was raised in GNOME bug 86108. This is a bad idea for similar reasons to the last.
  • Having a magic kind of window that Metacity promises never to raise; then the client will decide whether to raise itself or not based on whether the click was the start of a drag operation. This is how Sawfish does or did it. It’s a bad idea because it rather defeats the purpose of having a window manager if clients are going to manage their own windows, and besides applications can’t raise their own windows in Metacity anyway.

What is a solution
What needs to happen is this:

  1. We figure out a way for other clients to tell the window manager that a click in their window was the start of some kind of drag-and-drop operation.
  2. At this point, the fact that Metacity doesn’t understand this message suddenly becomes a bug in Metacity. So we fix the window manager to understand this.
  3. At this point, the fact that none of the applications out there understand how to tell Metacity about this becomes a bug in those applications, but we can’t do anything much about it without fixing the toolkits like GTK. So we do that.
  4. Now we can actually fix all the applications separately. The bug for fixing Nautilus at this point is GNOME bug 132339.

Clearly we can’t get 2, 3, and 4 sorted until we have 1 down, so let’s just talk about that for the moment. Back in 2004, Lubos Lunak (the maintainer of KDE’s window manager) proposed the first plan to do this, called _NET_WM_TAKE_ACTIVITY (a misleading name, since it’s about taking focus and not activity). When a window other than the topmost one was clicked, the window manager would send it _NET_WM_TAKE_ACTIVITY, which it would remember; after that, nothing would happen until the button was released. If the click had actually begun a drag-and-drop operation, that was all well and good, but if it hadn’t, the client should send it on to the root window and the window manager would raise the window after all. In GNOME bug 152952, Elijah Newren wrote a patch for Metacity implementing this plan.

Lubos’s original plan had a few infelicities, some of which were discussed in this meeting. It means that the window is raised when you release the mouse button, which is bad for reasons we discussed above.  It also means that a lot of policy is decided ahead of time: for example, some people would like their window manager to raise the lower window while they were copying text from it, and then drop it back down when they were done, but not do the same thing for drag-and-drop.  There was working code for KDE and GNOME, but many people objected about all the problems mentioned above including the GTK hackers.  In the end it didn’t make it into the EWMH standard, although some parts of the KDE libraries appear still to accept it to some extent.

Elijah then proposed to fix the problem with a new message type called _NET_WM_MOUSE_ACTION. With this plan, a client would send _NET_WM_MOUSE_ACTION through to the root window as soon as any button was pressed or released on it, telling the window manager what kind of action the click meant: it could be “nothing special” or “drag-and-drop”, but also “text selection” or “scrollbar drag” or “generic thing that I don’t want to explain right now but involves not raising me”.  Lubos agreed that this was a better plan, but it died even earlier in committee, and as far as I know was never implemented anywhere.

It seems to me that the best thing to do, if we can, is to go with a partial fix using _NET_WM_MOUSE_ACTION which allows us to heal this obvious problem.  Then we can carry on later and fix specific problems.  Elijah has said that _NET_WM_MOUSE_ACTION needed a great deal of work to implement on the GTK side; the closest thing we have so far to working code is a patch he then posted.  This does still need working on, preferably by someone who understands the internals of GDK (could this be you, gentle reader?).

A similar but not identical problem is the issue of raising windows when they are a drag target; this is covered in GNOME bug 112308.

Next in the overview series: why getting stacking exactly right is hard and what we’re going to do about it.

Photo by pbo31, cc-by-nc-nd.

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
Human

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)"/>

to:

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

Understanding Metacity themes

cleaning windowsThis is an article about how to theme Metacity. It is a work in progress, and I have had to dig deeply to find some answers; I may well have made mistakes and I welcome corrections and suggestions.

GNOME lets you theme a bunch of different things, but we’re only talking about window border themes here, which some people call Metacity themes; Wikipedia begins a sentence with “Despite the incomplete state of Metacity theme development documentation”, and though there is documentation in the source, apparently not many people find it, and it’s written more for programmers than theme designers. Glynn Foster also wrote a very good introduction to Metacity themes [de] six years ago, but things have changed a little since then. Metacity themes can also be used by Compiz, and perhaps by other window managers for all I know.

So, a Metacity theme is a set of instructions about how to “decorate” (draw the borders around) a window. Presumably you don’t want to style all windows identically, so the format lets you specify details for different kinds of window:

  • state: Every window must be in exactly one of these states: normal, dialog, modal dialog (i.e. a dialogue which means you can’t interact with the rest of the program while it’s up), menu (torn off from the main application, not that people do that much these days), utility (that is, palettes and toolboxes and things), and border. X also allows a window to explicitly ask to be undecorated, but of course we don’t provide for those in a list of decoration instructions.
  • focused: Every window is either the active window (which X people call “focused”), or it isn’t.
  • maximized: Every window is either (fully) maximised (horizontal and vertical only don’t count), or it isn’t.
  • shaded: Every window is either rolled up to show just its titlebar (which techies call “shaded” for some reason I can’t fathom), or it isn’t.
  • If a window is not fully maximised and not shaded, it either allows horizontal resizing, or it doesn’t.
  • If a window is not fully maximised and not shaded, it either allows vertical resizing, or it doesn’t.

What’s in the file

The files must be called either

  • ~/.themes/N/metacity-1/metacity-theme-V.xml
    for a theme used only by you, or
  • /usr/share/themes/N/metacity-1/metacity-theme-V.xml
    for a theme installed for all users.

where N is the name of the theme and V is the version of the format. Version 2, introduced in October 2006, adds a few extra features, but it’s rarely used. Version 1 is the original format. The formats are fixed once they’re stable for both backwards and forwards compatibility; new features can’t be added without introducing a new version number, which is why improvements come out rarely and in large clumps. metacity-1 in the names is a fossil and doesn’t mean version 1 of anything.

The metacity-theme-V.xml files are GMarkup files, which are very similar to XML. For now, you actually have to write these in a text editor or something; you can either start with a blank page, or modify a theme someone else has made. (I am thinking of writing a general theme editor program, but that’ll have to wait until I’ve reduced Metacity’s open bug queue a little.) If you want to see a fully-fledged one, you can look at the current version of “Atlanta”, one of the simplest themes, but even that is quite complicated-looking at first.

So, let’s talk about what actually goes inside the files. As in any XML file, <!-- ... --> are comments. At its most basic, it would go:

<metacity_theme>
<!-- Helper stuff: -->
<info ...> <!-- to be explained -->
<constant ...> <!-- maybe; to be explained -->
<draw_ops ...> <!-- maybe; to be explained -->

<!-- Things we build the top level onto: -->
<frame_geometry ...> <!-- to be explained -->
<frame_style ...> <!-- to be explained -->
<frame_style_set ...> <!-- to be explained -->

<!-- And the top level: -->

<window type="normal" style_set="..." />
<window type="dialog" style_set="..." />
<window type="modal_dialog" style_set="..." />
<window type="menu" style_set="..." />
<window type="utility" style_set="..." />
<window type="border" style_set="..." />
</metacity_theme>

Matching windows

window: You see that at the top level we have a list of <window> tags, one for each window state we discussed above. The style_set argument of each of these gives the name of a frame_style_set.

frame_style_set: …tells Metacity how to draw windows according to whether they’re focused or not, maximised or not, shaded or not, and allowing resizing vertically, horizontally, both, or neither. It looks like this:


<frame_style_set>
<frame focus="F" state="S" resize="R" style="N"/>
<frame... />
...
</frame_style_set>

where:
F is yes for focused, no for unfocused
S combines the shaded and maximized flags: normal, maximized, shaded, or maximized_and_shaded
R represents resize permissions that the window gives us: none, vertical, horizontal, or both. Frame settings for maximised windows, which can’t be resized, don’t have this attribute.
N is the name of a frame_style to apply to a window which has these attributes.

A frame_style_set tag may also have a “parent” tag, which should be the name of another frame_style_set. This means that if Metacity wants to know about a kind of window which that frame_style_set doesn’t describe, it should look in the parent. Most of the more complicated tags in Metacity theme files also have a “parent” attribute which work the same way. This is particularly useful because, taken together, all the frame_style_sets in a theme file must be capable of matching every possible kind of window; if a window turns up that they can’t match, there will be an error at runtime.

Let’s recap what we’ve seen so far. The combination of a window, which matches a window’s state (normal, dialog, and so forth), with an entry in the corresponding frame_style_set, which matches its focus, shadedness, maximisedness, and resize permissions where relevant, will allow you to make a list of rules to match any window against. The next piece of this puzzle lets you specify what Metacity should do with such windows once it’s matched them.

Actually drawing stuff

frame_style: This is probably the most complicated part of the whole system. A frame_style is a series of pieces and buttons. It looks like this:

<frame_style name="..." geometry="G">
<piece position="P">
<draw_ops>
</draw_ops>
</piece>
...
<button function="F" state="S" draw_ops="D"/>
<draw_ops>
</draw_ops>
</button>
...
</frame_style>

The pieces are pieces of the window frame. When Metacity draws a window frame, it renders its various pieces always in the same order. The bolded parts are all the possible values of P:

  • the entire_background, covering the whole frame
  • the titlebar, covering the entire background of the titlebar
  • the titlebar_middle, the part of the titlebar that doesn’t touch its edges
  • the left_titlebar_edge, right_titlebar_edge, top_titlebar_edge, and bottom_titlebar_edge
  • the title, just exactly that area which is covered by the text on the titlebar
  • the left_edge, right_edge, and bottom_edge of the frame (yes, there is no top_edge: it’s identical to top_titlebar_edge, isn’t it?)
  • the overlay, which covers everything– the same as entire_background, but done last instead of first.

What Metacity draws in these pieces is decided by the theme. If a frame_style or its parents don’t specify a particular piece, nothing will be drawn for that piece. You have two ways to specify what to draw: one is that the piece tag can have a draw_ops tag inside it which lists a sequence of drawing operations in Metacity’s custom format. You might ask why we don’t use SVG; one answer is that SVG support wasn’t very strong when this format was designed, and another answer is that these days you can use SVG all you like; just include it as an image and Metacity will know what to do.

An alternative to including a draw_ops tag inside a piece tag is to add a draw_ops attribute to the piece tag. Then you can add a draw_ops tag at top level (inside the metacity_theme tag) with a name attribute, and Metacity will use that. This is useful if you use similar draw_ops over and over.

I’m not going to document draw_ops at present, because this is already very long. I will write it up later and link it from here.

The button tag tells Metacity how, but not where, to draw buttons. Buttons are drawn after all the pieces are finished, and the way to draw them is also given using draw_ops. You ought to provide buttons for all the possible kinds of button; if you don’t give one it won’t be drawn, which is unfortunate for the user who wants to use it:

  • left_left_background, left_middle_background, and left_right_background don’t represent buttons as such, but the background behind them, assuming there can be at most three buttons on the left. These days there can be more, so the extra ones also use left_middle_background.
  • right_left_background, right_middle_background, and right_right_background similarly.
  • close, minimize, maximize are the obvious original three buttons.
  • menu is the menu button you can click to get a list of actions you can perform on the window.
  • shade, above, stick are similar to the original buttons but only allowed in version 2
  • unshade, unabove, unstick are the toggled versions of these buttons. Again, version 2 only. It is not immediately apparent to me how the toggled version of maximize is generated, though I suppose I must have known at some point.

Update: The reason there are toggled versions of shade, above, and stick, and not maximize, is that by the time you get this far you’ve probably already decided whether you’re drawing a maximised window. So if you are drawing a maximised window, you can make the button called “maximize” look how you want the restore button to be; otherwise, make it look like you want the maximise button to be.

For each button tag you should also set a “state” attribute; this time the state is either normal (the way you see it most of the time), pressed, or prelight (this makes the buttons subtly light up when you hover over them). You only really need “normal”, but the others are good to have too.

The “geometry” attribute of a frame_style tag is the name of a…

Geometry

The geometry tag defines the sizes of things around the window. It is important, but not easy to explain, and again this file has gone on too long. I’ll write it up later.

Other things which lie around a file

The most important other thing in a theme file is the metadata held in the info tag. This contains a set of tags each of which contains some text explaining something about the theme itself, in a sort of Dublin Core sort of way. (Next time around, we should probably use the actual Dublin Core.) The tags are name, author, copyright, date, and description.

Version 1 of the format had a menu_icon tag at top level, which let themes specify the icons beside options in the menu you get from the menu icon. This has become redundant; the icons are taken from the icon theme! The tag can still be used in all formats, but does nothing and is deprecated.

Version 2 of the format has a fallback tag at top level, which let the theme specify what icon a window should be considered to have if it doesn’t provide an icon of its own. This should also be taken from the icon theme, if anyone fancies fixing it, and the tag should also then be deprecated. It shouldn’t be hard.

When you’re working on a theme

When you’re editing a theme, you can view it without using it on the whole desktop using
metacity-theme-viewer YourThemeName

and view it on the whole desktop using
gconftool --type=string --set /apps/metacity/general/theme YourThemeName

Whenever you change the selected theme in GConf, Metacity will load the newly-chosen theme. This is how control-center does it. But when you change a theme, as you’re working on it, you might want to ask Metacity to reload the theme which is currently used on the whole desktop to reflect your changes. You can do this using the little-known metacity-message program, with the command metacity-message reload-theme. This works by sending the ClientMessage _METACITY_RELOAD_THEME_MESSAGE to the root window, in case you’re interested.

Once you’re done with your theme, consider submitting it to the art.gnome.org site, or the gnome-look site.

The future

Please feel free to link to this so people don’t have to keep asking the basic questions and can start asking the deeper ones. One of the important deeper ones is: where should we go in the future? Since this format is becoming something of a de facto standard between window managers, should we set up some kind of freedesktop.org standards discussion? Would it be useful to spin off Metacity’s theme parsing code into a separate, LGPL-licensed library so that other applications could use it more easily?

What would a version 3 of this format look like? Could we simplify the window / frame_style_set system? (I can imagine abolishing both, and being able to write <frame_style for="normal+unfocused+maximized">... and having Metacity assume it applied to all resize permissions and shadednesses.) Maybe we should try to do everything with SVG we can? Getting more wild and handwavey, is it worth keeping XML-like? Maybe if other window managers were dealing with the files, .ini-style files would be more universally useful? Or perhaps not. And then of course we need a decent graphical editor for it. I have a few ideas, but if anyone fancies jumping in…

Photo: “Cleaning Windows”, cc-by-nc-sa, by John Harvey.

2.23.21

What is it ?
============

Metacity is a simple compositing window manager that integrates nicely with GNOME 2.

What’s changed ?
================

Thanks to Robert Escriva, Iain Holmes, Matt Krai, Thomas Thurman, and Chris Wang for improvements in this version.

– Add shadow ability for menus and tooltips (Iain) (#517442) (GNOME bug 517524)
– Fix possible crashes in compositor (Iain) (GNOME bug 534569) (GNOME bug 528787)
– Major reorganisation of compositor code (Iain)
– Initial version of XRender backend for the compositor (Iain)
– New basic public API for compositor (Iain)
– Window decoration updates colour when GTK theme changes (Robert) (GNOME bug 511826)
– Minor code cleanup for pedantic compilers (Thomas)
– Further code cleanup for pedantic compilers (Matt) (GNOME bug 526049)
– The atom list appears only once in the code (Thomas) (GNOME bug 530843)
– Don’t attempt to read attributes of invalid windows (Chris) (GNOME bug 530485)

Translations
Khaled Hosny (ar), Gabor Kelemen (hu), Kjartan Maraas (nb), Tino Meinen (nl), Theppitak Karoonboonyanan (th)

Where can I get it ?
====================

As 780eddd5a57559c6255d7d2440f73114 bz2 or 75328c77f6de4e1c5ae638f3f0a4b0b6 gz.

Build systems and version control

In GNOME bug 532353, Elijah suggests switching Metacity to waf. Your thoughts on this are requested. I will build this into the test scripts whether or not we go with it in the long term.

Also, no work is getting done (or at least checked in) until the openssh débâcle is over and gone. Would this be a good excuse to move to bzr or git? Advocate please! I like bzr, but mainly because I already use it a lot and I love Python.

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