93

Is there a way to set gtk-application-prefer-dark-theme for an application?

This is normally set in the code by the application. Apps such as Eye of Gnome and Totem turn it on. I want to, as a user turn it on, on a per application bases.

For gnome-terminal, I normally use a white text on black background color scheme, and having the dark window border would improve the overall look.

I also want to turn it on for vlc.

don_crissti
  • 82,805
  • Maybe someone still needs a solution to this problem. I wrote a small script: https://github.com/catvitalio/dark-headers. Works as a systemd daemon. – catvitalio Nov 08 '20 at 04:39

10 Answers10

122

With gtk+ ≥ 3.12 you can load a specific theme and its variant (dark, light) on a per-application1 basis via the environment variable GTK_THEME=theme:variant. As per the gtk+ reference manual:

GTK_THEME.  If set, makes GTK+ use the named theme instead of the theme that is
specified by the gtk-theme-name setting [...] It is also possible to specify a
theme variant to load, by appending the variant name with a colon, like this:
GTK_THEME=Adwaita:dark.

So, to load2 the dark variant you would run:

GTK_THEME=Adwaita:dark gedit

Likewise, to achieve the opposite (when the default theme is dark), you load the light variant:

GTK_THEME=Adwaita:light gedit

Note that if you want to use it via a custom launcher (.desktop file) you'll have to prepend env to the command in the Exec line:

Exec=env GTK_THEME=Adwaita:dark eog %U

1: Worth noting that - as per the devs decision - newer gnome-terminal has its own configuration via menu > preferences and it ignores the theme. Also, since this is rather new stuff, some gtk+ 3 applications might not (yet) honor the GTK_THEME environment variable.
2: This doesn't seem to work if you already have a running instance of that application e.g. if nautilus is already running in dark mode then running GTK_THEME=Adwaita:light nautilus will open a new nautilus window but still in dark mode. I don't know if this is a feature or a bug...

don_crissti
  • 82,805
  • So you can name a specific theme, but can't say "dark variant of whatever theme is set"? – XTL Mar 18 '15 at 07:38
  • 3
    @XTL - Exactly. Though GTK_THEME=:light eog seems to be working too... – don_crissti Mar 18 '15 at 12:04
  • 7
    This doesn't seem to work for most applications. – Thayne Jun 01 '15 at 23:53
  • 2
    I haven't been able to find an application that this works for yet, when I have a dark theme. – Thayne Jun 01 '15 at 23:58
  • @Thayne - as per the first line in my post, this works for systems/apps using gtk3 version 3.12 or higher (but the apps must honor the GTK_THEME env variable). – don_crissti Jun 02 '15 at 00:27
  • 4
    I have tried the above (for .desktop files), but it doesn't work, not even with the env. When launched from terminal it works prefectly. I use gtk 3.14.5-1+deb8u1, and tried with gedit 3.14.0-3, running on Debian "jessie/stable" 8. – aBarocio80 Jul 13 '16 at 18:13
  • @aBarocio80 - works fine here (archlinux + gnome 3 - up to date). Any custom launcher I create in ~/.local/share/applications/ (including for gedit) honors the env GTK_THEME directive in the Exec field so most likely something is wrong on your setup but since I don't use debian/derivatives I can't help you. – don_crissti Jul 13 '16 at 18:26
  • As not all themes have variants, one could try something like GTK_THEME=NAME_OF_THEME APP. But this works only for some apps (from what I have tested: synaptic, gdebi, transmission-gtk, uget-gtk, basic text editors). Thunar and Pcmanfm do not follow, which is not a big issue, as the main non-specific theme is usually meant for the file manager. But libreoffice and vlc which are not great with a dark theme do not follow. What (somewhat) works for those is this: https://askubuntu.com/a/427440/47206 –  Nov 27 '17 at 14:15
  • sh -c can be used here instead of env –  Nov 27 '17 at 16:49
  • 1
    Specifically for gnome-terminal, you can use the following gsettings set org.gnome.Terminal.Legacy.Settings theme-variant 'dark' – Nick Bull Aug 27 '19 at 14:07
  • For Charles Proxy (a big Java app), at least on Pop!_OS it's very hard to read on Dark Mode, so I changed /usr/share/applications/charles-proxy.desktop and changed the Exec line to look like: Exec=env GTK_THEME=Adwaita:light /usr/bin/charles4 %F this makes Charles a bright lamp, but readable. – Martin Marconcini Dec 12 '19 at 11:36
  • @aBarocio80 - Exec=env GTK_THEME=Adwaita:dark geany %F in a .desktop file works for Ubuntu 18.04, gtk 3.22.30-1ubu. I have also added alias geany='GTK_THEME=Adwaita:dark geany' in .bash_aliases for launches from the terminal. – chus Nov 26 '20 at 17:34
