pcb-rnd knowledge pool


GTK4 rant: CSS: design error with custom widgets

gtk4r_css_custom by Tibor 'Igor2' Palinkas on 2021-12-23

Tags: insight, gtk4, rant, css, custom, widget, theme, style

node source



Abstract: n/a

  This rant is part of a series.

The lost color

As we saw previously, I had to implement my own scrollbar widget. I didn't do it because I wanted it to look different, I did it because I wanted it to work, and I wanted it to be simple.

Which means I did want it to look the same as stock scrollbar. Gtk4 has a css class named after widget classes, for example this is how the scrollbar gizmo (called slider in css for some reason) is specified in the stock dark theme css:

scrollbar >
 range >
 trough >
 slider {
	min-width: 8px;
	min-height: 8px;
	margin: -1px;
	border: 4px solid transparent;
	border-radius: 10px;
	background-clip: padding-box;
	background-color: #a4a4a3;
	transition: all 300ms cubic-bezier(0.25, 0.46, 0.45, 0.94);

'C' from css means cascade, so we are good, we just need to arrange things that the new scrollbar gets to (cascades to) the same css node, right? Well, not really. It won't work because the original implementation used two separate widgets, the scrollbar and the gizmo, while my explicit goal with the custom scrollbar implementation was to simplify things so it's a single widget.

In my simplified implementation I just draw the slider as a rectangle. This way I do not need to have an embedded second widget and I do not need to depend on some generic widget sizing/allocation (that breaks). Instead I simply calculate coordinates and draw a box. But as my box is not a widget, I can't use the above css for it, because I can't get gtk4 to bind a css node to something that's not a widget!

Okay, but I don't need to do that, as all I need is set the same color, so I could just go and extract the color from the css, right? Wrong. There is no way to do that. As one of the gtk developers explained in a discussion , it is impossible to query the background color of a widget, by design! Okay, I could sort of accept that, there are so many complicated mechanisms resulting in multiple colors (e.g. a gradient) that it's not a good query. On the other hand, CSS is just a tree of data and I would expect I could somehow query a leaf node in it. In my case the background-color of scrollbar > range > trough > slider. But it seems it can't be done.

Custom widgets vs. theme

Which leads to a real big contradiction in three core values gtk4 promotes:

  1. developing custom widgets is very easy, whenever you need one, just write one
  2. use css for all themes, let users choose from different themes
  3. gnome (gtk) apps should look and feel the same to keep desktop integrity

The problem is: if you indeed develop your own widget as per 1., and it decides to draw anything by itself, you can't make it use the current css theme to copy an existing widget's color. Which means you will need to use come custom color. You could hardwire that color in code, but that contradicts with 2, plus it's hard to find a color that would work with every possible theme. Or you could rely on a custom css, which really means you need to provide a whole application-specific gtk4 theme and tell the user he can't use a stock theme because that'd break your custom widgets - contradicting 3.


css is simply not flexible enough to support both custom drawn widgets and central themes. In librnd custom scrollbar I decided to hardwire some neutral grey color for the scrollbar slider to keep it simple.