From 94176fad836ff1dc609a913883a882e2a881863f Mon Sep 17 00:00:00 2001 From: Runze Date: Sat, 9 Aug 2025 14:02:56 +0800 Subject: [PATCH] feat(bar): unify extraction to StyledPopup and add namespace --- .../ii/modules/bar/BatteryIndicator.qml | 40 +----- .../quickshell/ii/modules/bar/ClockWidget.qml | 130 +++++++----------- .../quickshell/ii/modules/bar/Resource.qml | 94 +++++-------- .../ii/modules/bar/weather/WeatherBar.qml | 37 +---- .../ii/modules/common/widgets/StyledPopup.qml | 57 ++++++++ 5 files changed, 158 insertions(+), 200 deletions(-) create mode 100644 .config/quickshell/ii/modules/common/widgets/StyledPopup.qml diff --git a/.config/quickshell/ii/modules/bar/BatteryIndicator.qml b/.config/quickshell/ii/modules/bar/BatteryIndicator.qml index 6815d6d7e..39388aafe 100644 --- a/.config/quickshell/ii/modules/bar/BatteryIndicator.qml +++ b/.config/quickshell/ii/modules/bar/BatteryIndicator.qml @@ -95,39 +95,13 @@ MouseArea { } } - LazyLoader { - id: popupLoader - active: root.containsMouse - - component: PanelWindow { - id: popupWindow - visible: true - color: "transparent" - exclusiveZone: 0 - - anchors.top: true - anchors.left: true - - implicitWidth: batteryPopup.implicitWidth - implicitHeight: batteryPopup.implicitHeight - - margins { - left: root.mapToGlobal(Qt.point( - (root.width - batteryPopup.implicitWidth) / 2, - 0 - )).x - top: root.mapToGlobal(Qt.point(0, root.height)).y - 30 - } - - mask: Region { - item: batteryPopup - } - - BatteryPopup { - id: batteryPopup - anchors.centerIn: parent - } + StyledPopup { + hoverTarget: root + offsetY: -30 + maskEnabled: true + contentComponent: BatteryPopup { + id: batteryPopup + anchors.centerIn: parent } } - } diff --git a/.config/quickshell/ii/modules/bar/ClockWidget.qml b/.config/quickshell/ii/modules/bar/ClockWidget.qml index ac630ad5e..25e5a5eb5 100644 --- a/.config/quickshell/ii/modules/bar/ClockWidget.qml +++ b/.config/quickshell/ii/modules/bar/ClockWidget.qml @@ -46,99 +46,73 @@ Item { acceptedButtons: Qt.NoButton } - LazyLoader { - id: popupLoader - active: mouseArea.containsMouse + StyledPopup { + hoverTarget: mouseArea + offsetY: -30 + contentComponent: Rectangle { + id: datePopup + readonly property real margin: 12 + implicitWidth: columnLayout.implicitWidth + margin * 2 + implicitHeight: columnLayout.implicitHeight + margin * 2 + color: Appearance.colors.colLayer0 + radius: Appearance.rounding.small + border.width: 1 + border.color: Appearance.colors.colLayer0Border + clip: true - component: PanelWindow { - id: popupWindow - visible: true - implicitWidth: datePopup.implicitWidth - implicitHeight: datePopup.implicitHeight - color: "transparent" - exclusiveZone: 0 + ColumnLayout { + id: columnLayout + anchors.centerIn: parent + spacing: 8 - anchors.top: true - anchors.left: true + // Date + Time row + RowLayout { + spacing: 5 + Layout.fillWidth: true + StyledText { + Layout.fillWidth: true + horizontalAlignment: Text.AlignLeft + color: Appearance.colors.colOnLayer1 + text: `${root.formattedDate} • ${root.formattedTime}` + } + } - margins { - left: root.mapToGlobal(Qt.point( - (root.width - datePopup.implicitWidth) / 2, - 0 - )).x - top: root.mapToGlobal(Qt.point(0, root.height)).y - 30 - } - - mask: Region { - item: datePopup - } - - Rectangle { - id: datePopup - readonly property real margin: 12 - implicitWidth: columnLayout.implicitWidth + margin * 2 - implicitHeight: columnLayout.implicitHeight + margin * 2 - color: Appearance.colors.colLayer0 - radius: Appearance.rounding.small - border.width: 1 - border.color: Appearance.colors.colLayer0Border - clip: true + // Uptime row + RowLayout { + spacing: 5 + Layout.fillWidth: true + MaterialSymbol { text: "timelapse"; color: Appearance.m3colors.m3onSecondaryContainer } + StyledText { text: Translation.tr("Uptime:"); color: Appearance.colors.colOnLayer1 } + StyledText { + Layout.fillWidth: true + horizontalAlignment: Text.AlignRight + color: Appearance.colors.colOnLayer1 + text: root.formattedUptime + } + } + // Upcoming tasks row ColumnLayout { - id: columnLayout - anchors.centerIn: parent - spacing: 8 + spacing: 2 + Layout.fillWidth: true - // Date + Time row RowLayout { spacing: 5 Layout.fillWidth: true - StyledText { - Layout.fillWidth: true - horizontalAlignment: Text.AlignLeft - color: Appearance.colors.colOnLayer1 - text: `${root.formattedDate} • ${root.formattedTime}` - } + MaterialSymbol { text: "checklist"; color: Appearance.m3colors.m3onSecondaryContainer } + StyledText { text: Translation.tr("Upcoming Tasks:"); color: Appearance.colors.colOnLayer1 } } - // Uptime row - RowLayout { - spacing: 5 + StyledText { Layout.fillWidth: true - MaterialSymbol { text: "timelapse"; color: Appearance.m3colors.m3onSecondaryContainer } - StyledText { text: Translation.tr("Uptime:"); color: Appearance.colors.colOnLayer1 } - StyledText { - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - color: Appearance.colors.colOnLayer1 - text: root.formattedUptime - } - } - - // Upcoming tasks row - ColumnLayout { - spacing: 2 - Layout.fillWidth: true - - RowLayout { - spacing: 5 - Layout.fillWidth: true - MaterialSymbol { text: "checklist"; color: Appearance.m3colors.m3onSecondaryContainer } - StyledText { text: Translation.tr("Upcoming Tasks:"); color: Appearance.colors.colOnLayer1 } - } - - StyledText { - Layout.fillWidth: true - topPadding: 5 - horizontalAlignment: Text.AlignLeft - wrapMode: Text.Wrap - color: Appearance.colors.colOnLayer1 - text: root.todosSection - } + topPadding: 5 + horizontalAlignment: Text.AlignLeft + wrapMode: Text.Wrap + color: Appearance.colors.colOnLayer1 + text: root.todosSection } } } - } } diff --git a/.config/quickshell/ii/modules/bar/Resource.qml b/.config/quickshell/ii/modules/bar/Resource.qml index 76aca94a8..031a77ed3 100644 --- a/.config/quickshell/ii/modules/bar/Resource.qml +++ b/.config/quickshell/ii/modules/bar/Resource.qml @@ -68,71 +68,49 @@ Item { enabled: resourceRowLayout.x >= 0 && root.width > 0 && root.visible } - LazyLoader { - id: popupLoader - active: mouseArea.containsMouse + StyledPopup { + hoverTarget: mouseArea + offsetY: -30 + contentComponent: Rectangle { + id: resourcePopup + readonly property real margin: 10 + implicitWidth: columnLayout.implicitWidth + margin * 2 + implicitHeight: columnLayout.implicitHeight + margin * 2 + color: Appearance.colors.colLayer0 + radius: Appearance.rounding.small + border.width: 1 + border.color: Appearance.colors.colLayer0Border + clip: true - component: PanelWindow { - id: popupWindow - visible: true + ColumnLayout { + id: columnLayout + anchors.centerIn: parent + spacing: 6 - color: "transparent" - exclusiveZone: 0 - anchors.top: true - anchors.left: true + Repeater { + model: root.tooltipData + delegate: RowLayout { + spacing: 5 + Layout.fillWidth: true - implicitWidth: resourcePopup.implicitWidth - implicitHeight: resourcePopup.implicitHeight - - margins { - left: root.mapToGlobal(Qt.point( - (root.width - resourcePopup.implicitWidth) / 2, - 0 - )).x - top: root.mapToGlobal(Qt.point(0, root.height)).y - 30 - } - - - Rectangle { - id: resourcePopup - readonly property real margin: 10 - implicitWidth: columnLayout.implicitWidth + margin * 2 - implicitHeight: columnLayout.implicitHeight + margin * 2 - color: Appearance.colors.colLayer0 - radius: Appearance.rounding.small - border.width: 1 - border.color: Appearance.colors.colLayer0Border - clip: true - - ColumnLayout { - id: columnLayout - anchors.centerIn: parent - spacing: 6 - - Repeater { - model: root.tooltipData - delegate: RowLayout { - spacing: 5 + MaterialSymbol { + text: modelData.icon + color: Appearance.m3colors.m3onSecondaryContainer + } + StyledText { + text: modelData.label + color: Appearance.colors.colOnLayer1 + } + StyledText { Layout.fillWidth: true - - MaterialSymbol { - text: modelData.icon - color: Appearance.m3colors.m3onSecondaryContainer - } - StyledText { - text: modelData.label - color: Appearance.colors.colOnLayer1 - } - StyledText { - Layout.fillWidth: true - horizontalAlignment: Text.AlignRight - visible: modelData.value !== "" - color: Appearance.colors.colOnLayer1 - text: modelData.value - } + horizontalAlignment: Text.AlignRight + visible: modelData.value !== "" + color: Appearance.colors.colOnLayer1 + text: modelData.value } } } + } } } diff --git a/.config/quickshell/ii/modules/bar/weather/WeatherBar.qml b/.config/quickshell/ii/modules/bar/weather/WeatherBar.qml index d3ca95a7a..b547ad0ea 100644 --- a/.config/quickshell/ii/modules/bar/weather/WeatherBar.qml +++ b/.config/quickshell/ii/modules/bar/weather/WeatherBar.qml @@ -36,37 +36,12 @@ MouseArea { } } - LazyLoader { - id: popupLoader - active: root.containsMouse - - component: PanelWindow { - id: popupWindow - visible: true - implicitWidth: weatherPopup.implicitWidth - implicitHeight: weatherPopup.implicitHeight - - color: "transparent" - exclusiveZone: 0 - - anchors.top: true - anchors.left: true - - margins { - left: root.mapToGlobal(Qt.point( - (root.width - weatherPopup.implicitWidth) / 2, - 0 - )).x - top: root.mapToGlobal(Qt.point(0, root.height)).y - 25 - } - - mask: Region { - item: weatherPopup - } - - WeatherPopup { - id: weatherPopup - } + StyledPopup { + hoverTarget: root + offsetY: -25 + contentComponent: WeatherPopup { + id: weatherPopup + anchors.centerIn: parent } } } diff --git a/.config/quickshell/ii/modules/common/widgets/StyledPopup.qml b/.config/quickshell/ii/modules/common/widgets/StyledPopup.qml new file mode 100644 index 000000000..69b664c0b --- /dev/null +++ b/.config/quickshell/ii/modules/common/widgets/StyledPopup.qml @@ -0,0 +1,57 @@ +import qs +import qs.modules.common +import qs.modules.common.widgets +import qs.services +import QtQuick +import QtQuick.Layouts +import Quickshell +import Quickshell.Wayland + +LazyLoader { + id: root + + property Item hoverTarget + property real offsetY: -30 + property bool maskEnabled: true + property Component contentComponent + + active: hoverTarget && hoverTarget.containsMouse + + component: PanelWindow { + id: popupWindow + visible: true + color: "transparent" + exclusiveZone: 0 + anchors.top: true + anchors.left: true + + implicitWidth: popupContent.implicitWidth + implicitHeight: popupContent.implicitHeight + + margins { + left: hoverTarget + ? hoverTarget.mapToGlobal(Qt.point( + (hoverTarget.width - popupContent.implicitWidth) / 2, + 0 + )).x + : 0 + top: hoverTarget + ? hoverTarget.mapToGlobal(Qt.point(0, hoverTarget.height)).y + offsetY + : 0 + } + + mask: maskEnabled ? popupMask : undefined + WlrLayershell.namespace: "quickshell:styledPopup" //maybe this can fix with the popups not showing ? + + Region { + id: popupMask + item: popupContent + } + + Loader { + id: popupContent + sourceComponent: root.contentComponent + anchors.centerIn: parent + } + } +}