I have implemented several controls using GtkDrawingArea and GtkGLArea. To manage user interactions effectively, I need to access theme colors such as the text color and the selected background color. Until now, I have been using GtkStyleContext to achieve this. However, as of version 4.10, GtkStyleContext is deprecated, and I am uncertain about the best way to replace it.
While there are discussions on this topic, my situation is unique because I specifically need to retrieve colors. So, what is the replacement for gtk_style_context_get_color? Is there another way to obtain these colors? Additionally, can someone point me to the documentation for string “definitions like theme_text_color”, “theme_selected_fg_color”, and others?
Here is the code I currently use to obtain the required colors:
You don’t. You can keep using deprecated API until you need to port to the next major version of GTK.
In this specific case, there is no replacement (otherwise you’d have seen a message to that effect in the documentation).
Named colors depend on the theme, so unless you know exactly that:
a theme is providing that specific named color
the user isn’t going to change theme
you cannot rely on those colors to exist.
Additionally, only GTK widgets can have style; you cannot “draw” manually using the data from the CSS style machinery, because that’s reserved for widgets themselves, and GTK will handle colors, spacing, and backgrounds for you.
If you’re drawing something yourself, you should define your own colors using your own preferences mechanism, and not rely on CSS.
These were deprecated, it’s usually a bad approach to use these kind of lookup functions, as there are no guarantee all the themes define them.
In gtk4, there is only the Gtk.Widget.get_color, which will in your case return the “theme_text_color”.
Usually, you should avoid mixing code and style, and let the CSS manage the whole styling, by using the named colors in CSS only, like:
mywidget {
color: @theme_text_color;
}
If you need to setup some colors programmatically, generate a CSS string on the fly and load it to the display. You can have a look at the source code of apps like gnome-text-editor, they use that trick to recolor the interface based on the sourceview style.
I understand the concept of styling the widget, which is fine. However, my problem is this: I have custom controls that I draw myself, using either GtkDrawingArea or GtkGLArea , to simulate user interaction. When the user moves the mouse cursor over a certain area of my control, I want to create a similar effect to selecting an item on a list. In other words, I need to know the system’s foreground and background selection colors. My goal is to use the system colors instead of custom ones. So, is there any reliable way to obtain these system colors without using the system API?
The theming machinery does not have “system colors”, and you can’t gather that information from the CSS itself without a tree of widgets. If you asked the DrawingArea or the GLArea for a color, you’d likely get something like “white”, or “transparent black”, because a DrawingArea or a GLArea do not have styling information associated with them, and they likely inherit whatever comes from their parent. In practice, you would need to define a CSS class for your widget, and then add a bunch of properties to it anyway.
This is not GTK2, with 5 colors defined inside a resource file: CSS is much more complicated than that. It needs a tree of widgets to properly follow the cascade rules, and “colors” are just a special case for uniform textures.
On top of that, what you think are “system colors” are just names defined inside specific themes; there’s no guarantee a theme will define them, and there’s no fallback for them. In the next stable version of GTK, “named colors” are getting replaced by CSS variables, which means you can’t even look them up unless the theme author decided to maintain some level of backward compatibility.
This is what GTK themes are, and what they have been since 2011. You either use GTK widgets all the way through, or you find some other way to define colors. For instance, on recent systems, you could probably query the accent colors from the Settings portal, and use that information; otherwise, you’ll have to decide what kind of themes you wish to support, and hard code the colors you wish to use.
If you use libadwaita, theme_selected_bg_color is mapped to accent_bg_color, and the upcoming version (1.6) will have some basic APIs to query the cuurent accent color: Adw.StyleManager.get_accent_color . You can get the corresponding RGBA with Adw.AccentColor.to_rgba . The selected foreground color is always white, so no API for it.