React to system theme changes that happen while LOOT is open
Closed this issue · 2 comments
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.
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