loot/loot

React to system theme changes that happen while LOOT is open

Closed this issue · 2 comments

Ortham commented

It would be good if LOOT's theme updated when the system theme changes, e.g. when transitioning from a daytime light theme to a nighttime dark theme.

Qt has a QStyleHints::colorSchemeChanged signal that's supposed to fire whenever Qt detects that the system theme's color scheme has changed, but I haven't seen the signal fire on Linux when running LOOT as a Flatpak application, only when running it as an unpackaged executable. I guess that the sandboxing is interfering, but I'm not sure how to resolve that.

  • On a Manjaro KDE 22.1.3 Linux desktop in a Hyper-V VM I can see the org.kde.kdeglobals.General ColorScheme event being fired in dbus and that's what Qt listens for. However, only the title bar and window border changes, the application UI stays in its initial colour scheme.
  • On a Ubuntu (Gnome) 20.04 Linux desktop in a Hyper-V VM I can see the org.gnome.desktop.interface gtk-theme event being fired in dbus and that's also what Qt listens for. However, only the title bar and window border changes, the application UI stays in its initial colour scheme.
    • If I run the compiled LOOT binary directly (not in a Flatpak package), then I can see that the signal gets fired. Unfortunately the application UI stays in its initial colour scheme.
  • On an Ubuntu (Gnome) 22.04 Linux desktop as a host OS, the application UI changes to reflect the system theme change (e.g. all backgrounds and text change colour), but the signal still doesn't fire so the default theme's adjustments aren't made (e.g. error messages have white text when the colour scheme is dark).
    • If I run the compiled LOOT binary directly (not in a Flatpak package), then I can see that the signal gets fired. Unfortunately the application UI stays in its initial colour scheme.

It does work on Windows, but there the dark theme looks bad enough that I don't want LOOT using it by default when the OS theme is dark.

I've pushed the code to the linux-improvements branch, in case it works on some other setup.

Ortham commented

Using QtDBus I've been able to verify that LOOT is able to receive DBus signals like

signal time=1692653062.379963 sender=:1.106 -> destination=(null destination) serial=375 path=/org/freedesktop/portal/desktop; interface=org.freedesktop.impl.portal.Settings; member=SettingChanged
   string "org.gnome.desktop.interface"
   string "gtk-theme"
   variant       string "Yaru-dark"

which is what Qt connects to and listens for and uses to set the colour scheme. That goes through a few function calls but eventually emits the Qt signal that I'm expecting to see.

As far as I can tell, there's no reason why Qt shouldn't be emitting the signal I'm expecting, but it doesn't.

Some very hacky code snippets showing how I checked that:

#include <QtDBus/QDBusConnection>
#include <QtDBus/QDBusVariant>

void MainWindow::handleDbusSignal(QString arg1, QString arg2, QDBusVariant arg3) {
  	const auto logger = getLogger();
  	if (logger) {
            logger->debug("Received DBus signal: {}, {}, {}", 
                 arg1.toStdString(), 
                 arg2.toStdString(), 
                 arg3.variant().toString().toStdString());
  	}
}

void MainWindow::setupUi() {
        const auto logger = getLogger();
	if (!QDBusConnection::sessionBus().isConnected()) {
	    if (logger) {
		    logger->error("Not connected to session bus");
	    }
	}
	
        const auto result = QDBusConnection::sessionBus().connect(
                 "org.freedesktop.portal.Desktop", 
                 "/org/freedesktop/portal/desktop", 
                 "org.freedesktop.portal.Settings", 
                 "SettingChanged", 
                 this, 
                 SLOT(handleDbusSignal(QString,QString,QDBusVariant)));

        if (!result) {
	        if (logger) {
	         	logger->error("Failed to connect to signal");
	        }
        }

        // snip
}

Running as a Flatpak on my Ubuntu 20.04 VM, LOOT's log includes:

[22:32:19.222679] [debug]: Received DBus signal: org.gnome.desktop.interface, gtk-theme, Yaru-dark

and running as a Flatpak on my Manjaro VM, LOOT's log includes:

[23:49:02.760082] [debug]: Received DBus signal: org.kde.kdeglobals.General, ColorScheme, BreathDark
[23:49:02.765658] [debug]: Received DBus signal: org.freedesktop.appearance, color-scheme, 1
Ortham commented

I've merged the code for reacting to system theme changes in 4d3ab19. Although it doesn't work consistently, that's due to some issue in Qt or its interaction with Flatpak or the OS, not LOOT's code, so I'm closing this as done.