From c03030019100718d473ae86c89656e98124f5b3a Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Fri, 6 Mar 2026 01:39:24 -0800 Subject: [PATCH] core/desktopentry: preserve desktop action order --- changelog/next.md | 1 + src/core/desktopentry.cpp | 31 ++++++++++++++++++++++--------- src/core/desktopentry.hpp | 6 +++--- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/changelog/next.md b/changelog/next.md index 0feffe1..ef63323 100644 --- a/changelog/next.md +++ b/changelog/next.md @@ -50,6 +50,7 @@ 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/src/core/desktopentry.cpp b/src/core/desktopentry.cpp index 2dbafea..637f758 100644 --- a/src/core/desktopentry.cpp +++ b/src/core/desktopentry.cpp @@ -107,7 +107,10 @@ ParsedDesktopEntryData DesktopEntry::parseText(const QString& id, const QString& auto groupName = QString(); auto entries = QHash>(); - auto finishCategory = [&data, &groupName, &entries]() { + auto actionOrder = QStringList(); + auto pendingActions = QHash(); + + auto finishCategory = [&data, &groupName, &entries, &actionOrder, &pendingActions]() { if (groupName == "Desktop Entry") { if (entries.value("Type").second != "Application") return; @@ -129,9 +132,10 @@ 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(16); + auto actionName = groupName.sliced(15); DesktopActionData action; action.id = actionName; @@ -147,7 +151,7 @@ ParsedDesktopEntryData DesktopEntry::parseText(const QString& id, const QString& } } - data.actions.insert(actionName, action); + pendingActions.insert(actionName, action); } entries.clear(); @@ -193,6 +197,13 @@ 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; } @@ -216,17 +227,18 @@ void DesktopEntry::updateState(const ParsedDesktopEntryData& newState) { this->updateActions(newState.actions); } -void DesktopEntry::updateActions(const QHash& newActions) { +void DesktopEntry::updateActions(const QVector& newActions) { auto old = this->mActions; + this->mActions.clear(); - for (const auto& [key, d]: newActions.asKeyValueRange()) { + for (const auto& d: newActions) { DesktopAction* act = nullptr; - if (auto found = old.find(key); found != old.end()) { - act = found.value(); + auto found = std::ranges::find(old, d.id, &DesktopAction::mId); + if (found != old.end()) { + act = *found; old.erase(found); } else { act = new DesktopAction(d.id, this); - this->mActions.insert(key, act); } Qt::beginPropertyUpdateGroup(); @@ -237,6 +249,7 @@ void DesktopEntry::updateActions(const QHash& newAct Qt::endPropertyUpdateGroup(); act->mEntries = d.entries; + this->mActions.append(act); } for (auto* leftover: old) { @@ -250,7 +263,7 @@ void DesktopEntry::execute() const { bool DesktopEntry::isValid() const { return !this->bName.value().isEmpty(); } -QVector DesktopEntry::actions() const { return this->mActions.values(); } +QVector DesktopEntry::actions() const { return this->mActions; } QVector DesktopEntry::parseExecString(const QString& execString) { QVector arguments; diff --git a/src/core/desktopentry.hpp b/src/core/desktopentry.hpp index 623019d..0d1eff2 100644 --- a/src/core/desktopentry.hpp +++ b/src/core/desktopentry.hpp @@ -43,7 +43,7 @@ struct ParsedDesktopEntryData { QVector categories; QVector keywords; QHash entries; - QHash actions; + QVector actions; }; /// A desktop entry. See @@DesktopEntries for details. @@ -164,10 +164,10 @@ public: // clang-format on private: - void updateActions(const QHash& newActions); + void updateActions(const QVector& newActions); ParsedDesktopEntryData state; - QHash mActions; + QVector mActions; friend class DesktopAction; };