29

For GTK+-3 applications, you can enforce the dark theme variant using GtkSettings' settings.ini:

$ mkdir -p $HOME/.config/gnome-terminal/gtk-3.0 # the path before gtk-3.0 is arbitrary
$ cat >> $HOME/.config/gnome-terminal/gtk-3.0/settings.ini << EOF
[Settings]
gtk-application-prefer-dark-theme=true
EOF
$ echo 'alias gnome-terminal="XDG_CONFIG_HOME=$HOME/.config/gnome-terminal gnome-terminal" >> $HOME/.bashrc

For non-GTK+ applications like vnc, you can still enforce dark window decorations by setting the _GTK_THEME_VARIANT X property of type UTF8_STRING to dark. To do this with xprop, type the following command and click the window afterwards:

$ xprop -f _GTK_THEME_VARIANT 8u -set _GTK_THEME_VARIANT "dark"

xprop can also select windows by the WM_NAME property (the title bar label) or by window id:

$ xprop -f _GTK_THEME_VARIANT 8u -set _GTK_THEME_VARIANT "dark" -name "Spotify Premium - Linux Preview"
$ xprop -f _GTK_THEME_VARIANT 8u -set _GTK_THEME_VARIANT "dark" -id 0x380002b

To get window ids and names, use xlsclients -l.

  • For some reason gnome-terminal has decided it's too much effort to keep the code for the Dark theme, so unless your distro has patched this back in this wont work for gnome-terminal – MattSturgeon Mar 12 '16 at 21:03
  • xlsclients won't get the right ids (I don't know why). I used wmctrl -lp instead – Vassilis May 25 '22 at 18:52
10

Here is a bash script I have used to launch a application with a different theme. Haven't used it in years though, so I don't know if it will work with the current GTK.

#!/bin/bash
# lauch a gtk application with a different theme
# set GTKRCFILE variable to your favourite theme
GTKRCFILE=Clearlooks
GTK2_RC_FILES=/usr/share/themes/"$GTKRCFILE"/gtk-2.0/gtkrc "$@"

Here is a bit of info I got off the ubuntu fourms archives. Not sure if it will be a problem. (here) There is also a blog post detailing this method a little more. (here) and (here). There is also a similar question on this site that has already been answered. (here)

