diff --git a/changelog/next.md b/changelog/next.md index ef63323..0feffe1 100644 --- a/changelog/next.md +++ b/changelog/next.md @@ -50,7 +50,6 @@ set shell id. - Fixed ClippingRectangle related crashes. - Fixed crashes when monitors are unplugged. - Fixed crashes when default pipewire devices are lost. -- Desktop action order is now preserved. ## Packaging Changes diff --git a/default.nix b/default.nix index 02b8659..59e68b0 100644 --- a/default.nix +++ b/default.nix @@ -19,7 +19,6 @@ wayland-protocols, wayland-scanner, xorg, - libxcb ? xorg.libxcb, libdrm, libgbm ? null, vulkan-headers, @@ -89,7 +88,7 @@ ++ lib.optional (withWayland && lib.strings.compareVersions qt6.qtbase.version "6.10.0" == -1) qt6.qtwayland ++ lib.optionals withWayland [ wayland wayland-protocols ] ++ lib.optionals (withWayland && libgbm != null) [ libdrm libgbm vulkan-headers ] - ++ lib.optional withX11 libxcb + ++ lib.optional withX11 xorg.libxcb ++ lib.optional withPam pam ++ lib.optional withPipewire pipewire ++ lib.optionals withPolkit [ polkit glib ]; diff --git a/src/core/desktopentry.cpp b/src/core/desktopentry.cpp index 637f758..2dbafea 100644 --- a/src/core/desktopentry.cpp +++ b/src/core/desktopentry.cpp @@ -107,10 +107,7 @@ ParsedDesktopEntryData DesktopEntry::parseText(const QString& id, const QString& auto groupName = QString(); auto entries = QHash>(); - auto actionOrder = QStringList(); - auto pendingActions = QHash(); - - auto finishCategory = [&data, &groupName, &entries, &actionOrder, &pendingActions]() { + auto finishCategory = [&data, &groupName, &entries]() { if (groupName == "Desktop Entry") { if (entries.value("Type").second != "Application") return; @@ -132,10 +129,9 @@ ParsedDesktopEntryData DesktopEntry::parseText(const QString& id, const QString& else if (key == "Terminal") data.terminal = value == "true"; else if (key == "Categories") data.categories = value.split(u';', Qt::SkipEmptyParts); else if (key == "Keywords") data.keywords = value.split(u';', Qt::SkipEmptyParts); - else if (key == "Actions") actionOrder = value.split(u';', Qt::SkipEmptyParts); } } else if (groupName.startsWith("Desktop Action ")) { - auto actionName = groupName.sliced(15); + auto actionName = groupName.sliced(16); DesktopActionData action; action.id = actionName; @@ -151,7 +147,7 @@ ParsedDesktopEntryData DesktopEntry::parseText(const QString& id, const QString& } } - pendingActions.insert(actionName, action); + data.actions.insert(actionName, action); } entries.clear(); @@ -197,13 +193,6 @@ ParsedDesktopEntryData DesktopEntry::parseText(const QString& id, const QString& } finishCategory(); - - for (const auto& actionId: actionOrder) { - if (pendingActions.contains(actionId)) { - data.actions.append(pendingActions.value(actionId)); - } - } - return data; } @@ -227,18 +216,17 @@ void DesktopEntry::updateState(const ParsedDesktopEntryData& newState) { this->updateActions(newState.actions); } -void DesktopEntry::updateActions(const QVector& newActions) { +void DesktopEntry::updateActions(const QHash& newActions) { auto old = this->mActions; - this->mActions.clear(); - for (const auto& d: newActions) { + for (const auto& [key, d]: newActions.asKeyValueRange()) { DesktopAction* act = nullptr; - auto found = std::ranges::find(old, d.id, &DesktopAction::mId); - if (found != old.end()) { - act = *found; + if (auto found = old.find(key); found != old.end()) { + act = found.value(); old.erase(found); } else { act = new DesktopAction(d.id, this); + this->mActions.insert(key, act); } Qt::beginPropertyUpdateGroup(); @@ -249,7 +237,6 @@ void DesktopEntry::updateActions(const QVector& newActions) { Qt::endPropertyUpdateGroup(); act->mEntries = d.entries; - this->mActions.append(act); } for (auto* leftover: old) { @@ -263,7 +250,7 @@ void DesktopEntry::execute() const { bool DesktopEntry::isValid() const { return !this->bName.value().isEmpty(); } -QVector DesktopEntry::actions() const { return this->mActions; } +QVector DesktopEntry::actions() const { return this->mActions.values(); } QVector DesktopEntry::parseExecString(const QString& execString) { QVector arguments; diff --git a/src/core/desktopentry.hpp b/src/core/desktopentry.hpp index 0d1eff2..623019d 100644 --- a/src/core/desktopentry.hpp +++ b/src/core/desktopentry.hpp @@ -43,7 +43,7 @@ struct ParsedDesktopEntryData { QVector categories; QVector keywords; QHash entries; - QVector actions; + QHash actions; }; /// A desktop entry. See @@DesktopEntries for details. @@ -164,10 +164,10 @@ public: // clang-format on private: - void updateActions(const QVector& newActions); + void updateActions(const QHash& newActions); ParsedDesktopEntryData state; - QVector mActions; + QHash mActions; friend class DesktopAction; }; diff --git a/src/services/pipewire/core.cpp b/src/services/pipewire/core.cpp index 5077abe..e40bc54 100644 --- a/src/services/pipewire/core.cpp +++ b/src/services/pipewire/core.cpp @@ -143,17 +143,12 @@ void PwCore::onSync(void* data, quint32 id, qint32 seq) { void PwCore::onError(void* data, quint32 id, qint32 /*seq*/, qint32 res, const char* message) { auto* self = static_cast(data); - // Pipewire's documentation describes the error event as being fatal, however it isn't. - // We're not sure what causes these ENOENTs on device removal, presumably something in - // the teardown sequence, but they're harmless. Attempting to handle them as a fatal - // error causes unnecessary triggers for shells. - if (res == -ENOENT) { - qCDebug(logLoop) << "Pipewire ENOENT on object" << id << "with code" << res << message; - return; + if (message != nullptr) { + qCWarning(logLoop) << "Fatal pipewire error on object" << id << "with code" << res << message; + } else { + qCWarning(logLoop) << "Fatal pipewire error on object" << id << "with code" << res; } - qCWarning(logLoop) << "Pipewire error on object" << id << "with code" << res << message; - emit self->fatalError(); }