Server Side Decorations in GTK: A Proposal

Hello all!

I have written a basic proposal for trying to include SSD (Server SIde Decoration) support in GTK and related libraries (API names may change):

  1. Protocols: Remove the outdated KWin server-decorations protocl from Gtk and replace it with the new xdg-decorations protocol, part of wayland-protocols. This makes Wayland compositors only have to deal with one protocol for decorations.
  2. Default Behaviour: Gtk by default will request CSDs (Client Side Decorations) via the xdg-decorations protocol. Gtk will only switch to SSDs if requested by an application developer, or if a compositor insists (unlikely). This makes SSDs an opt-in behaviour. An app that does not want to support SSDs would not have to do anything. However, If Gtk is running with SSDs, Gtk should remove rounded corners from the window border, as well as window shadows, but not remove anything else from the UI. Any other UI changes must be done by the companion library (such as Libadwaita), or the developer.
  3. Developer Control: If the developer wishes to support SSDs in their app, the developer can use an API, such as gtk_application_request_ssd. This API requests that an application should use SSDs, and thus should only be called if not being ran on their native environment (for example, a Libadwaita application should not call this API while running on GNOME).
  4. Developing SSD UIs: A property should be exposed, either via GtkApplication or GtkWindow that specifies the current decoration type, either CLIENT_SIDE and SERVER_SIDE. This allows an application to read or bind this property to adjust their UIs for SSDs. Examples of what an application could do would be to hide the headerbar, hide window controls, align widgets differently, or more. For applications that rely on the headerbar for more then just window title and window controls, they would most likely have very little to do, and could get away with minimal changes to their UI.

This allows Gtk to work better in other environments outside of GNOME Shell, while not compromising a developers vision or design unnecessarily. If we can agree on an API, I am willing to make the necessary merge requests to implement this.

Related Information:
gtk!6161
wayland_protocol!217
xdg-decoration protocol

2 Likes
  1. Protocols: Remove the outdated KWin server-decorations protocl from Gtk and replace it with the new xdg-decorations protocol, part of wayland-protocols. This makes Wayland compositors only have to deal with one protocol for decorations.

Fully agree.

  1. Default Behaviour: Gtk by default will request CSDs (Client Side Decorations) via the xdg-decorations protocol. Gtk will only switch to SSDs if requested by an application developer, or if a compositor insists (unlikely). This makes SSDs an opt-in behaviour. An app that does not want to support SSDs would not have to do anything. However, If Gtk is running with SSDs, Gtk should remove rounded corners from the window border, as well as window shadows, but not remove anything else from the UI. Any other UI changes must be done by the companion library (such as Libadwaita), or the developer.

This is not really how it works. By default, apps that set custom header bars can’t automatically be turned into SSD, because they have explicitly been designed to not have an additional headerbar. I do not think it’s unlikely that some compositors will insist on SSD no matter the client preference, and there is nothing in the protocol that should be interpreted as such.

I think going behind the back of app developers that explicitly designed their apps to not have any extra decoration is not the way to go here, it’d look even more broken than on X11.

  1. Developer Control: If the developer wishes to support SSDs in their app, the developer can use an API, such as gtk_application_request_ssd. This API requests that an application should use SSDs, and thus should only be called if not being ran on their native environment (for example, a Libadwaita application should not call this API while running on GNOME).

It isn’t so much about “requesting ssd”. From an xdg-decoration perspective, a client has three options:

  • It only supports CSD (custom header bar GTK right now)
  • It doesn’t care (default header bar in GTK right now)
  • It support both and has a preference (doesn’t exist yet)

So it rather seems that a proposal should be modelled to add support the third case, i.e. declare support, and perhaps optionally a preference (or just always prefer CSD).

1 Like

for 3) and 4), doesn’t the GtkWindow.decorated property already do that?

i also don’t understand it… why align widgets differently when SSD? if it means for example Web would get a layout like Firefox when running in other DEs, i think many users wouldn’t like it

