Client-side window decorations for GTK+

This is a new feature that will be proposed later, which intends to make it possible to decorate GTK+ applications in-process using the toolkit and the theme engine. This also involves better RGBA window support in the toolkit and improved mouse cursor handling.

New goals

  • Let applications and the window manager draw window frames with exactly the same code for theme-ing and drawing. Traditional apps let the WM draw window frames as usual; new apps can choose to draw window frames themselves.
  • Applications with client-side decorations can completely change the way frames are drawn, or they can simply customize the default window frames a bit.
  • Apps have an easy way to extend or change the way window frames are drawn: add a couple of widgets in the titlebar (example), or make the titlebar taller so that it can fit a web browser's tabs.


See the client-side-decorations branch in GTK+.

Metacity's code to read theme files and draw window frames is put inside GTK+. Applications will thus have access to this code through a convenient API. (Metacity's code is almost identical to Mutter's; any differences are just lack of synchronization in both projects.) In turn, Metacity/Mutter will be made to use GTK+'s theme-drawing code directly rather than including its own copy of the code.

FIXME: Do themes need to define a "customizable area" for window frames? Or can the code figure out how a certain theme ought to be handled for customization?

API discussion

Some hypothetical code for an app that adds an entry to its window's titlebar:

GtkWidget *window;
GtkWindowDecoration *deco;
GtkWidget *area;
GtkWidget *entry;

window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_client_side_decorated (window, TRUE);

deco = gtk_window_get_decoration (window);
area = gtk_window_decoration_get_titlebar_area (deco);

entry = gtk_entry_new ();

gtk_container_add (area, entry);

FIXME: What does Firefox need to have tabs-in-titlebar?


Application/window manager communication

GTK+ needs to tell the window manager not to decorate a window so that GTK+ can paint the decorations itself. This seems to work fine using the usual EWMH.

Conversely, the window manager may need to tell GTK+ that it is running in a "netbook" or "fullscreen apps" mode. In that case, an application with client-side-decorations should not draw a full window frame, but rather adjust itself to that mode.

GTK+ may need to tell the window manager about special areas within the window frame, for example, the location of the Close button. If an app becomes unresponsive, the WM may want to trap clicks on the Close button and give the user the option of killing the app. NOTE: This assumes that the Close button will be visible at all; an application that does not even repaint will be in trouble. This is probably not much of an issue with compositing window managers that store the window's contents anyway.

Original goals

Short-term goals:

  • Fix issues we get with non-reparenting WMs like compiz that transform the window and the user can see an ugly polygon edges between titlebar and app
  • Have a good reason to push for rgba windows :)

  • Possible performance improvement in reparenting WMs where there is currently a mismatch between client/decoration visuals?

Longer-term goals:

  • single source for theming the application and decoration
  • Get gtk+ working on Wayland

TODO items

  • Experiment with doing window resizing 100% in gtk+
  • Allow theme to specify positions of decoration buttons
  • Expose decorated region to WM (xfixes region?)
  • Fix issue with Nautilus/gnome-bg related to RGBA changes (probably other apps too)
  • Merge in features from libwnck? Not sure.
  • Drop shadows?
  • Create some nicer icons to use for min/max/close. :)


Projects/GTK/ClientSideDecorations (last edited 2018-12-05 15:45:51 by EmmanueleBassi)