Skip to content

Commit 02784b0

Browse files
authored
Fix race in dark mode detection (#13366)
The current dark mode detection implementation is prone to a race between an asynchronous D-Bus method call in NixUtils::NixUtils() and bootstrap logic in Bootstrap::bootstrap(). This race condition causes dark mode detection to fail intermittently during application startup. The sequence of events in the failing case is as follows: 1. In the Application constructor, osUtils is instantiated, causing the NixUtils constructor to run. 2. An asynchronous D-Bus method call is issued to query the value of the org.freedesktop.appearance.color-scheme key. 3. Bootstrap code runs. In particular, a prctl() system call is issued to set the keepassxc process "dumpable" attribute to 0. 4. xdg-desktop-portal begins handling the D-Bus method call initiated in step 2. Flatpak detection logic is invoked, triggering an attempt to access /proc/<pid>/root, where <pid> is the PID of the keepassxc process. 5. Since the keepassxc process had its "dumpable" attribute set to 0 in step 3, its /proc/<pid>/root entry becomes owned by root. This causes the access attempt from xdg-desktop-portal to fail, which in turn causes the D-Bus method call to fail as well. As a result, the registered callback (NixUtils::handleColorSchemeRead()) is never invoked, effectively breaking dark mode detection. If xdg-desktop-portal completes its permission checks before the prctl() system call is issued (that is, if the order of steps 3 and 4 is reversed), everything works correctly. Fix by replacing the asynchronous D-Bus method call with a synchronous one, preventing bootstrap code from executing while the D-Bus call is still pending. * Use ReadOne D-Bus method instead of Read The org.freedesktop.portal.Settings.Read method is deprecated. Replace its use with org.freedesktop.portal.Settings.ReadOne and adjust reply handling accordingly. Remove NixUtils::handleColorSchemeRead(), which is no longer needed.
1 parent 36fbca4 commit 02784b0

2 files changed

Lines changed: 7 additions & 11 deletions

File tree

src/gui/osutils/nixutils/NixUtils.cpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#include <QApplication>
2525
#include <QDBusInterface>
26+
#include <QDBusReply>
2627
#include <QDebug>
2728
#include <QDir>
2829
#include <QPointer>
@@ -81,10 +82,12 @@ NixUtils::NixUtils(QObject* parent)
8182
this,
8283
SLOT(handleColorSchemeChanged(QString, QString, QDBusVariant)));
8384

84-
QDBusMessage msg = QDBusMessage::createMethodCall(
85-
"org.freedesktop.portal.Desktop", "/org/freedesktop/portal/desktop", "org.freedesktop.portal.Settings", "Read");
86-
msg << QVariant("org.freedesktop.appearance") << QVariant("color-scheme");
87-
sessionBus.callWithCallback(msg, this, SLOT(handleColorSchemeRead(QDBusVariant)));
85+
QDBusInterface desktopPortal(
86+
"org.freedesktop.portal.Desktop", "/org/freedesktop/portal/desktop", "org.freedesktop.portal.Settings");
87+
QDBusReply<QDBusVariant> reply = desktopPortal.call("ReadOne", "org.freedesktop.appearance", "color-scheme");
88+
if (reply.isValid()) {
89+
setColorScheme(reply.value());
90+
}
8891
}
8992

9093
NixUtils::~NixUtils() = default;
@@ -359,12 +362,6 @@ bool NixUtils::unregisterGlobalShortcut(const QString& name)
359362
return true;
360363
}
361364

362-
void NixUtils::handleColorSchemeRead(QDBusVariant value)
363-
{
364-
value = qvariant_cast<QDBusVariant>(value.variant());
365-
setColorScheme(value);
366-
}
367-
368365
void NixUtils::handleColorSchemeChanged(QString ns, QString key, QDBusVariant value)
369366
{
370367
if (ns == "org.freedesktop.appearance" && key == "color-scheme") {

src/gui/osutils/nixutils/NixUtils.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ class NixUtils : public OSUtilsBase, QAbstractNativeEventFilter
5353
quint64 getProcessStartTime() const;
5454

5555
private slots:
56-
void handleColorSchemeRead(QDBusVariant value);
5756
void handleColorSchemeChanged(QString ns, QString key, QDBusVariant value);
5857
void launchAtStartupRequested(uint response, const QVariantMap& results);
5958

0 commit comments

Comments
 (0)