diff --git a/changelog/next.md b/changelog/next.md index 761161d..b430a27 100644 --- a/changelog/next.md +++ b/changelog/next.md @@ -43,8 +43,6 @@ set shell id. - Added `QS_DISABLE_CRASH_HANDLER` environment variable to disable crash handling. - Added `QS_CRASHREPORT_URL` environment variable to allow overriding the crash reporter link. - Added `AppId` pragma and `QS_APP_ID` environment variable to allow overriding the desktop application ID. -- Added `DropExpensiveFonts` pragma and `QS_DROP_EXPENSIVE_FONTS` environment variable which avoids loading fonts which may cause lag and excessive memory usage if many variants are used. -- Unrecognized pragmas are no longer a hard error for future backward compatibility. ## Bug Fixes @@ -73,7 +71,6 @@ set shell id. - Fixed JsonAdapter sending unnecessary property changes for primitive values. - Fixed JsonAdapter serialization for lists. - Fixed pipewire crashes after hotplugging devices and changing default outputs. -- Fixed launches failing for `--daemonize` on some systems. ## Packaging Changes diff --git a/src/launch/launch.cpp b/src/launch/launch.cpp index dcdefa7..0f5b090 100644 --- a/src/launch/launch.cpp +++ b/src/launch/launch.cpp @@ -77,7 +77,6 @@ int launch(const LaunchArgs& args, char** argv, QCoreApplication* coreApplicatio QString iconTheme = qEnvironmentVariable("QS_ICON_THEME"); QHash envOverrides; QString appId = qEnvironmentVariable("QS_APP_ID"); - bool dropExpensiveFonts = false; QString dataDir; QString stateDir; QString cacheDir; @@ -93,7 +92,6 @@ int launch(const LaunchArgs& args, char** argv, QCoreApplication* coreApplicatio else if (pragma == "NativeTextRendering") pragmas.nativeTextRendering = true; else if (pragma == "IgnoreSystemSettings") pragmas.desktopSettingsAware = false; else if (pragma == "RespectSystemStyle") pragmas.useSystemStyle = true; - else if (pragma == "DropExpensiveFonts") pragmas.dropExpensiveFonts = true; else if (pragma.startsWith("IconTheme ")) pragmas.iconTheme = pragma.sliced(10); else if (pragma.startsWith("Env ")) { auto envPragma = pragma.sliced(4); @@ -118,7 +116,8 @@ int launch(const LaunchArgs& args, char** argv, QCoreApplication* coreApplicatio } else if (pragma.startsWith("CacheDir ")) { pragmas.cacheDir = pragma.sliced(9).trimmed(); } else { - qWarning() << "Unrecognized pragma" << pragma; + qCritical() << "Unrecognized pragma" << pragma; + return -1; } } else if (line.startsWith("import")) break; } @@ -178,48 +177,6 @@ int launch(const LaunchArgs& args, char** argv, QCoreApplication* coreApplicatio qputenv(var.toUtf8(), val.toUtf8()); } - pragmas.dropExpensiveFonts |= qEnvironmentVariableIntValue("QS_DROP_EXPENSIVE_FONTS") == 1; - - if (pragmas.dropExpensiveFonts) { - if (auto* runDir = QsPaths::instance()->instanceRunDir()) { - auto baseConfigPath = qEnvironmentVariable("FONTCONFIG_FILE"); - if (baseConfigPath.isEmpty()) baseConfigPath = "/etc/fonts/fonts.conf"; - - auto filterPath = runDir->filePath("fonts-override.conf"); - auto filterFile = QFile(filterPath); - if (filterFile.open(QFile::WriteOnly | QFile::Truncate | QFile::Text)) { - auto filterTemplate = QStringLiteral(R"( - - - %1 - - - - - woff - - - - - woff2 - - - - - -)"); - - QTextStream(&filterFile) << filterTemplate.arg(baseConfigPath); - filterFile.close(); - qputenv("FONTCONFIG_FILE", filterPath.toUtf8()); - } else { - qCritical() << "Could not write fontconfig filter to" << filterPath; - } - } else { - qCritical() << "Could not create fontconfig filter: instance run directory unavailable"; - } - } - // The qml engine currently refuses to cache non file (qsintercept) paths. // if (auto* cacheDir = QsPaths::instance()->cacheDir()) { diff --git a/src/launch/main.cpp b/src/launch/main.cpp index efd6628..a324e09 100644 --- a/src/launch/main.cpp +++ b/src/launch/main.cpp @@ -84,29 +84,21 @@ void exitDaemon(int code) { close(DAEMON_PIPE); - auto fd = open("/dev/null", O_RDWR); - if (fd == -1) { - qCritical().nospace() << "Failed to open /dev/null for daemon stdio" << errno << ": " - << qt_error_string(); - return; + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + + if (open("/dev/null", O_RDONLY) != STDIN_FILENO) { // NOLINT + qFatal() << "Failed to open /dev/null on stdin"; } - if (dup2(fd, STDIN_FILENO) != STDIN_FILENO) { // NOLINT - qCritical().nospace() << "Failed to set daemon stdin to /dev/null" << errno << ": " - << qt_error_string(); + if (open("/dev/null", O_WRONLY) != STDOUT_FILENO) { // NOLINT + qFatal() << "Failed to open /dev/null on stdout"; } - if (dup2(fd, STDOUT_FILENO) != STDOUT_FILENO) { // NOLINT - qCritical().nospace() << "Failed to set daemon stdout to /dev/null" << errno << ": " - << qt_error_string(); + if (open("/dev/null", O_WRONLY) != STDERR_FILENO) { // NOLINT + qFatal() << "Failed to open /dev/null on stderr"; } - - if (dup2(fd, STDERR_FILENO) != STDERR_FILENO) { // NOLINT - qCritical().nospace() << "Failed to set daemon stderr to /dev/null" << errno << ": " - << qt_error_string(); - } - - close(fd); } int main(int argc, char** argv) { diff --git a/src/x11/i3/ipc/controller.cpp b/src/x11/i3/ipc/controller.cpp index a83afd4..1a08c63 100644 --- a/src/x11/i3/ipc/controller.cpp +++ b/src/x11/i3/ipc/controller.cpp @@ -276,7 +276,7 @@ void I3IpcController::handleWorkspaceEvent(I3IpcEvent* event) { if (newWorkspace->bindableMonitor().value()) { auto* monitor = newWorkspace->bindableMonitor().value(); - monitor->setActiveWorkspace(newWorkspace); + monitor->setFocusedWorkspace(newWorkspace); this->bFocusedMonitor = monitor; } } else if (change == "empty") { @@ -286,7 +286,13 @@ void I3IpcController::handleWorkspaceEvent(I3IpcEvent* event) { if (oldWorkspace != nullptr) { qCInfo(logI3Ipc) << "Deleting" << oldWorkspace->bindableId().value() << name; + + if (this->bFocusedWorkspace == oldWorkspace) { + this->bFocusedMonitor->setFocusedWorkspace(nullptr); + } + this->workspaces()->removeObject(oldWorkspace); + delete oldWorkspace; } else { qCInfo(logI3Ipc) << "Workspace" << name << "has already been deleted"; diff --git a/src/x11/i3/ipc/monitor.cpp b/src/x11/i3/ipc/monitor.cpp index 7afb68e..fb0ec86 100644 --- a/src/x11/i3/ipc/monitor.cpp +++ b/src/x11/i3/ipc/monitor.cpp @@ -40,37 +40,21 @@ void I3Monitor::updateFromObject(const QVariantMap& obj) { this->bHeight = rect.value("height").value(); this->bScale = obj.value("scale").value(); - auto* activeWorkspace = this->bActiveWorkspace.value(); - if (!activeWorkspace || activeWorkspaceName != activeWorkspace->bindableName().value()) { + if (!this->bActiveWorkspace + || activeWorkspaceName != this->bActiveWorkspace->bindableName().value()) + { if (activeWorkspaceName.isEmpty()) { - activeWorkspace = nullptr; + this->bActiveWorkspace = nullptr; } else { - activeWorkspace = this->ipc->findWorkspaceByName(activeWorkspaceName); + this->bActiveWorkspace = this->ipc->findWorkspaceByName(activeWorkspaceName); } }; - this->setActiveWorkspace(activeWorkspace); - Qt::endPropertyUpdateGroup(); } void I3Monitor::updateInitial(const QString& name) { this->bName = name; } -void I3Monitor::setActiveWorkspace(I3Workspace* workspace) { - auto* oldWorkspace = this->bActiveWorkspace.value(); - if (oldWorkspace == workspace) return; - - if (oldWorkspace) { - QObject::disconnect(oldWorkspace, nullptr, this, nullptr); - } - - if (workspace) { - QObject::connect(workspace, &QObject::destroyed, this, &I3Monitor::onActiveWorkspaceDestroyed); - } - - this->bActiveWorkspace = workspace; -} - -void I3Monitor::onActiveWorkspaceDestroyed() { this->bActiveWorkspace = nullptr; } +void I3Monitor::setFocusedWorkspace(I3Workspace* workspace) { this->bActiveWorkspace = workspace; }; } // namespace qs::i3::ipc diff --git a/src/x11/i3/ipc/monitor.hpp b/src/x11/i3/ipc/monitor.hpp index c328d8b..cd348b1 100644 --- a/src/x11/i3/ipc/monitor.hpp +++ b/src/x11/i3/ipc/monitor.hpp @@ -55,7 +55,7 @@ public: [[nodiscard]] QBindable bindableScale() { return &this->bScale; } [[nodiscard]] QBindable bindableFocused() { return &this->bFocused; } - [[nodiscard]] QBindable bindableActiveWorkspace() const { + [[nodiscard]] QBindable bindableActiveWorkspace() { return &this->bActiveWorkspace; } @@ -64,7 +64,7 @@ public: void updateFromObject(const QVariantMap& obj); void updateInitial(const QString& name); - void setActiveWorkspace(I3Workspace* workspace); + void setFocusedWorkspace(I3Workspace* workspace); signals: void idChanged(); @@ -79,9 +79,6 @@ signals: void lastIpcObjectChanged(); void focusedChanged(); -private slots: - void onActiveWorkspaceDestroyed(); - private: I3IpcController* ipc; diff --git a/src/x11/i3/ipc/workspace.cpp b/src/x11/i3/ipc/workspace.cpp index 530f0a2..03fadc2 100644 --- a/src/x11/i3/ipc/workspace.cpp +++ b/src/x11/i3/ipc/workspace.cpp @@ -43,17 +43,14 @@ void I3Workspace::updateFromObject(const QVariantMap& obj) { auto monitorName = obj.value("output").value(); - auto* monitor = this->bMonitor.value(); - if (!monitor || monitorName != monitor->bindableName().value()) { + if (!this->bMonitor || monitorName != this->bMonitor->bindableName().value()) { if (monitorName.isEmpty()) { - monitor = nullptr; + this->bMonitor = nullptr; } else { - monitor = this->ipc->findMonitorByName(monitorName, true); + this->bMonitor = this->ipc->findMonitorByName(monitorName, true); } } - this->setMonitor(monitor); - Qt::endPropertyUpdateGroup(); } @@ -61,21 +58,4 @@ void I3Workspace::activate() { this->ipc->dispatch(QString("workspace number %1").arg(this->bNumber.value())); } -void I3Workspace::setMonitor(I3Monitor* monitor) { - auto* oldMonitor = this->bMonitor.value(); - if (oldMonitor == monitor) return; - - if (oldMonitor) { - QObject::disconnect(oldMonitor, nullptr, this, nullptr); - } - - if (monitor) { - QObject::connect(monitor, &QObject::destroyed, this, &I3Workspace::onMonitorDestroyed); - } - - this->bMonitor = monitor; -} - -void I3Workspace::onMonitorDestroyed() { this->bMonitor = nullptr; } - } // namespace qs::i3::ipc diff --git a/src/x11/i3/ipc/workspace.hpp b/src/x11/i3/ipc/workspace.hpp index c08e926..f540545 100644 --- a/src/x11/i3/ipc/workspace.hpp +++ b/src/x11/i3/ipc/workspace.hpp @@ -57,13 +57,11 @@ public: [[nodiscard]] QBindable bindableActive() { return &this->bActive; } [[nodiscard]] QBindable bindableFocused() { return &this->bFocused; } [[nodiscard]] QBindable bindableUrgent() { return &this->bUrgent; } - [[nodiscard]] QBindable bindableMonitor() const { return &this->bMonitor; } + [[nodiscard]] QBindable bindableMonitor() { return &this->bMonitor; } [[nodiscard]] QVariantMap lastIpcObject() const; void updateFromObject(const QVariantMap& obj); - void setMonitor(I3Monitor* monitor); - signals: void idChanged(); void nameChanged(); @@ -74,9 +72,6 @@ signals: void monitorChanged(); void lastIpcObjectChanged(); -private slots: - void onMonitorDestroyed(); - private: I3IpcController* ipc;