hefty: bar: add system tray

This commit is contained in:
end-4
2026-03-22 20:54:44 +01:00
parent 12d510e9eb
commit 30583abf36
6 changed files with 163 additions and 9 deletions
@@ -8,7 +8,7 @@ JsonObject {
property list<var> centerLeftWidgets: ["HTime"]
property list<var> centerWidgets: ["HWorkspaces"]
property list<var> centerRightWidgets: ["HResources"]
property list<var> rightWidgets: ["HSystemIndicators"]
property list<var> rightWidgets: ["HSystemTray", "HSystemIndicators"]
property bool m3ExpressiveGrouping: true
property JsonObject resources: JsonObject {
@@ -9,9 +9,10 @@ GridLayout {
property real totalDuration: 250
property real interval: totalDuration / count
default property list<QtObject> choreographableChildren
property list<QtObject> choreographableChildren: children.filter(c => {
return c.hasOwnProperty("progress")
})
readonly property int count: choreographableChildren.length
children: choreographableChildren
property bool shown: false
onShownChanged: {
@@ -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
@@ -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<var> pinnedItems: TrayService.pinnedItems
property list<var> 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)
}
}
}
@@ -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 {
@@ -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 {