launch: initialize QuickshellTracked before almost anything else

This fixes consumers like WlSessionLock getting connections to
QGuiApplication::screenAdded before QuickshellTracked::updateScreens
can run if the user never references the Quickshell singleton from QML
first.
This commit is contained in:
outfoxxed committed 2026-08-28 19:27:13 -07:00
1 parent fd116897cf
commit ec0be5b36f
4 files changed
+21 -6

No files matched your search

+1
View File
@@ -4,3 +4,4 @@
- Fixed crashes when attempting to create or modify session locks reentrantly. - Fixed crashes when attempting to create or modify session locks reentrantly.
- Fixed networking state breaking after restarting NetworkManager. - Fixed networking state breaking after restarting NetworkManager.
- Fixed accessibility information not being provided for Quickshell windows. - Fixed accessibility information not being provided for Quickshell windows.
- Fixed `WlSessionLockSurface.screen` being null and never updating with a real screen on monitor plug.
+14 -6
View File
@@ -88,6 +88,8 @@ QuickshellTracked::QuickshellTracked() {
} }
} }
// FIXME: Some callers can potentially pass a freed QScreen here which is why we don't init a new one.
// The QuickshellTracked::init() in launch.cpp makes sure our screenAdded handler runs first for now.
QuickshellScreenInfo* QuickshellTracked::screenInfo(QScreen* screen) const { QuickshellScreenInfo* QuickshellTracked::screenInfo(QScreen* screen) const {
for (auto* info: this->screens) { for (auto* info: this->screens) {
if (info->screen == screen) return info; if (info->screen == screen) return info;
@@ -96,13 +98,19 @@ QuickshellScreenInfo* QuickshellTracked::screenInfo(QScreen* screen) const {
return nullptr; return nullptr;
} }
namespace {
static QuickshellTracked* qsTrackedInstance = nullptr; // NOLINT
}
void QuickshellTracked::init() {
if (qsTrackedInstance) qFatal() << "Tried to reinitialize QuickshellTracked";
qsTrackedInstance = new QuickshellTracked();
QJSEngine::setObjectOwnership(qsTrackedInstance, QJSEngine::CppOwnership);
}
QuickshellTracked* QuickshellTracked::instance() { QuickshellTracked* QuickshellTracked::instance() {
static QuickshellTracked* instance = nullptr; // NOLINT if (!qsTrackedInstance) qFatal() << "Tried to get QuickshellTracked instance before init";
if (instance == nullptr) { return qsTrackedInstance;
QJSEngine::setObjectOwnership(instance, QJSEngine::CppOwnership);
instance = new QuickshellTracked();
}
return instance;
} }
void QuickshellTracked::updateScreens() { void QuickshellTracked::updateScreens() {
+1
View File
@@ -70,6 +70,7 @@ public:
QVector<QuickshellScreenInfo*> screens; QVector<QuickshellScreenInfo*> screens;
QuickshellScreenInfo* screenInfo(QScreen* screen) const; QuickshellScreenInfo* screenInfo(QScreen* screen) const;
static void init();
static QuickshellTracked* instance(); static QuickshellTracked* instance();
private slots: private slots:
+5
View File
@@ -22,6 +22,7 @@
#include "../core/logging.hpp" #include "../core/logging.hpp"
#include "../core/paths.hpp" #include "../core/paths.hpp"
#include "../core/plugin.hpp" #include "../core/plugin.hpp"
#include "../core/qmlglobal.hpp"
#include "../core/rootwrapper.hpp" #include "../core/rootwrapper.hpp"
#include "../ipc/ipc.hpp" #include "../ipc/ipc.hpp"
#include "build.hpp" #include "build.hpp"
@@ -299,6 +300,10 @@ int launch(const LaunchArgs& args, char** argv) {
QQmlDebuggingEnabler::startTcpDebugServer(args.debugPort, wait); QQmlDebuggingEnabler::startTcpDebugServer(args.debugPort, wait);
} }
// This needs to run early to get the first connection to QGuiApplication::screenAdded() in Qs.
// If we don't do that, attempts to get a QuickshellScreenInfo from a QScreen will fail in screenAdded bindings.
QuickshellTracked::init();
QsEnginePlugin::initPlugins(); QsEnginePlugin::initPlugins();
// Base window transparency appears to be additive. // Base window transparency appears to be additive.