launch: avoid creating multiple QApplications

Accessibility hooks created by QQuick module init are destroyed by the
QApplication destructor and not recreated by a new QApplication.
This commit is contained in:
outfoxxed committed 2026-08-28 00:48:19 -07:00
1 parent 0f9939ca4f
commit 916a0dd90c
8 files changed
+37 -53

No files matched your search

+1
View File
@@ -3,3 +3,4 @@
- Fixed main process crashes on pam subprocess misbehavior.
- Fixed crashes when attempting to create or modify session locks reentrantly.
- Fixed networking state breaking after restarting NetworkManager.
- Fixed accessibility information not being provided for Quickshell windows.
+17 -19
View File
@@ -335,28 +335,33 @@ void LogManager::init(
qInstallMessageHandler(&LogManager::messageHandler);
qCDebug(logLogging) << "Creating offthread logger...";
auto* thread = new QThread();
instance->threadProxy.moveToThread(thread);
thread->start();
QMetaObject::invokeMethod(
&instance->threadProxy,
&LoggingThreadProxy::initInThread,
Qt::BlockingQueuedConnection
);
instance->threadLogging = new ThreadLogging(instance);
instance->threadLogging->init();
qCDebug(logLogging) << "Logger initialized.";
}
void LogManager::initThreadLogging() {
auto* instance = LogManager::instance();
qCDebug(logLogging) << "Moving logger to dedicated thread...";
auto* thread = new QThread();
instance->threadLogging->setParent(nullptr);
instance->threadLogging->moveToThread(thread);
thread->start();
qCDebug(logLogging) << "Logger thread initialized.";
}
void initLogCategoryLevel(const char* name, QtMsgType defaultLevel) {
LogManager::instance()->defaultLevels.insert(QLatin1StringView(name), defaultLevel);
}
void LogManager::initFs() {
QMetaObject::invokeMethod(
&LogManager::instance()->threadProxy,
"initFs",
LogManager::instance()->threadLogging,
&ThreadLogging::initFs,
Qt::BlockingQueuedConnection
);
}
@@ -369,13 +374,6 @@ CategoryFilter LogManager::getFilter(QLatin1StringView category) {
return this->allFilters.value(category);
}
void LoggingThreadProxy::initInThread() {
this->logging = new ThreadLogging(this);
this->logging->init();
}
void LoggingThreadProxy::initFs() { this->logging->initFs(); }
void ThreadLogging::init() {
auto logMfd = memfd_create("quickshell:logs", 0);
+2 -15
View File
@@ -55,20 +55,6 @@ size_t qHash(const LogMessage& message);
class ThreadLogging;
class LoggingThreadProxy: public QObject {
Q_OBJECT;
public:
explicit LoggingThreadProxy() = default;
public slots:
void initInThread();
void initFs();
private:
ThreadLogging* logging = nullptr;
};
namespace qt_logging_registry {
class QLoggingRule;
}
@@ -104,6 +90,7 @@ public:
const QString& prefix = ""
);
static void initThreadLogging();
static void initFs();
static LogManager* instance();
@@ -137,7 +124,7 @@ private:
QTextStream stdoutStream;
QMutex stdoutMutex;
LoggingThreadProxy threadProxy;
ThreadLogging* threadLogging = nullptr;
friend void initLogCategoryLevel(const char* name, QtMsgType defaultLevel);
};
+3 -1
View File
@@ -114,9 +114,11 @@ public:
explicit ThreadLogging(QObject* parent): QObject(parent) {}
void init();
void initFs();
void setupFileLogging();
public slots:
void initFs();
private slots:
void onMessage(const LogMessage& msg, bool showInSparse);
+4 -5
View File
@@ -465,7 +465,7 @@ int ipcCommand(CommandState& cmd) {
});
}
int launchFromCommand(CommandState& cmd, QCoreApplication* coreApplication) {
int launchFromCommand(CommandState& cmd) {
QString configPath;
auto r = locateConfigFile(cmd, configPath);
@@ -485,14 +485,13 @@ int launchFromCommand(CommandState& cmd, QCoreApplication* coreApplication) {
.debugPort = cmd.debug.port,
.waitForDebug = cmd.debug.wait,
},
cmd.exec.argv,
coreApplication
cmd.exec.argv
);
}
} // namespace
int runCommand(int argc, char** argv, QCoreApplication* coreApplication) {
int runCommand(int argc, char** argv) {
auto state = CommandState();
if (auto ret = parseCommand(argc, argv, state); ret != 65535) return ret;
@@ -577,7 +576,7 @@ int runCommand(int argc, char** argv, QCoreApplication* coreApplication) {
"the quickshell package must be rebuilt.\n";
}
return launchFromCommand(state, coreApplication);
return launchFromCommand(state);
}
return 0;
+4 -4
View File
@@ -57,7 +57,7 @@ QString base36Encode(T number) {
} // namespace
int launch(const LaunchArgs& args, char** argv, QCoreApplication* coreApplication) {
int launch(const LaunchArgs& args, char** argv) {
auto pathId = QCryptographicHash::hash(args.configPath.toUtf8(), QCryptographicHash::Md5).toHex();
auto shellId = QString(pathId);
@@ -171,7 +171,6 @@ int launch(const LaunchArgs& args, char** argv, QCoreApplication* coreApplicatio
QsPaths::init(shellId, pathId, pragmas.dataDir, pragmas.stateDir, pragmas.cacheDir);
QsPaths::instance()->linkRunDir();
QsPaths::instance()->linkPathDir();
LogManager::initFs();
Common::INITIAL_ENVIRONMENT = QProcessEnvironment::systemEnvironment();
@@ -279,8 +278,6 @@ int launch(const LaunchArgs& args, char** argv, QCoreApplication* coreApplicatio
QGuiApplication::setDesktopSettingsAware(pragmas.desktopSettingsAware);
delete coreApplication;
QGuiApplication* app = nullptr;
auto qArgC = 0;
@@ -290,6 +287,9 @@ int launch(const LaunchArgs& args, char** argv, QCoreApplication* coreApplicatio
app = new QGuiApplication(qArgC, argv);
}
LogManager::initThreadLogging();
LogManager::initFs();
QGuiApplication::setDesktopFileName(appId);
if (args.debugPort != -1) {
+2 -2
View File
@@ -107,10 +107,10 @@ struct LaunchArgs {
void exitDaemon(int code);
int parseCommand(int argc, char** argv, CommandState& state);
int runCommand(int argc, char** argv, QCoreApplication* coreApplication);
int runCommand(int argc, char** argv);
QString getDisplayConnection();
int launch(const LaunchArgs& args, char** argv, QCoreApplication* coreApplication);
int launch(const LaunchArgs& args, char** argv);
} // namespace qs::launch
+4 -7
View File
@@ -24,7 +24,7 @@ namespace qs::launch {
namespace {
void checkCrashRelaunch(char** argv, QCoreApplication* coreApplication) {
void checkCrashRelaunch(char** argv) {
#if CRASH_HANDLER
auto lastInfoFdStr = qEnvironmentVariable("__QUICKSHELL_CRASH_INFO_FD");
auto dumpPid = qEnvironmentVariable("__QUICKSHELL_CRASH_DUMP_PID").toInt();
@@ -71,7 +71,7 @@ void checkCrashRelaunch(char** argv, QCoreApplication* coreApplication) {
} else {
qCritical() << "Quickshell has been restarted.";
launch({.configPath = info.instance.configPath}, argv, coreApplication);
launch({.configPath = info.instance.configPath}, argv);
}
}
#endif
@@ -123,11 +123,8 @@ int main(int argc, char** argv) {
qsCheckCrash(argc, argv);
#endif
auto qArgC = 1;
auto* coreApplication = new QCoreApplication(qArgC, argv);
checkCrashRelaunch(argv, coreApplication);
auto code = runCommand(argc, argv, coreApplication);
checkCrashRelaunch(argv);
auto code = runCommand(argc, argv);
exitDaemon(code);
return code;