Why and how libadwaita prevents theming?

There is no path and there is no setting, an app can load stylesheets from anywhere it wants. An app could apply that order of loading if it wanted or it could do something else entirely. Apps can even generate new stylesheets dynamically in memory and load/unload them at runtime. This didn’t change over years, GTK3 also worked this way if an app wanted to do it.

Then don’t use software, because all software places artificial restrictions.

Libadwaita provides the UI appearance and behaviours described in the GNOME human interface guidelines. If an application is using libadwaita then its authors have decided to follow the GNOME guidelines; any attempt at changing that is going to break the application’s intended user experience.

If a user wishes to inject their own styles into an already styled application, with no regards to the intent of the authors of that application, then they can, by using the facilities exposed by GTK—namely, adding styles to the $HOME/.config/gtk-4.0/style.css file that is automatically loaded. If you do that, you get to keep both the pieces when things inevitably break, and you don’t get to complain about it.

There is nothing in the licensing terms or development practice that says that application of library developers in free and open source software have to provide knobs and settings for people who want to modify applications and libraries without paying the cost of learning how to read and modify the code.

1 Like

Maybe, but it’s difference restrict e.g. size of note 100MB than block manually edit stylesheets. But don’t stuck to this comment.

I’m not against that, but is it really necessary try block something like this? Just endless cat-mouse game. Don’t also stuck to this.

Maybe I asked badly. So forget all the previous comments, the whole thread:

I’m interest of couple things and I can’t find answers to them since lot of fuss and misinfo about this topic.

To understand answers of following questions, I need understand, how stylesheets works in GTK? Can you explain it?
My understand is basically following, please fix details:
1. GTK Default stylesheets is always loaded (hardcoded), but in start GTK also try find stylesheets from paths /usr/share/gtk-4.0/:$HOME/.config/gtk-4.0/ or something like and loads them.
2. GTK Default is by default enabled, but in start GTK reads confs from /usr/share/gtk-4.0/settings.ini:$HOME/.config/gtk-4.0/settings.ini and lastly from dconf . These confs can replace GTK Default.
3. Then GTK app has by preloaded all those stylesheets and pre-enabled one of these. If the GTK app doesn’t touch to stylesheet confs it will use what it get as such.
4. But the GTK app wants, it can unload all stylesheets except Default, it can load new stylesheets and enable as many it wants.
5. $GTK_THEME can force enable any loaded stylesheet. Debug feature.

Now to the questions of libadwaita:

What concretely changed for styles when libadwaita comes in, compared to the GTK3 times?
Is it this:
libadwaita unload all stylesheets it can (4. in the list), load own stylesheet (hardcoded) and enable it.
The app have to separately ask libadwaita do that or not?

How users can cancel this behaviour of libadwaita and load/enable own stylesheets?

What are benefits of this behaviour of libadwaita? Is it just for forcing adwaita stylesheets?

And yes, I know that, this against

to this

but I don’t know how fix my understand with just this fact. I’m not trying to dispute what you, ebassi, tell.

I think I have answered all these questions already but I will consolidate them if it can help you.

  1. No. The base stylesheet is loaded depending on the value of the gtk-theme-name GtkSetting. This defaults to the theme Default but an app can set it to anything. Libadwaita changes this in order to apply its own styles without conflict. Additional styles you place in gtk.css will be loaded on top of the base theme and will likely conflict with it. So they are not desirable compared to the way it’s done in libadwaita, I would say that is also a debug feature.
  1. Those configs can all change the value of gtk-theme-name but an app can just override it. Libadwaita apps will always override it, any other app can do the same if it desires its own base theme.
  1. In many cases yes, GTK (not libadwaita) apps will default to this behavior. However from what I have seen, it is extremely common for all GTK apps to load their own styles for their own widgets, even if they don’t use libadwaita. So it is never as simple as the app just getting the default stylesheet with no changes.
  1. Yes, also it can also load an empty style into gtk-theme-name and then get the styles from elsewhere. For example if an app really wanted to then they could implement a “theme store” that downloads new styles from a website.
  1. Not quite. It can force override the value coming from the gtk-theme-name setting. Note this has nothing to do with the app styles which will still need to be changed in the app.

Yes, that is what it does. The app doesn’t ask, it does it automatically because the apps would just break if it didn’t do that.

Nothing really. The same thing was technically possible in GTK3. Again, GTK3 apps that wanted to require the adwaita theme would do the exact same thing by forcing the setting. The only difference is now libadwaita does it automatically.

You fork the app, modify its styles and then rebuild it. There is no other way. Because again, the app is the one that gets to make the final decision of what stylesheets it loads, and nearly all apps will require their own additional stylesheets that are not coming from libadwaita. This is a general restriction with any app that applies any styles to widgets, it is not specific to GTK or libadwaita or anything.

