Skip to content

Commit

Permalink
Detect system dark mode preference changes without restart on Linux
Browse files Browse the repository at this point in the history
The new org.freedesktop.appearance.color-scheme key allows us to do this
in a reliable way.

Recently freedesktop standardized the system dark mode preference in a
desktop environment independent way in the xdg-desktop-portal
specification.

The specification can be seen here: https://github.com/flatpak/xdg-desktop-portal/blob/d7a304a00697d7d608821253cd013f3b97ac0fb6/data/org.freedesktop.impl.portal.Settings.xml#L33-L45

KDE supports this since KDE Plasma 5.24 and Gnome supports this since
Gnome 42.

Relevant blog post: https://blogs.gnome.org/alexm/2021/10/04/dark-style-preference/

Fixes #7146
  • Loading branch information
vimpostor committed Feb 16, 2022
1 parent 58615d7 commit bc37fc3
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/gui/osutils/nixutils/NixUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "NixUtils.h"

#include <QApplication>
#include <QDBusInterface>
#include <QDir>
#include <QPointer>
#include <QStandardPaths>
Expand Down Expand Up @@ -60,6 +61,15 @@ NixUtils::NixUtils(QObject* parent)
{
dpy = QX11Info::display();
rootWindow = QX11Info::appRootWindow();

// notify about system color scheme changes
QDBusConnection sessionBus = QDBusConnection::sessionBus();
sessionBus.connect("org.freedesktop.portal.Desktop",
"/org/freedesktop/portal/desktop",
"org.freedesktop.portal.Settings",
"SettingChanged",
this,
SLOT(handleColorSchemeChanged(QString,QString,QDBusVariant)));
}

NixUtils::~NixUtils()
Expand All @@ -68,6 +78,11 @@ NixUtils::~NixUtils()

bool NixUtils::isDarkMode() const
{
// prefer freedesktop "org.freedesktop.appearance color-scheme" setting
if (m_systemColorschemePref != ColorschemePref::PreferNone) {
return m_systemColorschemePref == ColorschemePref::PreferDark;
}

if (!qApp || !qApp->style()) {
return false;
}
Expand Down Expand Up @@ -257,3 +272,11 @@ bool NixUtils::unregisterGlobalShortcut(const QString& name)
m_globalShortcuts.remove(name);
return true;
}

void NixUtils::handleColorSchemeChanged(QString ns, QString key, QDBusVariant value)
{
if (ns == "org.freedesktop.appearance" && key == "color-scheme") {
m_systemColorschemePref = static_cast<ColorschemePref>(value.variant().toInt());
emit interfaceThemeChanged();
}
}
13 changes: 13 additions & 0 deletions src/gui/osutils/nixutils/NixUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include "gui/osutils/OSUtilsBase.h"
#include <QAbstractNativeEventFilter>
#include <QtDBus/QDBusVariant>
#include <QSharedPointer>

class NixUtils : public OSUtilsBase, QAbstractNativeEventFilter
Expand Down Expand Up @@ -48,6 +49,9 @@ class NixUtils : public OSUtilsBase, QAbstractNativeEventFilter
return false;
}

private slots:
void handleColorSchemeChanged(QString ns, QString key, QDBusVariant value);

private:
explicit NixUtils(QObject* parent = nullptr);
~NixUtils() override;
Expand All @@ -66,6 +70,15 @@ class NixUtils : public OSUtilsBase, QAbstractNativeEventFilter
};
QHash<QString, QSharedPointer<globalShortcut>> m_globalShortcuts;

// defined as per "org.freedesktop.appearance color-scheme" spec in
// https://github.com/flatpak/xdg-desktop-portal/blob/d7a304a00697d7d608821253cd013f3b97ac0fb6/data/org.freedesktop.impl.portal.Settings.xml#L33-L45
enum ColorschemePref {
PreferNone,
PreferDark,
PreferLight
};
ColorschemePref m_systemColorschemePref = ColorschemePref::PreferNone;

Q_DISABLE_COPY(NixUtils)
};

Expand Down

0 comments on commit bc37fc3

Please sign in to comment.