diff --git a/shell/plugins/bar/widgets/Tray.qml b/shell/plugins/bar/widgets/Tray.qml index 16e94624..adcc0d1d 100644 --- a/shell/plugins/bar/widgets/Tray.qml +++ b/shell/plugins/bar/widgets/Tray.qml @@ -4,6 +4,7 @@ import Quickshell.Services.SystemTray import Quickshell.Widgets import qs.Commons import qs.Ui +import "TrayModel.js" as TrayModel BarWidget { id: root @@ -70,12 +71,18 @@ BarWidget { return "drawer" } + function ownedByDedicatedWidget(item) { + var layout = root.bar && root.bar.layoutConfig ? root.bar.layoutConfig : null + return TrayModel.ownedByDedicatedWidget(item, layout) + } + function bucket(category) { var values = SystemTray.items.values var result = [] for (var i = 0; i < values.length; i++) { var item = values[i] if (item.status === Status.Passive) continue + if (ownedByDedicatedWidget(item)) continue if (category === "all") { result.push(item) continue diff --git a/shell/plugins/bar/widgets/TrayModel.js b/shell/plugins/bar/widgets/TrayModel.js new file mode 100644 index 00000000..a9da13c4 --- /dev/null +++ b/shell/plugins/bar/widgets/TrayModel.js @@ -0,0 +1,44 @@ +function text(value) { + return String(value || "").toLowerCase() +} + +function isDropboxTrayItem(item) { + if (!item) return false + return text(item.id).indexOf("dropbox") !== -1 + || text(item.title).indexOf("dropbox") !== -1 + || text(item.tooltipTitle).indexOf("dropbox") !== -1 +} + +function entryId(entry) { + if (typeof entry === "string") return entry + if (entry && typeof entry === "object") { + var id = entry.id + if (id !== undefined && id !== null && String(id) !== "") return String(id) + } + return "" +} + +function layoutHasWidget(layout, id) { + var sections = ["left", "center", "right"] + for (var s = 0; s < sections.length; s++) { + var entries = layout && layout[sections[s]] + if (!Array.isArray(entries)) continue + for (var i = 0; i < entries.length; i++) { + if (entryId(entries[i]) === id) return true + } + } + return false +} + +function ownedByDedicatedWidget(item, layout) { + return layoutHasWidget(layout, "omarchy.dropbox") && isDropboxTrayItem(item) +} + +if (typeof module !== "undefined") { + module.exports = { + isDropboxTrayItem: isDropboxTrayItem, + entryId: entryId, + layoutHasWidget: layoutHasWidget, + ownedByDedicatedWidget: ownedByDedicatedWidget + } +} diff --git a/test/shell.d/tray-test.sh b/test/shell.d/tray-test.sh new file mode 100644 index 00000000..d2b2a25e --- /dev/null +++ b/test/shell.d/tray-test.sh @@ -0,0 +1,24 @@ +#!/bin/bash + +set -euo pipefail + +source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh" + +run_node_test "tray model helpers" <<'JS' +const tray = requireFromRoot('shell/plugins/bar/widgets/TrayModel.js') + +assert(tray.isDropboxTrayItem({ id: 'dropbox-client' }), 'tray detects dropbox item ids') +assert(tray.isDropboxTrayItem({ title: 'Dropbox' }), 'tray detects dropbox item titles') +assert(!tray.isDropboxTrayItem({ id: 'nextcloud' }), 'tray ignores non-dropbox items') + +const layout = { + left: [{ id: 'omarchy.menu' }], + center: [], + right: [{ id: 'omarchy.dropbox' }, { id: 'omarchy.tray' }] +} + +assert(tray.layoutHasWidget(layout, 'omarchy.dropbox'), 'tray finds dedicated dropbox widget in layout') +assert(tray.ownedByDedicatedWidget({ id: 'dropbox' }, layout), 'tray suppresses dropbox when dedicated widget is in bar') +assert(!tray.ownedByDedicatedWidget({ id: 'dropbox' }, { left: [], center: [], right: [] }), 'tray keeps dropbox when dedicated widget is absent') +assert(!tray.ownedByDedicatedWidget({ id: 'nextcloud' }, layout), 'tray keeps unrelated tray items') +JS