diff --git a/dots/.config/quickshell/ii/modules/common/config/HeftyConfig.qml b/dots/.config/quickshell/ii/modules/common/config/HeftyConfig.qml index 5bd70b28f..407726b6b 100644 --- a/dots/.config/quickshell/ii/modules/common/config/HeftyConfig.qml +++ b/dots/.config/quickshell/ii/modules/common/config/HeftyConfig.qml @@ -8,7 +8,7 @@ JsonObject { property list centerLeftWidgets: ["HTime"] property list centerWidgets: ["HWorkspaces"] property list centerRightWidgets: ["HResources"] - property list rightWidgets: ["HSystemIndicators"] + property list rightWidgets: ["HSystemTray", "HSystemIndicators"] property bool m3ExpressiveGrouping: true property JsonObject resources: JsonObject { diff --git a/dots/.config/quickshell/ii/modules/common/widgets/ChoreographerGridLayout.qml b/dots/.config/quickshell/ii/modules/common/widgets/ChoreographerGridLayout.qml index 76daccad4..8063ed353 100644 --- a/dots/.config/quickshell/ii/modules/common/widgets/ChoreographerGridLayout.qml +++ b/dots/.config/quickshell/ii/modules/common/widgets/ChoreographerGridLayout.qml @@ -9,9 +9,10 @@ GridLayout { property real totalDuration: 250 property real interval: totalDuration / count - default property list choreographableChildren + property list choreographableChildren: children.filter(c => { + return c.hasOwnProperty("progress") + }) readonly property int count: choreographableChildren.length - children: choreographableChildren property bool shown: false onShownChanged: { diff --git a/dots/.config/quickshell/ii/modules/hefty/topLayer/bar/HBarWidgetContent.qml b/dots/.config/quickshell/ii/modules/hefty/topLayer/bar/HBarWidgetContent.qml index 10f56ec4d..50359b02c 100644 --- a/dots/.config/quickshell/ii/modules/hefty/topLayer/bar/HBarWidgetContent.qml +++ b/dots/.config/quickshell/ii/modules/hefty/topLayer/bar/HBarWidgetContent.qml @@ -32,6 +32,9 @@ W.ButtonMouseArea { Layout.fillWidth: vertical Layout.fillHeight: !vertical + property alias hover: hoverOverlay.hover + property alias press: hoverOverlay.press + W.StateOverlay { id: hoverOverlay anchors.fill: parent diff --git a/dots/.config/quickshell/ii/modules/hefty/topLayer/bar/widgets/HSystemTray.qml b/dots/.config/quickshell/ii/modules/hefty/topLayer/bar/widgets/HSystemTray.qml new file mode 100644 index 000000000..20f8ea0a1 --- /dev/null +++ b/dots/.config/quickshell/ii/modules/hefty/topLayer/bar/widgets/HSystemTray.qml @@ -0,0 +1,135 @@ +pragma ComponentBehavior: Bound +import QtQuick +import QtQuick.Layouts +import Quickshell +import Quickshell.Wayland +import Quickshell.Hyprland + +import qs.services +import qs.modules.common +import qs.modules.common.widgets +import qs.modules.ii.bar +import ".." + +HBarWidgetWithPopout { + id: root + + property list pinnedItems: TrayService.pinnedItems + property list unpinnedItems: TrayService.unpinnedItems + + popupContentWidth: popupContent.implicitWidth + popupContentHeight: popupContent.implicitHeight + + Layout.maximumWidth: vertical ? -1 : implicitWidth + Layout.maximumHeight: vertical ? implicitHeight : -1 + Layout.fillWidth: true + Layout.fillHeight: true + + HBarWidgetContent { + id: contentRoot + vertical: root.vertical + atBottom: root.atBottom + showPopup: root.showPopup + contentImplicitWidth: trayContent.implicitWidth + contentImplicitHeight: trayContent.implicitHeight + + hoverEnabled: false + parentRadiusToPaddingRatio: 0.9 + + hover: trayContent.moreHovered + press: trayContent.morePressed + + TrayContent { + id: trayContent + anchors.fill: parent + vertical: root.vertical + } + + UnpinnedItemsPopup { + id: popupContent + anchors { + top: parent.top + topMargin: root.popupContentOffsetY + left: parent.left + leftMargin: root.popupContentOffsetX + } + shown: root.showPopup + } + } + + component TrayContent: BoxLayout { + spacing: 4 + property alias moreHovered: moreBtn.containsMouse + property alias morePressed: moreBtn.containsPress + + ButtonMouseArea { + id: moreBtn + visible: TrayService.unpinnedItems.length > 0 + Layout.fillWidth: true + Layout.fillHeight: true + hoverEnabled: true + + implicitWidth: 20 - parent.spacing + implicitHeight: 20 - parent.spacing + + onClicked: root.showPopup = !root.showPopup + + MaterialSymbol { + anchors.centerIn: parent + iconSize: 20 + text: "expand_more" + horizontalAlignment: Text.AlignHCenter + color: root.showPopup ? Appearance.colors.colOnSecondaryContainer : Appearance.colors.colOnLayer2 + rotation: (root.showPopup ? 180 : 0) - (90 * root.vertical) + (180 * root.atBottom) + Behavior on rotation { + animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this) + } + } + } + Repeater { + model: root.pinnedItems + delegate: StyledTrayItem { + Layout.fillWidth: true + Layout.fillHeight: true + required property var modelData + item: modelData + } + } + } + + component UnpinnedItemsPopup: ChoreographerLoader { + sourceComponent: ChoreographerGridLayout { + id: popupRoot + totalDuration: 70 + columns: root.vertical ? 1 : -1 + columnSpacing: 8 + rowSpacing: 8 + + Repeater { + model: root.unpinnedItems + delegate: FlyFadeEnterChoreographable { + id: unpinnedTrayItem + required property var modelData + StyledTrayItem { + item: unpinnedTrayItem.modelData + } + } + } + } + } + + component StyledTrayItem: SysTrayItem { + iconSize: 18 + propagateComposedEvents: false + + property var menuWindow + onMenuClosed: { + if (menuWindow) + GlobalFocusGrab.removeDismissable(menuWindow); + } + onMenuOpened: (qsWindow) => { + menuWindow = qsWindow; + GlobalFocusGrab.addDismissable(qsWindow) + } + } +} diff --git a/dots/.config/quickshell/ii/modules/ii/bar/SysTrayItem.qml b/dots/.config/quickshell/ii/modules/ii/bar/SysTrayItem.qml index 859d04217..f9f7081d9 100644 --- a/dots/.config/quickshell/ii/modules/ii/bar/SysTrayItem.qml +++ b/dots/.config/quickshell/ii/modules/ii/bar/SysTrayItem.qml @@ -9,7 +9,7 @@ import qs.modules.common import qs.modules.common.widgets import qs.modules.common.functions -MouseArea { +ButtonMouseArea { id: root required property SystemTrayItem item property bool targetMenuOpen: false @@ -19,8 +19,10 @@ MouseArea { hoverEnabled: true acceptedButtons: Qt.LeftButton | Qt.RightButton - implicitWidth: 20 - implicitHeight: 20 + property real iconSize: 20 + property real backgroundSize: 26 + implicitWidth: iconSize + implicitHeight: iconSize onPressed: (event) => { switch (event.button) { case Qt.LeftButton: @@ -40,6 +42,16 @@ MouseArea { tooltip.text = TrayService.getTooltipForItem(root.item); } + StateOverlay { + id: hoverOverlay + anchors.centerIn: parent + width: root.backgroundSize + height: root.backgroundSize + radius: root.backgroundSize / 2 + hover: root.containsMouse + press: root.containsPress + } + Loader { id: menu function open() { @@ -73,8 +85,8 @@ MouseArea { visible: !Config.options.tray.monochromeIcons source: root.item.icon anchors.centerIn: parent - width: parent.width - height: parent.height + width: root.iconSize + height: root.iconSize } Loader { diff --git a/dots/.config/quickshell/ii/modules/ii/bar/SysTrayMenu.qml b/dots/.config/quickshell/ii/modules/ii/bar/SysTrayMenu.qml index 03c734b9d..95d4f154f 100644 --- a/dots/.config/quickshell/ii/modules/ii/bar/SysTrayMenu.qml +++ b/dots/.config/quickshell/ii/modules/ii/bar/SysTrayMenu.qml @@ -187,7 +187,10 @@ PopupWindow { Layout.fillWidth: true visible: root.trayItemId !== undefined && root.trayItemId.length > 0 && stackView.depth === 1 - releaseAction: () => TrayService.togglePin(root.trayItemId); + releaseAction: () => { + GlobalFocusGrab.dismiss(); + TrayService.togglePin(root.trayItemId); + } contentItem: RowLayout { anchors {