It is to make it easier for apps to follow the GNOME HIG and have a consistent look and feel.

No. I have said this multiple times: nothing is forced, the app developer can set it to anything.

The thing is just the lib (libadwaita) that enables stylesheet that is from the lib itself, hardcoded? These two changes?
In the GTK3 times basically all apps just decided not to enable any stylesheet? Everyone just wanted to inherit the configuration? In GTK3 Adwaita is hardcoded stylesheet, right?

Then how e.g. this can be work? And:
“If a user wishes to inject their own styles into an already styled application, with no regards to the intent of the authors of that application, then they can, by using the facilities exposed by GTK—namely, adding styles to the $HOME/.config/gtk-4.0/style.css file that is automatically loaded. If you do that, you get to keep both the pieces when things inevitably break, and you don’t get to complain about it.”

I speak from the user perspective. So, is the change just for forcing spesific stylesheet for users? If so, what is the problem with letting for user modify stylesheet if he wants?

P.S. Thanks for you so much! You explained a lot! :grin:

I don’t know what you mean here by “hardcoded”. Again, apps can just change the setting. This did not change between GTK3 and GTK4. If you mean something that is built into the library, the only thing that is “hardcoded” is the default gtk-theme-name setting which is here: gtksettingsprivate.h. In GTK3 this was "Adwaita" but in GTK4 it is "Default". The only reason there is a default theme is so the widgets don’t look completely horrible when using GTK without the app supplying a theme. I don’t know if apps were less likely to do it during GTK3 times but I have seen apps that did.

It does not really work. I personally would not recommend using those themes or changing anything in .config/gtk-4.0, they are likely to break apps. That reddit post even says it causes GUI bugs. In my experience, any attempts to hack apps to use random styles will cause bugs, because you are doing a behavior that is not intended or supported by the app developer.

No. From the user perspective there is no change because the user is always “forced” to do whatever the app developer decides. It does not matter if the app uses GTK4, GTK3, GTK2, GTK1, Adwaita, Qt, X11, Electron, Wayland, or anything else – if the app wants to force a specific appearance and hardcode in some styles then it can just do that. If this is unacceptable, then you get to spend the time to become a developer yourself and fork those apps, or find another app that does what you want, or write your own app from scratch. There is no other way, really.

There is no problem, a user can just fork the app.

If you mean a user who is not also a developer: at least with the way styles are done in GTK, those users by definition cannot modify stylesheets. CSS stylesheets are a tool for developers to define the visual construction of an app. A user cannot effectively modify an app’s stylesheets without reading and understanding the entire code of the GUI. Without that understanding it is extremely likely that any changes you make to the styles will cause bugs.

Thanks a lot! :raised_hands:

Last questions… I promise:

  • Is Adwaita stylesheets hardcoded in libadwaita? By hardcoded I mean, is these stylesheets in the /usr/lib64/libadwaita binary? So only options change these stylesheets is rebuild libadwaita? (or hack with hexeditor but, but :D)

  • Is Default, etc stylesheets hardcoded in gtk3 and gtk4? Styles are in /usr/lib64/gtk-3.0 and /usr/lib64/gtk-4.0 binaries?

  • libadwaita by default automatically unload all stylesheets and then load the “harcdoded” Adwaita stylesheets? For load it uses gtk_css_provider_load_from_file, but what it uses for unloading?

  • Can I make app with libadwaita without loading adwaita stylesheets? In other words, can I disable that “unload stylesheets and then load adwaita” automatically function?

  1. Yes, the stylesheets are built into the .so binary. This because the stylesheets are part of the API, you should not change them randomly because doing so will break apps.
  2. Yes, same as answer 1.
  3. It does not actually unload any other stylesheets but instead it changes the default stylesheet to an empty one. Then it loads the appropriate Adwaita stylesheets on top of it according to the current user preference (dark mode, high contrast, etc). To achieve this it calls gtk_style_context_add_provider_for_display to load and gtk_style_context_remove_provider_for_display to unload stylesheets. If you switch between dark mode and high contrast then libadwaita will call these functions many times at runtime. Any app can call also these functions to load and unload stylesheets at any time. They can be called in response to mode/contrast changes but also in response to anything else the app developer desires.
  4. Realistically no, because then the apps will have no styles and they will look and behave badly. If you really want to see what happens you can comment out the line that loads the stylesheet and rebuild libadwaita, and you will see the breakage.

Edit: BTW, I just remember one other thing. Another way to change the gtk-theme-name setting without recompiling is to open GTK Inspector (Ctrl+Shift+I or Ctrl+Shift+D) and go to Global → Settings → GTK Theme. Though this also is pretty much only useful for testing non-libadwaita apps, it is practically guaranteed to break Adwaita apps.

1 Like