From 28bf94904f3e67c5f84410b68c6a6bab89bd66ce Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Sun, 16 Nov 2025 21:59:42 +0100 Subject: [PATCH] wbar: unpin and stuff i realized i mixed up pinning and unpinning, but whatever --- .../modules/common/widgets/PopupToolTip.qml | 4 + .../ii/modules/waffle/bar/BarIconButton.qml | 1 + .../ii/modules/waffle/bar/tray/Tray.qml | 38 ++++-- .../ii/modules/waffle/bar/tray/TrayButton.qml | 9 +- .../waffle/bar/tray/TrayOverflowMenu.qml | 121 +++++++++++++----- .../ii/modules/waffle/looks/WPopupToolTip.qml | 18 ++- 6 files changed, 141 insertions(+), 50 deletions(-) diff --git a/dots/.config/quickshell/ii/modules/common/widgets/PopupToolTip.qml b/dots/.config/quickshell/ii/modules/common/widgets/PopupToolTip.qml index bc72ee416..afc9957a4 100644 --- a/dots/.config/quickshell/ii/modules/common/widgets/PopupToolTip.qml +++ b/dots/.config/quickshell/ii/modules/common/widgets/PopupToolTip.qml @@ -14,6 +14,10 @@ Item { property real horizontalPadding: 10 property real verticalPadding: 5 + function updateAnchor() { + tooltipLoader.item?.anchor.updateAnchor(); + } + readonly property bool internalVisibleCondition: (extraVisibleCondition && (parent.hovered === undefined || parent?.hovered)) || alternativeVisibleCondition property var anchorEdges: Edges.Top property var anchorGravity: anchorEdges diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/BarIconButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/BarIconButton.qml index 5b4b327b6..311e5e4c9 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/BarIconButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/BarIconButton.qml @@ -14,6 +14,7 @@ BarButton { property alias iconSize: iconContent.implicitSize property alias iconRotation: iconContent.rotation property alias iconMonochrome: iconContent.monochrome + property alias iconScale: iconContent.scale property alias tooltipText: tooltip.text property alias overlayingItems: iconContent.data 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 a98d9b786..f05f2593e 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/tray/Tray.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/tray/Tray.qml @@ -13,6 +13,7 @@ RowLayout { id: root property bool overflowOpen: false + property bool dragging: false Layout.fillHeight: true spacing: 0 @@ -20,7 +21,7 @@ RowLayout { BarIconButton { id: overflowButton - visible: TrayService.unpinnedItems.length > 0 + visible: (TrayService.unpinnedItems.length > 0 || root.dragging) checked: root.overflowOpen iconName: "chevron-down" @@ -29,11 +30,11 @@ RowLayout { Behavior on iconRotation { animation: Looks.transition.rotate.createObject(this) } - + onClicked: { root.overflowOpen = !root.overflowOpen; } - + TrayOverflowMenu { id: trayOverflowLayout Synchronizer on active { @@ -64,27 +65,25 @@ RowLayout { 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 + drag.threshold: 2 - onPressed: (event) => { + onPressed: event => { + trayButton.Drag.hotSpot.x = event.x; trayButton.initialX = trayButton.x; - trayButton.initialY = trayButton.y; + root.dragging = true; trayButton.Drag.active = true; } + onPositionChanged: { + pinTooltip.updateAnchor(); + } onReleased: { if (!dragArea.drag.active) { trayButton.click(); @@ -96,9 +95,22 @@ RowLayout { pinDropArea.willPin = false; } else { trayButton.x = trayButton.initialX; - trayButton.y = trayButton.initialY; } } + trayButton.Drag.active = false; + root.dragging = false; + } + } + + BarToolTip { + id: pinTooltip + extraVisibleCondition: trayButton.Drag.active && pinDropArea.containsDrag && pinDropArea.willPin + realContentHorizontalPadding: 6 + realContentVerticalPadding: 6 + realContentItem: FluentIcon { + anchors.centerIn: parent + icon: "pin-off" + implicitSize: 18 } } } diff --git a/dots/.config/quickshell/ii/modules/waffle/bar/tray/TrayButton.qml b/dots/.config/quickshell/ii/modules/waffle/bar/tray/TrayButton.qml index f7fa7bb1f..e3c85e290 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/tray/TrayButton.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/tray/TrayButton.qml @@ -16,6 +16,13 @@ BarIconButton { property alias menuOpen: menu.visible readonly property bool barAtBottom: Config.options.waffles.bar.bottom iconSource: item.icon + iconScale: 0 + Component.onCompleted: { + root.iconScale = 1 + } + Behavior on iconScale { + animation: Looks.transition.enter.createObject(this) + } onClicked: { item.activate(); @@ -39,7 +46,7 @@ BarIconButton { } BarToolTip { - extraVisibleCondition: root.shouldShowTooltip + extraVisibleCondition: root.shouldShowTooltip && !root.Drag.active text: TrayService.getTooltipForItem(root.item) } } 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 3c7f5f466..f4d5d96d8 100644 --- a/dots/.config/quickshell/ii/modules/waffle/bar/tray/TrayOverflowMenu.qml +++ b/dots/.config/quickshell/ii/modules/waffle/bar/tray/TrayOverflowMenu.qml @@ -1,3 +1,4 @@ +pragma ComponentBehavior: Bound import QtQuick import QtQuick.Controls import QtQuick.Layouts @@ -15,46 +16,108 @@ BarPopup { closeOnFocusLost: false onFocusCleared: { const hasMenuOpen = contentItem.children.some(c => (c.menuOpen)); - if (!hasMenuOpen) root.close(); - else root.grabFocus(); + if (!hasMenuOpen) + root.close(); + else + root.grabFocus(); } - contentItem: GridLayout { + contentItem: Item { id: contentItem anchors.centerIn: parent - rows: Math.floor(Math.sqrt(TrayService.unpinnedItems.length)) - columns: Math.ceil(TrayService.unpinnedItems.length / rows) - columnSpacing: 0 - rowSpacing: 0 + implicitWidth: contentGrid.implicitWidth + implicitHeight: contentGrid.implicitHeight + GridLayout { + id: contentGrid + anchors.centerIn: parent + rows: Math.floor(Math.sqrt(TrayService.unpinnedItems.length)) + columns: Math.ceil(TrayService.unpinnedItems.length / rows) + columnSpacing: 0 + rowSpacing: 0 - Repeater { - model: ScriptModel { - values: TrayService.unpinnedItems - } - delegate: TrayButton { - required property var modelData - item: modelData + Repeater { + model: ScriptModel { + values: TrayService.unpinnedItems + onValuesChanged: { + if (values.length === 0) { + root.close(); + } + } + } + delegate: TrayButton { + id: trayButton + required property var modelData + item: modelData - topInset: 0 - bottomInset: 0 - implicitWidth: 40 - implicitHeight: 40 + topInset: 0 + bottomInset: 0 + implicitWidth: 40 + implicitHeight: 40 - colBackground: ColorUtils.transparentize(Looks.colors.bg2) - colBackgroundHover: Looks.colors.bg2Hover - colBackgroundActive: Looks.colors.bg2Active + colBackground: ColorUtils.transparentize(Looks.colors.bg2) + colBackgroundHover: Looks.colors.bg2Hover + colBackgroundActive: Looks.colors.bg2Active - onMenuOpenChanged: { - // The overflow menu should only be closed when the user clicks outside - // However the focus grab refuses to reactivate, so we can't have that - // But most of the time the user dismisses the menu by clicking outside anyway, - // so this is acceptable. - if (!menuOpen) { - root.close(); + onMenuOpenChanged: { + // The overflow menu should only be closed when the user clicks outside + // However the focus grab refuses to reactivate, so we can't have that + // But most of the time the user dismisses the menu by clicking outside anyway, + // so this is acceptable. + if (!menuOpen) { + root.close(); + } + } + + property real initialX + property real initialY + + Behavior on x { + animation: Looks.transition.move.createObject(this) + } + Behavior on y { + animation: Looks.transition.move.createObject(this) + } + + MouseArea { + id: dragArea + anchors.fill: parent + drag.target: parent + drag.threshold: 2 + + onPressed: event => { + trayButton.Drag.hotSpot.x = event.x; + trayButton.Drag.hotSpot.y = event.y; + trayButton.initialX = trayButton.x; + trayButton.initialY = trayButton.y; + trayButton.Drag.active = true; + } + onReleased: { + if (!dragArea.drag.active) { + trayButton.click(); + } else { + if (!unpinDropArea.containsDrag && unpinDropArea.willUnpin) { + // 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); + unpinDropArea.willUnpin = false; + } else { + trayButton.x = trayButton.initialX; + trayButton.y = trayButton.initialY; + } + } + trayButton.Drag.active = false; + } } } } } + + DropArea { + id: unpinDropArea + anchors.fill: parent + property bool willUnpin: false + onEntered: willUnpin = false + onExited: willUnpin = true + } } } - diff --git a/dots/.config/quickshell/ii/modules/waffle/looks/WPopupToolTip.qml b/dots/.config/quickshell/ii/modules/waffle/looks/WPopupToolTip.qml index 6b89d4f24..ff633dec0 100644 --- a/dots/.config/quickshell/ii/modules/waffle/looks/WPopupToolTip.qml +++ b/dots/.config/quickshell/ii/modules/waffle/looks/WPopupToolTip.qml @@ -10,9 +10,17 @@ import qs.modules.waffle.looks PopupToolTip { id: root + property Item realContentItem + realContentItem: WText { + text: root.text + anchors.centerIn: parent + } + property real visualMargin: 11 verticalPadding: visualMargin horizontalPadding: visualMargin + property real realContentVerticalPadding: 8 + property real realContentHorizontalPadding: 10 contentItem: Item { anchors.centerIn: parent @@ -36,16 +44,12 @@ PopupToolTip { id: realContent z: 1 anchors.centerIn: parent - implicitWidth: tooltipText.implicitWidth + 10 * 2 - implicitHeight: tooltipText.implicitHeight + 8 * 2 + implicitWidth: root.realContentItem.implicitWidth + root.realContentHorizontalPadding * 2 + implicitHeight: root.realContentItem.implicitHeight + root.realContentVerticalPadding * 2 color: Looks.colors.bg1 radius: Looks.radius.medium - WText { - id: tooltipText - text: root.text - anchors.centerIn: parent - } + children: [root.realContentItem] } } }