NOTE: I will update this post as I run into more application frameworks which need a little encouragement to feel native on my KDE desktop. While a lot of the technologies covered are strongly associated with Linux, they do still tend to be portable, so this information isn’t exclusively for Linux.
It seems like, these days, the rise of Electron and other web-based application toolkits has emboldened every two-bit UI designer to forget that the point of a user interface is to fade into the background and let the content gain full focus. (And that means consistency is paramount.)
I won’t go into detail on that, given that others have already done that:
It doesn’t help that everyone (including Apple) seems to have forgotten Joel Spolsky’s Things You Should Never Do, Part I and that the computing world in general has been sliding in this direction since 2002.
…but it is still my computer, and I still have to live with it… so here’s a reference for how to apply UI customizations to various applications and UI toolkits as an end-user.
Firefox
Call me crazy, but I have to wonder what’s going on at Mozilla headquarters that nobody seems to have asked “Is it possible that making our UI chrome feel less similar to platform-native UI than Google Chrome’s, and grabbing user attention with whizbang elements of dubious value… is hurting our user appeal, not helping it?”
Anyway, here’s a summary of the relevant guides on /r/FirefoxCSS (See also userChrome.org):
- Enable
userChrome.css
:
- Open up
about:config
and set toolkit.legacyUserProfileCustomizations.stylesheets
to true
- Create
chrome/userChrome.css
inside your profile folder (There’s a button to open a file browser window for your profile inside about:support
but I somehow broke it while locking down my Flatpak install of Firefox further.)
- Enable the browser inspector:
- Open the developer tools (
Ctrl + Shift + I
on Linux or Windows), open Settings (the cog which may be inside the overflow/… menu), and enable “Enable browser chrome and add-on debugging toolboxes” and “Enable remote debugging”.
- Restart Firefox
- Write your CSS tweak:
- Press
Ctrl + Alt + Shift + I
and choose OK in the “Incoming Connection” dialog (It will probably have appeared behind the unnamed, empty window which will become the browser inspector)
- You will now have something that looks like the browser’s developer tools but lets you inspect and manipulate the browser’s UI instead. It’ll initially be an ugly vertical split with a log on the left but that will eventually go away. (I don’t know how to make it go away faster)
- Use the “Inspector” tab to identify what to change
- To actually make changes, select “Style Editor” and use the “Filter style sheets” field to find
userChrome.css.
This way, if you like the changes, all it takes to persist them is to click “Save” in the userChrome.css entry in the vertical tabs down the left side.
Here are a few examples of tweaks you can create:
/* Remove pointless thumbnail in the Bookmark popup
(Why?! You can always see the full version while bookmarking anyway.) */
#editBookmarkPanelImage,
#editBookmarkPanelFaviconContainer {
display: none !important;
}
/* Hide "Saved to Library!" bookmark confirmation popup
(The star in the address bar having stayed filled already says that.) */
#confirmation-hint {
display: none !important;
}
/* Compact sidebar header to match my compact toolbars
* BUG: https://bugzilla.mozilla.org/show_bug.cgi?id=1435184 */
#sidebar-header {
height: 32px !important;
padding: 0 !important;
font-size: 12px !important;
}
Thunderbird
All the same steps as with Firefox apply (including the caution that the “Incoming Connection” dialog will probably fail to put itself at the top of the window stack), but the means to enable things are in slightly different places. (Thanks to this Superuser Q&A and this /r/Thunderbird thread for helping me piece things together)
- To access
about:config
so you can enable toolkit.legacyUserProfileCustomizations.stylesheets
, go into the “General” page of settings, scroll down to the bottom, and click the “Config Editor…” button.
- Instead of typing
about:support
into the address bar, you can find the button to open your user profile to add chrome/userChrome.css
under Help > More Troubleshooting Information
.
- The option to open the developer tools is at
Tools > Developer Tools > Developer Toolbox
An example customization you can create would be this:
/* Override the horrendous UI font that Thunderbird suddenly started choosing
(i.e. Match Qt, GTK+ 2.x, and GTK 3 apps) */
* {
font-family: "Noto Sans", "Nimbus Sans L", "Droid Sans", sans-serif !important;
}
NOTE: As of at least Thunderbird version 115, you’ll want to remove the @namespace
line from any suggested userChrome.css
content or you’ll be fighting an uphill battle to apply changes to the increasing number of elements of Thunderbird’s UI that are HTML instead of XUL.
GTK 3+
Starting with GTK 3, the GNOME people and I have… differences of opinion… made worse by how the links I started with find more fodder in GTK 3 than any other system. While I’ve managed to replace most GTK applications on my desktop with Qt equivalents by now, there still exist a few of them (eg. Inkscape) with no viable replacements.
While such apps are, thankfully, not trying to embrace GNOME-isms that run counter to hard-won design principles from HCI research, they’re still being dragged along for the ride by the GNOME-isms creeping into GTK components outside libadwaita
.
- Archlinux Users: If your intent is to make your GTK 3 stuff feel more native on a non-GNOME desktop, start by installing the gtk3-classic package from AUR. It contains a GTK 3.x patched to revert some of the hard-coded GNOME-isms.
- Other Distros: If your goals include disabling some visual inconsistency caused by GNOME applying client-side window decorations (eg. drop shadows on context menus), gtk3-nocsd will resolve that… but it is an
LD_PRELOAD
hack, and getting it to work reliably when Flatpak isn’t designed to allow LD_PRELOAD
hacks is iffy, so I’d suggest using it as a last resort.
Settings
No matter how much user-hostility we may feel is present in the GNOME developers’ behaviour these days, they do still allow some customization, so always check that before getting hacky.
For GTK 3, settings are customized by putting lines like gtk-dialogs-use-header=0
into ~/.config/gtk-3.0/settings.ini
. For GTK 4, it’s ~/.config/gtk-4.0/settings.ini
.
Valid settings.ini
keys are documented as properties under the relevant GTK version’s GtkSettings
API documentation. (eg GtkSettings for GTK 3)
Here are some suggested changes mentioned on Archwiki:
gtk-can-change-accels = 1
is a deprecated GTK 3 option that lets you hover your mouse over a menu item and then press a hotkey to assign to it.
gtk-toolbar-style=GTK_TOOLBAR_ICONS
is another deprecated GTK 3 option that will give you icon-only toolbar buttons without needing to reach for the CSS overrides (That’s what tooltips are for, don’t you think?)
gtk-overlay-scrolling = false
is listed as API-unstable, but should replace those touchscreen-style overlay scrollbars with ones where you don’t need to wiggle the mouse to see what your current scroll position is.
There’s also the gsettings set org.gtk.Settings.FileChooser startup-mode cwd
command (which you may need to run inside your Flatpaks) to restore the “old-fashioned” behaviour of having GTK file chooser dialogs start in the current directory rather than the recent files list.
Themes
Flatpak should automatically install the Flatpak version of whatever GTK theme you’re using but, if it doesn’t the first two things to try are:
- Make sure whatever settings daemon your desktop uses is installed and running. If the active theme isn’t being announced, then
flatpak upgrade
can’t install it.
- It’s possible your theme hasn’t been packaged for Flatpak. The Stylepak tool will grab whatever GTK theme is active on the host and construct a Flatpak package from it.
- There’s currently a bug that can cause Flatpak’d GTK applications to revert from Breeze to Adwaita on KDE desktops. To work around it, just go into the
Application Style
system settings module, click the Configure GNOME/GTK Application Style...
button, fiddle around with one of the drop-downs to enable the Apply button, put the themes back to what you want, and click Apply. (I haven’t yet investigated a permanent fix.)
- According to this thread, there are situations where a customized Breeze color scheme (I just use the default) won’t get applied to GTK 3 apps, and the workaround is a global filesystem override (either via Flatseal or manually editing
~/.local/share/flatpak/overrides/global
) to grant access to filesystems=~/.local/share/icons:ro;~/.themes:ro;~/.icons:ro;xdg-config/gtk-3.0:ro;
libadwaita
-based apps aren’t meant to be themed beyond the light/dark switch and the recolouring API they eventually want to add, but, if the theme was designed to support it, you can force the issue by setting the GTK_THEME
environment variable. I recommend doing it on a per-application basis rather than globally.
Open/Save Dialogs
This is one area where things are actually getting better for desktop consistency and user customization instead of worse. If your goal is to get all apps using the same desktop-provided Open/Save dialogs, the GNOME people are on board with that. Thanks to the XDG Portal system, anything that uses GtkFileChooserNative
(GTK 3) or GtkFileDialog
(GTK 4) instead of GtkFileChooser
(holdover from GTK+ 2) is capable of delegating to a common dialog service provided by your desktop.
- Where possible, install applications through Flatpak or Snap. You’ll get the maximum amount of XDG Portal support by default, you won’t have to upgrade your whole distro to get access to new versions which add more portal support, and any testing the package maintainer does will be done with them enabled.
- Anything using
GtkFileDialog
will use portals by default where available.
GtkFileChooserNative
only uses portals when running under Flatpak/Snap by default, because of buggy behaviour in certain GNOME apps. However, if you’re not using those GNOME apps, you can set an environment variable named GDK_DEBUG=portals
(formerly GTK_USE_PORTAL=1
) to forcibly enable them.
- Firefox/Thunderbird: If not using the official Flatpak or Snap packages, open up
about:config
and set widget.use-xdg-desktop-portal.file-picker
to 1
Widgets and/or libadwaita
While I still think the need for it in this situation is a giant regression, I have to applaud the GTK developers for once again demonstrating that, regardless of my disagreements with them on what constitutes good UI design goals, their underlying infrastructure since the beginning of the GTK 3 era (GIR, gtk-rs, etc.) has been admirable.
As of GTK 3.14, they now have an equivalent to the Firefox Browser Toolbox that I pointed you at further up. It’s called GtkInspector, and it’s now a standard part of all GTK installs that just needs to be enabled through one of these means:
- Run
gsettings set org.gtk.Settings.Debug enable-inspector-keybinding true
. Any GTK application started after you did that will open GtkInspector when you press Ctrl+Shift+D
.
(If it’s a Flatpak, you may need to use flatpak run --command='sh' <AppID>
or flatpak enter <AppID>
and run the gsettings
command inside the Flatpak.)
- Run the application with the
GTK_DEBUG=interactive
environment variable set. The inspector will open automatically.
Here are some tips:
- GTK extends CSS with a
@define-color name #c01040
; construct, and those defined colours are referenced by using @name
where you might otherwise use something like #f0f0f0
or white
.
- If your Flatpak app isn’t obeying the colours you expect and the widgets used by the application are very similar in Adwaita and your chosen theme, check the Visual tab in the inspector to see if it’s just falling back to Adwaita. See my previous comment about an open KDE bug for a workaround for that.
- Look at the class name (eg.
GtkPaned
) in the Object tab’s header (to the right of the drop-down button) and search for it in the online GTK API documentation for whichever version of GTK you’re dealing with. Each entry has a “CSS nodes” section (intended to allow application developers to customize their UI) which will help you craft your overrides. (eg. GtkPaned under GTK 4)
- Don’t get demoralized if your changes don’t seem to be doing anything. It is more finicky than tweaking Firefox’s UI using the Browser Toolbox.
To make changes to GTK 3 apps global and persistent, put the CSS you figure out into ~/config/.gtk-3.0/gtk.css
. Here’s a fix I’m currently using:
/* Workaround for [Breeze] [Bug 414763] */
scrollbar trough { min-width: 6px; }
scrollbar:hover trough { min-width: 6px; }
scrollbar.horizontal trough { min-height: 6px; }
scrollbar.horizontal:hover.horizontal trough { min-height: 6px; }
scrollbar slider { min-width: 6px; }
scrollbar slider:hover { min-width: 6px; }
scrollbar.horizontal slider { min-height: 6px; }
scrollbar.horizontal slider { min-height: 6px; }
Fonts
As of GTK 4, lots of people without HiDPI displays have been complaining about blurry text. (i.e. the forcing of the “accurate glyph positioning is more important than crisp glyph edges” approach to low-resolution font rendering that Apple has been using since they stopped using bitmap fonts, long before high-DPI displays as opposed to the approach Microsoft has historically taken of using “font hinting” to find the least bad way to nudge lines to line up with pixel boundaries.)
None of the remaining GTK apps on my desktop have upgraded off GTK 3 yet (in fact, the Geeqie Flatpak finally considered their GTK 3 port debugged enough to migrate off GTK+ 2.x today) but I’ve read that making sure you’re on GTK 4.6 or newer and adding gtk-hint-font-metrics=1
to ~/.config/gtk-4.0/settings.ini
will help.
See also the GTK page on Archwiki and, if you’re trying to harmonize GTK and Qt, the Uniform look for Qt and GTK applications too.
Ttk (Themed Tk)
Here’s a list of Ttk themes you can browse through to find something as close as possible to the rest of your desktop.
If their Installation guide isn’t enough, I wrote about how to to it more manually years ago.
Wine
Last time I tried using Wine’s .msstyle support (many years ago), it made the UI sluggish to respond, so I just found a .reg patch to apply the default Breeze colour scheme to regular Windows 9x-style Win32 widgets instead.
From what I remember, applications have to opt into themed widgets on Windows, while basic colour schemes go back at least as far as Windows 3.1, so you’d probably benefit from one of these even if you do enable a .msstyle
theme… though the comments on the Breeze Dark colour scheme do point out that Wine 7.4 gained an on-by-default msstyle named “Light” that you may need to switch back to “(No style)” in winecfg
.
Here’s what I used, plus a dark variant of it:
Web Apps
Tons of people have written about restyling things with CSS userstyles, so I’ll just give a few tips:
- You can access Firefox’s normal context menu with
Shift+RightClick
if it’s been overridden.
- You can access things like Page Info without knowing their keyboard shortcuts by tapping
Alt
to reveal the traditional menu bar.
- I recommend Stylus as a userstyle host for Firefox and Ungoogled Chromium.
- Here’s an example where I worked around Discord’s lack of easy-to-match CSS classes to turn off the distracting visual cacophony of customized username colours:
/* I don't want my chat client to look like a Hawaiian shirt, thanks. */
span[class^=roleColor-], span[class*=' roleColor-'] {
color: #72767d !important;
}
span[class^=username-], span[class*=' username-'] {
color: #23262a !important;
}
For the record, the ability to do this is one of the reasons I prefer in-browser versions of unavoidable web-tech to Electron versions. (The other major reason is that they’ll accept tighter sandboxing.)