diff --git a/dots/.config/quickshell/ii/modules/common/Config.qml b/dots/.config/quickshell/ii/modules/common/Config.qml index c71b77cc9..ec47c514b 100644 --- a/dots/.config/quickshell/ii/modules/common/Config.qml +++ b/dots/.config/quickshell/ii/modules/common/Config.qml @@ -3,6 +3,7 @@ pragma ComponentBehavior: Bound import QtQuick import Quickshell import Quickshell.Io +import qs.modules.common.functions Singleton { id: root @@ -238,13 +239,6 @@ Singleton { property bool showPerformanceProfileToggle: false property bool showScreenRecord: false } - property JsonObject tray: JsonObject { - property bool monochromeIcons: true - property bool showItemId: false - property bool invertPinnedItems: true // Makes the below a whitelist for the tray and blacklist for the pinned area - property list pinnedItems: [ ] - property bool filterPassive: true - } property JsonObject workspaces: JsonObject { property bool monochromeIcons: true property int shown: 10 @@ -431,6 +425,14 @@ Singleton { property int historyLength: 60 } + property JsonObject tray: JsonObject { + property bool monochromeIcons: true + property bool showItemId: false + property bool invertPinnedItems: true // Makes the below a whitelist for the tray and blacklist for the pinned area + property list pinnedItems: [ "Fcitx" ] + property bool filterPassive: true + } + property JsonObject musicRecognition: JsonObject { property int timeout: 16 property int interval: 4 diff --git a/dots/.config/quickshell/ii/modules/ii/bar/SysTrayItem.qml b/dots/.config/quickshell/ii/modules/ii/bar/SysTrayItem.qml index 40549e6fe..6230de0f8 100644 --- a/dots/.config/quickshell/ii/modules/ii/bar/SysTrayItem.qml +++ b/dots/.config/quickshell/ii/modules/ii/bar/SysTrayItem.qml @@ -63,7 +63,7 @@ MouseArea { IconImage { id: trayIcon - visible: !Config.options.bar.tray.monochromeIcons + visible: !Config.options.tray.monochromeIcons source: root.item.icon anchors.centerIn: parent width: parent.width @@ -71,7 +71,7 @@ MouseArea { } Loader { - active: Config.options.bar.tray.monochromeIcons + active: Config.options.tray.monochromeIcons anchors.fill: trayIcon sourceComponent: Item { Desaturate { diff --git a/dots/.config/quickshell/ii/modules/settings/BarConfig.qml b/dots/.config/quickshell/ii/modules/settings/BarConfig.qml index 06e694bc8..bfe4c256e 100644 --- a/dots/.config/quickshell/ii/modules/settings/BarConfig.qml +++ b/dots/.config/quickshell/ii/modules/settings/BarConfig.qml @@ -148,18 +148,18 @@ ContentPage { ConfigSwitch { buttonIcon: "keep" text: Translation.tr('Make icons pinned by default') - checked: Config.options.bar.tray.invertPinnedItems + checked: Config.options.tray.invertPinnedItems onCheckedChanged: { - Config.options.bar.tray.invertPinnedItems = checked; + Config.options.tray.invertPinnedItems = checked; } } ConfigSwitch { buttonIcon: "colors" text: Translation.tr('Tint icons') - checked: Config.options.bar.tray.monochromeIcons + checked: Config.options.tray.monochromeIcons onCheckedChanged: { - Config.options.bar.tray.monochromeIcons = checked; + Config.options.tray.monochromeIcons = checked; } } } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/tray/Tray.qml b/dots/.config/quickshell/ii/modules/waffle/bar/tray/Tray.qml index b98d7c475..a98d9b786 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/tray/Tray.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/tray/Tray.qml @@ -45,6 +45,14 @@ RowLayout { extraVisibleCondition: overflowButton.shouldShowTooltip text: qsTr("Show hidden icons") } + + DropArea { + id: pinDropArea + anchors.fill: parent + property bool willPin: false + onEntered: willPin = true + onExited: willPin = false + } } Repeater { @@ -52,8 +60,47 @@ RowLayout { values: TrayService.pinnedItems } delegate: TrayButton { + id: trayButton required property var modelData item: modelData + + Drag.active: dragArea.drag.active + Drag.hotSpot.x: width / 2 + Drag.hotSpot.y: height / 2 + property real initialX + property real initialY + + Behavior on x { + animation: Looks.transition.move.createObject(this) + } + + MouseArea { + id: dragArea + anchors.fill: parent + drag.target: parent + drag.axis: Drag.XAxis + + onPressed: (event) => { + trayButton.initialX = trayButton.x; + trayButton.initialY = trayButton.y; + trayButton.Drag.active = true; + } + onReleased: { + if (!dragArea.drag.active) { + trayButton.click(); + } else { + if (pinDropArea.containsDrag && pinDropArea.willPin) { + // Quickshell would crash if we don't hide this item first. Took me fucking 3 hours to figure out... + trayButton.visible = false; + TrayService.togglePin(trayButton.item.id); + pinDropArea.willPin = false; + } else { + trayButton.x = trayButton.initialX; + trayButton.y = trayButton.initialY; + } + } + } + } } } } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/tray/TrayOverflowMenu.qml b/dots/.config/quickshell/ii/modules/waffle/bar/tray/TrayOverflowMenu.qml index cc4561b1d..3c7f5f466 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/tray/TrayOverflowMenu.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/tray/TrayOverflowMenu.qml @@ -28,7 +28,9 @@ BarPopup { rowSpacing: 0 Repeater { - model: TrayService.unpinnedItems + model: ScriptModel { + values: TrayService.unpinnedItems + } delegate: TrayButton { required property var modelData item: modelData diff --git a/dots/.config/quickshell/ii/services/TrayService.qml b/dots/.config/quickshell/ii/services/TrayService.qml index f957c46a6..a874c6c11 100644 --- a/dots/.config/quickshell/ii/services/TrayService.qml +++ b/dots/.config/quickshell/ii/services/TrayService.qml @@ -8,11 +8,11 @@ import Quickshell.Services.SystemTray Singleton { id: root - property bool smartTray: Config.options.bar.tray.filterPassive - property list itemsInUserList: SystemTray.items.values.filter(i => (Config.options.bar.tray.pinnedItems.includes(i.id) && (!smartTray || i.status !== Status.Passive))) - property list itemsNotInUserList: SystemTray.items.values.filter(i => (!Config.options.bar.tray.pinnedItems.includes(i.id) && (!smartTray || i.status !== Status.Passive))) + property bool smartTray: Config.options.tray.filterPassive + property list itemsInUserList: SystemTray.items.values.filter(i => (Config.options.tray.pinnedItems.includes(i.id) && (!smartTray || i.status !== Status.Passive))) + property list itemsNotInUserList: SystemTray.items.values.filter(i => (!Config.options.tray.pinnedItems.includes(i.id) && (!smartTray || i.status !== Status.Passive))) - property bool invertPins: Config.options.bar.tray.invertPinnedItems + property bool invertPins: Config.options.tray.invertPinnedItems property list pinnedItems: invertPins ? itemsNotInUserList : itemsInUserList property list unpinnedItems: invertPins ? itemsInUserList : itemsNotInUserList @@ -20,7 +20,26 @@ Singleton { var result = item.tooltipTitle.length > 0 ? item.tooltipTitle : (item.title.length > 0 ? item.title : item.id); if (item.tooltipDescription.length > 0) result += " • " + item.tooltipDescription; - if (Config.options.bar.tray.showItemId) result += "\n[" + item.id + "]"; + if (Config.options.tray.showItemId) result += "\n[" + item.id + "]"; return result; } + + // Pinning + function pin(itemId) { + var pins = Config.options.tray.pinnedItems; + if (pins.includes(itemId)) return; + Config.options.tray.pinnedItems.push(itemId); + } + function unpin(itemId) { + Config.options.tray.pinnedItems = Config.options.tray.pinnedItems.filter(id => id !== itemId); + } + function togglePin(itemId) { + var pins = Config.options.tray.pinnedItems; + if (pins.includes(itemId)) { + unpin(itemId) + } else { + pin(itemId) + } + } + }