From 28bd79234d52704fbdcde02a0923bfcabb294f47 Mon Sep 17 00:00:00 2001 From: end-4 <97237370+end-4@users.noreply.github.com> Date: Sun, 13 Apr 2025 16:37:30 +0200 Subject: [PATCH] rounding decorations --- .config/hypr/hyprland/rules.conf | 6 +- .config/quickshell/modules/bar/Bar.qml | 249 ++++++++++-------- .config/quickshell/modules/bar/Resources.qml | 4 +- .../quickshell/modules/bar/SysTrayItem.qml | 6 +- .../quickshell/modules/common/Appearance.qml | 9 + .../modules/common/widgets/RoundCorner.qml | 64 +++++ .../modules/screenCorners/ScreenCorners.qml | 66 +++++ .../modules/sidebarRight/SidebarRight.qml | 46 ++++ .config/quickshell/shell.qml | 12 +- 9 files changed, 343 insertions(+), 119 deletions(-) create mode 100644 .config/quickshell/modules/common/widgets/RoundCorner.qml create mode 100644 .config/quickshell/modules/screenCorners/ScreenCorners.qml create mode 100644 .config/quickshell/modules/sidebarRight/SidebarRight.qml diff --git a/.config/hypr/hyprland/rules.conf b/.config/hypr/hyprland/rules.conf index d67554148..701d5ebd6 100644 --- a/.config/hypr/hyprland/rules.conf +++ b/.config/hypr/hyprland/rules.conf @@ -69,8 +69,6 @@ layerrule = noanim, anyrun layerrule = noanim, indicator.* layerrule = noanim, osk layerrule = noanim, hyprpicker -layerrule = blur, shell:* -layerrule = ignorealpha 0.6, shell:* layerrule = noanim, noanim layerrule = blur, gtk-layer-shell @@ -105,3 +103,7 @@ layerrule = blur, indicator.* layerrule = ignorealpha 0.6, indicator.* layerrule = blur, osk[0-9]* layerrule = ignorealpha 0.6, osk[0-9]* + +# Quickshell +layerrule = animation fade, quickshell:screenCorners + diff --git a/.config/quickshell/modules/bar/Bar.qml b/.config/quickshell/modules/bar/Bar.qml index a6d3b1ebb..e84697e6e 100644 --- a/.config/quickshell/modules/bar/Bar.qml +++ b/.config/quickshell/modules/bar/Bar.qml @@ -8,8 +8,8 @@ import Quickshell Scope { id: bar - readonly property int barHeight: 40 - readonly property int sideCenterModuleWidth: 360 + readonly property int barHeight: Appearance.sizes.barHeight + readonly property int barCenterSideModuleWidth: Appearance.sizes.barCenterSideModuleWidth Variants { model: Quickshell.screens @@ -20,112 +20,12 @@ Scope { property var modelData screen: modelData - height: barHeight - color: Appearance.colors.colLayer0 - - // Left section - RowLayout { - anchors.left: parent.left - implicitHeight: barHeight - - ActiveWindow { - bar: barRoot - } - - // Scroll to change brightness - WheelHandler { - onWheel: (event) => { - if (event.angleDelta.y < 0) - Brightness.value = -1; - else if (event.angleDelta.y > 0) - Brightness.value = 1; - } - acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad - } - - } - - // Middle section - RowLayout { - anchors.centerIn: parent - spacing: 8 - - RowLayout { - Layout.preferredWidth: sideCenterModuleWidth - spacing: 4 - Layout.fillHeight: true - implicitWidth: 350 - - Resources { - } - - Media { - Layout.fillWidth: true - } - - } - - RowLayout { - Layout.fillWidth: true - Layout.fillHeight: true - spacing: 4 - - Workspaces { - bar: barRoot - } - - } - - RowLayout { - Layout.preferredWidth: sideCenterModuleWidth - Layout.fillHeight: true - spacing: 4 - - ClockWidget { - Layout.alignment: Qt.AlignVCenter - Layout.fillWidth: true - } - - UtilButtons { - Layout.alignment: Qt.AlignVCenter - } - - Battery { - Layout.alignment: Qt.AlignVCenter - } - - } - - } - - // Right section - RowLayout { - anchors.right: parent.right - implicitHeight: barHeight - spacing: 20 - - SysTray { - bar: barRoot - } - - Item { // TODO make this wifi & bluetooth - Layout.leftMargin: Appearance.rounding.screenRounding - } - - // Scroll to change volume - WheelHandler { - onWheel: (event) => { - const currentVolume = Audio.sink?.audio.volume; - const step = currentVolume < 0.1 ? 0.01 : 0.02 || 0.2; - if (event.angleDelta.y < 0) - Audio.sink.audio.volume -= step; - else if (event.angleDelta.y > 0) - Audio.sink.audio.volume += step; - } - acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad - } - + height: barHeight + Appearance.rounding.screenRounding + exclusiveZone: barHeight + mask: Region { + item: barContent } + color: "transparent" anchors { top: true @@ -133,6 +33,141 @@ Scope { right: true } + Rectangle { + id: barContent + anchors.right: parent.right + anchors.left: parent.left + anchors.top: parent.top + color: Appearance.colors.colLayer0 + height: barHeight + // Left section + RowLayout { + anchors.left: parent.left + implicitHeight: barHeight + + ActiveWindow { + bar: barRoot + } + + // Scroll to change brightness + WheelHandler { + onWheel: (event) => { + if (event.angleDelta.y < 0) + Brightness.value = -1; + else if (event.angleDelta.y > 0) + Brightness.value = 1; + } + acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad + } + + } + + // Middle section + RowLayout { + anchors.centerIn: parent + spacing: 8 + + RowLayout { + Layout.preferredWidth: barCenterSideModuleWidth + spacing: 4 + Layout.fillHeight: true + implicitWidth: 350 + + Resources { + } + + Media { + Layout.fillWidth: true + } + + } + + RowLayout { + Layout.fillWidth: true + Layout.fillHeight: true + spacing: 4 + + Workspaces { + bar: barRoot + } + + } + + RowLayout { + Layout.preferredWidth: barCenterSideModuleWidth + Layout.fillHeight: true + spacing: 4 + + ClockWidget { + Layout.alignment: Qt.AlignVCenter + Layout.fillWidth: true + } + + UtilButtons { + Layout.alignment: Qt.AlignVCenter + } + + Battery { + Layout.alignment: Qt.AlignVCenter + } + + } + + } + + // Right section + RowLayout { + anchors.right: parent.right + implicitHeight: barHeight + spacing: 20 + + SysTray { + bar: barRoot + } + + Item { // TODO make this wifi & bluetooth + Layout.leftMargin: Appearance.rounding.screenRounding + } + + // Scroll to change volume + WheelHandler { + onWheel: (event) => { + const currentVolume = Audio.sink?.audio.volume; + const step = currentVolume < 0.1 ? 0.01 : 0.02 || 0.2; + if (event.angleDelta.y < 0) + Audio.sink.audio.volume -= step; + else if (event.angleDelta.y > 0) + Audio.sink.audio.volume += step; + } + acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad + } + + } + } + + // Round decorators + Item { + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + height: Appearance.rounding.screenRounding + + RoundCorner { + anchors.top: parent.top + anchors.left: parent.left + size: Appearance.rounding.screenRounding + corner: cornerEnum.topLeft + color: Appearance.colors.colLayer0 + } + RoundCorner { + anchors.top: parent.top + anchors.right: parent.right + size: Appearance.rounding.screenRounding + corner: cornerEnum.topRight + color: Appearance.colors.colLayer0 + } + } + } } diff --git a/.config/quickshell/modules/bar/Resources.qml b/.config/quickshell/modules/bar/Resources.qml index 4528f8b48..0a7f28f6e 100644 --- a/.config/quickshell/modules/bar/Resources.qml +++ b/.config/quickshell/modules/bar/Resources.qml @@ -28,14 +28,14 @@ Rectangle { Resource { iconName: "swap_horiz" percentage: ResourceUsage.swapUsedPercentage - shown: ConfigOptions.bar.resources.alwaysShowSwap || (MprisController.activePlayer == null) + shown: ConfigOptions.bar.resources.alwaysShowSwap || (MprisController.activePlayer?.trackTitle == null) Layout.leftMargin: shown ? 4 : 0 } Resource { iconName: "settings_slow_motion" percentage: ResourceUsage.cpuUsage - shown: ConfigOptions.bar.resources.alwaysShowCpu || (MprisController.activePlayer == null) + shown: ConfigOptions.bar.resources.alwaysShowCpu || !(MprisController.activePlayer?.trackTitle?.length > 0) Layout.leftMargin: shown ? 4 : 0 } diff --git a/.config/quickshell/modules/bar/SysTrayItem.qml b/.config/quickshell/modules/bar/SysTrayItem.qml index d40ce778b..c0c2e6bad 100644 --- a/.config/quickshell/modules/bar/SysTrayItem.qml +++ b/.config/quickshell/modules/bar/SysTrayItem.qml @@ -21,11 +21,9 @@ MouseArea { item.activate(); break; case Qt.RightButton: - if (item.hasMenu) { + if (item.hasMenu) menu.open(); - } - default: - console.log("Buttonevent unhandled"); + } } diff --git a/.config/quickshell/modules/common/Appearance.qml b/.config/quickshell/modules/common/Appearance.qml index bfff14963..e65a54193 100644 --- a/.config/quickshell/modules/common/Appearance.qml +++ b/.config/quickshell/modules/common/Appearance.qml @@ -8,6 +8,7 @@ Singleton { property QtObject colors property QtObject rounding property QtObject font + property QtObject sizes function mix(color1, color2, percentage) { var c1 = Qt.color(color1); @@ -152,4 +153,12 @@ Singleton { } } + sizes: QtObject { + property int barHeight: 40 + property int barCenterSideModuleWidth: 360 + property int sidebarWidth: 450 + property int hyprlandGapsOut: 5 + property int elevationMargin: 7 + } + } diff --git a/.config/quickshell/modules/common/widgets/RoundCorner.qml b/.config/quickshell/modules/common/widgets/RoundCorner.qml new file mode 100644 index 000000000..6a9020bc0 --- /dev/null +++ b/.config/quickshell/modules/common/widgets/RoundCorner.qml @@ -0,0 +1,64 @@ +import QtQuick 2.9 + +Item { + id: root + + property int size: 25 + property color color: "#000000" + + property QtObject cornerEnum: QtObject { + property int topLeft: 0 + property int topRight: 1 + property int bottomLeft: 2 + property int bottomRight: 3 + } + + property int corner: cornerEnum.topLeft // Default to TopLeft + + width: size + height: size + + Canvas { + id: canvas + + anchors.fill: parent + antialiasing: true + + onPaint: { + var ctx = getContext("2d"); + var r = root.size; + + ctx.beginPath(); + switch (root.corner) { + case cornerEnum.topLeft: + ctx.arc(r, r, r, Math.PI, 3 * Math.PI / 2); + ctx.lineTo(0, 0); + break; + case cornerEnum.topRight: + ctx.arc(0, r, r, 3 * Math.PI / 2, 2 * Math.PI); + ctx.lineTo(r, 0); + break; + case cornerEnum.bottomLeft: + ctx.arc(r, 0, r, Math.PI / 2, Math.PI); + ctx.lineTo(0, r); + break; + case cornerEnum.bottomRight: + ctx.arc(0, 0, r, 0, Math.PI / 2); + ctx.lineTo(r, r); + break; + } + ctx.closePath(); + ctx.fillStyle = root.color; + ctx.fill(); + } + } + + Behavior on size { + NumberAnimation { + duration: root.animationDuration + easing.type: Easing.OutCubic + } + + } + +} diff --git a/.config/quickshell/modules/screenCorners/ScreenCorners.qml b/.config/quickshell/modules/screenCorners/ScreenCorners.qml new file mode 100644 index 000000000..49b2560ef --- /dev/null +++ b/.config/quickshell/modules/screenCorners/ScreenCorners.qml @@ -0,0 +1,66 @@ +import "../common" +import "../common/widgets" +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Quickshell +import Quickshell.Wayland + +Scope { + id: screenCorners + readonly property Toplevel activeWindow: ToplevelManager.activeToplevel + + Variants { + model: Quickshell.screens + + PanelWindow { + id: barRoot + visible: !activeWindow?.fullscreen + + property var modelData + + screen: modelData + exclusionMode: ExclusionMode.Ignore + mask: Region { + item: null + } + WlrLayershell.namespace: "quickshell:screenCorners" + color: "transparent" + + anchors { + top: true + left: true + right: true + bottom: true + } + + RoundCorner { + anchors.top: parent.top + anchors.left: parent.left + size: Appearance.rounding.screenRounding + corner: cornerEnum.topLeft + } + RoundCorner { + anchors.top: parent.top + anchors.right: parent.right + size: Appearance.rounding.screenRounding + corner: cornerEnum.topRight + } + RoundCorner { + anchors.bottom: parent.bottom + anchors.left: parent.left + size: Appearance.rounding.screenRounding + corner: cornerEnum.bottomLeft + } + RoundCorner { + anchors.bottom: parent.bottom + anchors.right: parent.right + size: Appearance.rounding.screenRounding + corner: cornerEnum.bottomRight + } + + } + + } + +} diff --git a/.config/quickshell/modules/sidebarRight/SidebarRight.qml b/.config/quickshell/modules/sidebarRight/SidebarRight.qml new file mode 100644 index 000000000..fcb296431 --- /dev/null +++ b/.config/quickshell/modules/sidebarRight/SidebarRight.qml @@ -0,0 +1,46 @@ +import "../common" +import "../common/widgets" +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import Quickshell + +Scope { + id: bar + + readonly property int sidebarWidth: Appearance.sizes.sidebarWidth + + Variants { + model: Quickshell.screens + + PanelWindow { + id: barRoot + + property var modelData + + screen: modelData + exclusiveZone: 0 + width: sidebarWidth + color: "transparent" + + anchors { + top: true + right: true + bottom: true + } + + // Background + Rectangle { + id: sidebarRightBackground + anchors.centerIn: parent + width: parent.width - Appearance.sizes.hyprlandGapsOut * 2 + height: parent.height - Appearance.sizes.hyprlandGapsOut * 2 + color: Appearance.colors.colLayer0 + radius: Appearance.rounding.screenRounding - Appearance.sizes.elevationMargin + 1 + } + + } + + } + +} diff --git a/.config/quickshell/shell.qml b/.config/quickshell/shell.qml index 9859b8db3..869923f3a 100644 --- a/.config/quickshell/shell.qml +++ b/.config/quickshell/shell.qml @@ -1,16 +1,20 @@ //@ pragma UseQApplication +import "./modules/bar/" +import "./modules/sidebarRight/" +import "./modules/screenCorners/" import QtQuick import QtQuick.Controls import QtQuick.Layouts -import Quickshell -import "./modules/bar" - import QtQuick.Window +import Quickshell ShellRoot { Bar { } - + // SidebarRight { + // } + ScreenCorners { + } }