Compare commits

..

No commits in common. "6bcd3d9bbf81efdd8620409b268b90310bc1374c" and "a849a88893c71d409aecef0b999e6cc3d9b50034" have entirely different histories.

5 changed files with 17 additions and 37 deletions

View file

@ -50,7 +50,6 @@ set shell id.
- Fixed ClippingRectangle related crashes. - Fixed ClippingRectangle related crashes.
- Fixed crashes when monitors are unplugged. - Fixed crashes when monitors are unplugged.
- Fixed crashes when default pipewire devices are lost. - Fixed crashes when default pipewire devices are lost.
- Desktop action order is now preserved.
## Packaging Changes ## Packaging Changes

View file

@ -19,7 +19,6 @@
wayland-protocols, wayland-protocols,
wayland-scanner, wayland-scanner,
xorg, xorg,
libxcb ? xorg.libxcb,
libdrm, libdrm,
libgbm ? null, libgbm ? null,
vulkan-headers, vulkan-headers,
@ -89,7 +88,7 @@
++ lib.optional (withWayland && lib.strings.compareVersions qt6.qtbase.version "6.10.0" == -1) qt6.qtwayland ++ lib.optional (withWayland && lib.strings.compareVersions qt6.qtbase.version "6.10.0" == -1) qt6.qtwayland
++ lib.optionals withWayland [ wayland wayland-protocols ] ++ lib.optionals withWayland [ wayland wayland-protocols ]
++ lib.optionals (withWayland && libgbm != null) [ libdrm libgbm vulkan-headers ] ++ lib.optionals (withWayland && libgbm != null) [ libdrm libgbm vulkan-headers ]
++ lib.optional withX11 libxcb ++ lib.optional withX11 xorg.libxcb
++ lib.optional withPam pam ++ lib.optional withPam pam
++ lib.optional withPipewire pipewire ++ lib.optional withPipewire pipewire
++ lib.optionals withPolkit [ polkit glib ]; ++ lib.optionals withPolkit [ polkit glib ];

View file

@ -107,10 +107,7 @@ ParsedDesktopEntryData DesktopEntry::parseText(const QString& id, const QString&
auto groupName = QString(); auto groupName = QString();
auto entries = QHash<QString, QPair<Locale, QString>>(); auto entries = QHash<QString, QPair<Locale, QString>>();
auto actionOrder = QStringList(); auto finishCategory = [&data, &groupName, &entries]() {
auto pendingActions = QHash<QString, DesktopActionData>();
auto finishCategory = [&data, &groupName, &entries, &actionOrder, &pendingActions]() {
if (groupName == "Desktop Entry") { if (groupName == "Desktop Entry") {
if (entries.value("Type").second != "Application") return; 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 == "Terminal") data.terminal = value == "true";
else if (key == "Categories") data.categories = value.split(u';', Qt::SkipEmptyParts); 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 == "Keywords") data.keywords = value.split(u';', Qt::SkipEmptyParts);
else if (key == "Actions") actionOrder = value.split(u';', Qt::SkipEmptyParts);
} }
} else if (groupName.startsWith("Desktop Action ")) { } else if (groupName.startsWith("Desktop Action ")) {
auto actionName = groupName.sliced(15); auto actionName = groupName.sliced(16);
DesktopActionData action; DesktopActionData action;
action.id = actionName; 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(); entries.clear();
@ -197,13 +193,6 @@ ParsedDesktopEntryData DesktopEntry::parseText(const QString& id, const QString&
} }
finishCategory(); finishCategory();
for (const auto& actionId: actionOrder) {
if (pendingActions.contains(actionId)) {
data.actions.append(pendingActions.value(actionId));
}
}
return data; return data;
} }
@ -227,18 +216,17 @@ void DesktopEntry::updateState(const ParsedDesktopEntryData& newState) {
this->updateActions(newState.actions); this->updateActions(newState.actions);
} }
void DesktopEntry::updateActions(const QVector<DesktopActionData>& newActions) { void DesktopEntry::updateActions(const QHash<QString, DesktopActionData>& newActions) {
auto old = this->mActions; auto old = this->mActions;
this->mActions.clear();
for (const auto& d: newActions) { for (const auto& [key, d]: newActions.asKeyValueRange()) {
DesktopAction* act = nullptr; DesktopAction* act = nullptr;
auto found = std::ranges::find(old, d.id, &DesktopAction::mId); if (auto found = old.find(key); found != old.end()) {
if (found != old.end()) { act = found.value();
act = *found;
old.erase(found); old.erase(found);
} else { } else {
act = new DesktopAction(d.id, this); act = new DesktopAction(d.id, this);
this->mActions.insert(key, act);
} }
Qt::beginPropertyUpdateGroup(); Qt::beginPropertyUpdateGroup();
@ -249,7 +237,6 @@ void DesktopEntry::updateActions(const QVector<DesktopActionData>& newActions) {
Qt::endPropertyUpdateGroup(); Qt::endPropertyUpdateGroup();
act->mEntries = d.entries; act->mEntries = d.entries;
this->mActions.append(act);
} }
for (auto* leftover: old) { for (auto* leftover: old) {
@ -263,7 +250,7 @@ void DesktopEntry::execute() const {
bool DesktopEntry::isValid() const { return !this->bName.value().isEmpty(); } bool DesktopEntry::isValid() const { return !this->bName.value().isEmpty(); }
QVector<DesktopAction*> DesktopEntry::actions() const { return this->mActions; } QVector<DesktopAction*> DesktopEntry::actions() const { return this->mActions.values(); }
QVector<QString> DesktopEntry::parseExecString(const QString& execString) { QVector<QString> DesktopEntry::parseExecString(const QString& execString) {
QVector<QString> arguments; QVector<QString> arguments;

View file

@ -43,7 +43,7 @@ struct ParsedDesktopEntryData {
QVector<QString> categories; QVector<QString> categories;
QVector<QString> keywords; QVector<QString> keywords;
QHash<QString, QString> entries; QHash<QString, QString> entries;
QVector<DesktopActionData> actions; QHash<QString, DesktopActionData> actions;
}; };
/// A desktop entry. See @@DesktopEntries for details. /// A desktop entry. See @@DesktopEntries for details.
@ -164,10 +164,10 @@ public:
// clang-format on // clang-format on
private: private:
void updateActions(const QVector<DesktopActionData>& newActions); void updateActions(const QHash<QString, DesktopActionData>& newActions);
ParsedDesktopEntryData state; ParsedDesktopEntryData state;
QVector<DesktopAction*> mActions; QHash<QString, DesktopAction*> mActions;
friend class DesktopAction; friend class DesktopAction;
}; };

View file

@ -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) { void PwCore::onError(void* data, quint32 id, qint32 /*seq*/, qint32 res, const char* message) {
auto* self = static_cast<PwCore*>(data); auto* self = static_cast<PwCore*>(data);
// Pipewire's documentation describes the error event as being fatal, however it isn't. if (message != nullptr) {
// We're not sure what causes these ENOENTs on device removal, presumably something in qCWarning(logLoop) << "Fatal pipewire error on object" << id << "with code" << res << message;
// the teardown sequence, but they're harmless. Attempting to handle them as a fatal } else {
// error causes unnecessary triggers for shells. qCWarning(logLoop) << "Fatal pipewire error on object" << id << "with code" << res;
if (res == -ENOENT) {
qCDebug(logLoop) << "Pipewire ENOENT on object" << id << "with code" << res << message;
return;
} }
qCWarning(logLoop) << "Pipewire error on object" << id << "with code" << res << message;
emit self->fatalError(); emit self->fatalError();
} }