Under gnome, apps get their theme from the gnome-settings-daemon. This instantaneously applies any theme change to all active applications, making per-appplication theme changing impossible.

  • 6
    Typo or mistake? ('gnome-settings-demon")... The word is daemon (not demon).. It has a very different root meaning: …(in ancient Greek belief) Daemons are good or benevolent supernatural beings between mortals and gods ... daemon=good / demon=bad ... http://en.wikipedia.org/wiki/Daemon_%28classical_mythology%29 .. (pronounced day-mon) – Peter.O Jun 10 '11 at 08:03
  • Typo, that's what happens when you don't spell check everything :| – giodamelio Jun 10 '11 at 09:27
  • 3
    @Peter.O: Different meaning in present day English, but same origin indeed. http://www.etymonline.com/index.php?term=demon – Joce Jan 27 '16 at 08:49
  • 1
    tried with GTK2_RC_FILES=/usr/share/themes/Adwaita/gtk-2.0/gtkrc /opt/ide/eclipse and does't worked – Robbi Nespu Aug 09 '18 at 09:23
  • This works well for gapcmon – Coder Guy Nov 09 '19 at 03:06
4

If somebody still need it, I've created simple app that will automatically set dark theme for specified apps.

You can find it here: https://github.com/galczo5/gnome-dark-apps

galczo5
  • 41
  • 1
3

I wrote a little wrapper script for that:

#!/bin/bash


if [ $# -eq 0 ]; then
    xprop -f _GTK_THEME_VARIANT 8u -set _GTK_THEME_VARIANT "dark"
    exit $?
fi


GTK_THEME="$(gsettings get org.gnome.desktop.interface gtk-theme)"
export  GTK_THEME="${a%%:*}:dark"
export GTK_THEME_VARIANT="dark"
"$@" & PID="$!"
echo "started darkening for PID=$PID"
cnt=0
while :; do
    if [ $cnt -lt 1000 ]; then
        sleep .1
        let 'x=x-1'
    else
        sleep 5
    fi
    if ! kill -0 $PID 2>/dev/null; then
        echo "darkening for PID=$PID done"
        exit 0
    fi
    REGEX="$(echo $PID | cat - <(command ps -o pid:1 --no-headers --ppid $PID) | paste -sd "|" -)"
    wmctrl -lp \
        | rg -i "^(0x[a-f0-9]+)\s+\d+\s+($REGEX)\s" -o --replace '$1' \
        | xargs -I @ xprop -f _GTK_THEME_VARIANT 8u -set _GTK_THEME_VARIANT "dark" -id @
done

It'S using https://github.com/BurntSushi/ripgrep for REGEX

3

I have the same issue with dark theme on Ubuntu 20.04 and have a work around for the issue with vmware horizon client. I would prefer dark mode to be supported but this will do for now.

  • Close vmware horizon client.
  • In terminal navigate to this directory:
    cd /usr/share/applications
    
  • Once in there
    sudo nano vmware-view.desktop
    
  • On line 4 it should have:
    Exec=vmware-view %u
    
  • Change it to:
    Exec=env GTK_THEME=Yaru-light vmware-view %u
    
  • Save the file.

Restart app and now you should be able to view everything properly.

If you don't have Yaru-light as a theme you may need to change it to what ever your OS light theme is named.

I hope this helps some people.

AdminBee
  • 22,803
2

Specifically for gnome-terminal, you can use the following to make the specific application dark:

gsettings set org.gnome.Terminal.Legacy.Settings theme-variant 'dark'
Nick Bull
  • 563
2

This is my solution as of August 2022, based on galczo5's answer & code:

#!/bin/bash
PREVID=
CLASSES=(
    "code"
    "insomnia"
    "spotify"
)
while true;
do
    ID=$(xprop -root _NET_ACTIVE_WINDOW | egrep -o '0x[a-fA-F0-9]+')
    if [[ "$ID" != "0x0" ]]; then
        CLASS=$(xprop -id "$ID" WM_CLASS)
        if [[ "$ID" != "$PREVID" ]]; then
            PREVID=$ID
            for i in "${CLASSES[@]}"
            do
                if echo "$CLASS" | grep -lq "$i"; then
                    echo "Set dark theme to $CLASS $ID"
                    xprop -f _GTK_THEME_VARIANT 8u -set _GTK_THEME_VARIANT "dark" -id "$ID"
                fi
            done
        fi
    fi
    sleep 1
done

Put this in a script anywhere in your system, it'll run in a loop every 1 second (or whatever you set in the last sleep 1 line). Put the window classes you want to have dark theme on in the CLASSES array, following the example.

DARKGuy
  • 121
  • 2
1

Merging the various solutions by paveloom and DARKGuy:

watch -n 5 "xdotool search --sync --onlyvisible --classname '' | xargs -I{} -r xprop -f _GTK_THEME_VARIANT 8u -set _GTK_THEME_VARIANT 'dark' -id {}"

It runs every 5 seconds and set every window title bar to black.

The xargs call needs an -n1 or the -I{} <command> {} syntax, including when setting an explicit classname as there may be multiple pids and the command should be set on every of them (the command would fail if more than one pid is passed).

0

Simplifying the solution proposed by Black Rain and expanding on the Florian Müllner's answer, you can use xprop to dynamically change the theme variant and xdotool to find the target window's ID after it's open, all in one call. Here's an example for an Emacs client:

emacsclient -c -a '' & xdotool search --sync --onlyvisible --classname "emacs" | xargs -r xprop -f _GTK_THEME_VARIANT 8u -set _GTK_THEME_VARIANT "dark" -id

To use it in a .desktop file, wrap it in a shell call:

Exec=bash -c 'emacsclient -c -a "" %F & xdotool search --sync --onlyvisible --class "emacs" | xargs -r xprop -f _GTK_THEME_VARIANT 8u -set _GTK_THEME_VARIANT "dark" -id'
  • This appears (superficially) to be similar to Black Rain’s answer.  Can you explain how yours is different, and why you are using xdotool (i.e., what good does it do)? … … … … … … … … … … Please do not respond in comments; [edit] your answer to make it clearer and more complete. – G-Man Says 'Reinstate Monica' May 02 '22 at 20:22