The 3. case is for “Use system decorations”-style preferences? If yes, then I don’t see what API is needed to be honest. If the app wants to use custom decorations, it sets a titlebar widget (case 1.), otherwise it unsets it and let’s GTK handle it (case 2).

An explicit API to specifically request SSD also raises the question what would happen if the app doesn’t check that the environment actually supports it. If GTK doesn’t add any decorations as requested, the app will be broken; if GTK does add its default decorations anyway, it effectively implements the existing “don’t care” policy behind the app’s back (so what’s the point of the separate API?)


Here’s an example of Adwaita Demo with no window controls, title, and no shadows/rounded corners. Notice how it has the menu button aligned weirdly? We can either bring back the title, which looks weird having two titles, or shift the alignment of the menu button to the far-left. This is just an example. Apps may want to have a slightly modified UI with SSDs

Fair enough. In this case, Gtk should only switch to SSDs if an app developer supports it (either with a default headerbar, or by declaring support.

1 Like

Yeah, I struggled with this question for a while. Of course, the environment supporting it is something that xdg-decoration would handle, so it should be very unlikely for an app to have broken decorations, but I’m more concerned about apps picking the wrong decoration in the wrong environment (CSD when it should be SSD on a different desktop environment, for example). I wonder if there’s a good way we can have an environment check, so an app can specify which environments it wants to prefer a decoration for. Or maybe that’s dumb :slight_smile:

How does xdg-decorations “of course handle” it in environments where it doesn’t exist? I’m not only talking about GNOME, but also Windows or MacOS.

How many apps do you really expect to keep developing two different designs in parallel indefinitely? I know Chromium used to have a “tabs-on-top/system-titlebar” toggle, but I’m hard-pressed to find another example.

I’m really skeptical about the usefulness of any xdg-decorations support in GTK that goes beyond adding (or not adding) default decorations when a window does not have a custom titlebar.

Well, maybe a read-only GtkSettings property to communicate the system preference, if there really is demand from apps to support two different UIs.

@jmurphy: Do you think about UI changes like in Drawing (Drawing | Flathub)?

I assume Gtk has an established decoration system for windows and macOS, either with our own decorations or by using the system decorations. This would stay the same.

I expect most apps to use the same design, with minimal adjustments if absolutely necessary. For an app that has a lot going on in the headerbar, the app really doesn’t need to do anything

If this is something we can do, I think this would be the best to let apps know what the current environment wants.

This really is more just for allowing apps to use SSDs if they choose. The default will stay as CSD, and if an app wants to use SSDs, Gtk provides a way.

1 Like

No, requesting “system decorations” would mean not setting a header bar in todays GTK.

“Request SSD” can be done by not setting the header bar. The default header bar will be added if the server doesn’t do SSD.

It’s not a global setting in xdg-decoration, it’s a “negotiation”: client-is-csd (dont decorate the xdg_toplevel with the protocol extension interface), client-doesnt-care (default header or ssd in negotiated automatically), or client-is-adaptive (needs gtk api)

Note that if you want to explore such an API, the “state” that tells a GtkWindow about how it should decorate itself or not, must be done before layout and CSS, as such a state would affect both.

But your API suggestion was gtk_application_request_ssd(), not gtk_application_request_ssd_where_supported().

Yes, GTK will add default decorations where necessary if no custom titlebar was set, but that is not SSD.

If you want an API that allows an app to choose between “guaranteed CSD” and “a default decoration that best suits the system”, then you already have gtk_window_set_titlebar().

Currently the default is not CSD, but depends on a variety of factors:

  • custom titlebar → CSD
  • broadway/windows → CSD
  • wayland → CSD, unless the compositor prefers SSD (via kwin protocol)
  • X11 → SSD

The only thing that wrong there IMHO is the use of the kwin protocol instead of xdg-decorations.

Given that SSD are not universally supported, an API that allows an app to explicitly request SSD would be wrong.

What an app can do (without any API additions) is to not set a custom titlebar, which leaves decorations to the system/toolkit (in other words: SSD will be used where supported).

Yes, and I don’t understand what else would be needed on top of that.

My point is that “request SSD” implies that SSD will be used, while not setting a titlebar means that SSD may be used.

IMO an API for explicitly requesting SSD is either broken (where only CSD is supported) or a lie (because it ends up using CSD anyway).

Eeks, I was only looking at what GTK is doing today with the kwin protocol. Yeah, we can’t have a global property when the protocol is tied to a surface.

I have to agree with the previous comments. Aside from #1, I really don’t understand how this proposal is any different from the current state. The Adwaita Demo (and most other libadwaita apps) are designed to use their own headerbars so they will look bad in any case otherwise. But if you don’t use those and you just use a GtkWindow without a custom headerbar you will already get the kwin decorations.

1 Like

I think the proposal “in spirit” would make a difference, but anything that “requests ssd” would make no difference. What would is to optionally allow clients that now uses a custom header bar to provide an alternative widget tree if the compositor prefers a server side window frame.

Whether it’s something that’s worth complicating GTK for I’ll leave unsaid.

Oh I see, now this is about another property to reflect whether the decorated state was actually honored. It is not clear to me why I would ever need to supply alternate widgets in that case.

It seems that the only thing people really want to do with SSD is make GTK automatically hide the decorations and stop drawing the shadows, but no additional API is needed for that. AFAIK this is what .csd and :not(.csd) selectors are supposed to do, i.e. you can already easily use that to apply rounding/shadows/etc to CSD windows only. And for the window decorations, other desktops can set gtk-decoration-layout to blank to hide them already. Edit: I suppose that would also hide them for CSD too so nevermind, but still GTK can just hide those internally without needing to make another API.

An app might want to avoid putting the name and window controls in the titlebar widget they constructed themself, to avoid having something that looks like

+------------------------------+
|          App       _ [ ] [X] |
+------------------------------+
|        App           [≡] [X] |
+------------------------------+
|                              |
|                              |
|                              |
|                              |
+------------------------------+

and instead do

+------------------------------+
|          App       _ [ ] [X] |
+------------------------------+
|                          [≡] |
+------------------------------+
|                              |
|                              |
|                              |
|                              |
+------------------------------+

or put [≡] somewhere elso etc.

1 Like

I hope I’m not chiming in in the wrong place, but it seems like between CSD and SSD there is another option to consider.

Title bars, menu buttons, close buttons, etc. really should be drawn client-side because they are legitimate controls for the window. They should appear somewhere in the tab sequence for keyboard focus, if nothing else then for accessibility. Sure, there might be differences between toolkits, but people are now used to a mix of GUIs from browsing the web.

Drop shadows, on the other hand, need the compositor for alpha blending, so they are at least partially server-side. I understand this is done now by putting some sort of client-side border on the window, which makes sense since corners may be rounded or sharp.

Shadows are more of a special effect, more decorative, than frame controls. For a consistent look, they should perhaps somehow be entirely server-side. I don’t know how corners fit into that. The server also knows the stacking info, so it could adjust shadows appropriately.

The middle road I’m proposing is for clients to draw the entirely opaque parts of the windows and leave the blended parts entirely to the compositor. I don’t know how the KDE people would feel about that.

Not very easy:

  • xdg-decoration does not support this mode
  • this would mean that it’d be necessary to introduce “masks” to describe what part of a window should have shadow (think about rounded corners for example)
  • the rounded corners will still need to be “smooth” so they wouldn’t be opaque
  • it makes it impossible to put a floating window as a whole in a in a GPU plane for bypassing compositing, if that window moves

So I’d say that has more downsides than benefits.

1 Like

If I understand it correctly, xdg-shell would have to change too. Is it not xdg_surface::set_window_geometry that tells the compositor which part of the window is just shadow? What I suggested would leave no need for that part of the protocol. In any case, that’s another strike against it.