diff --git a/modules/bar/Bar.qml b/modules/bar/Bar.qml index e9044bf..bb45748 100644 --- a/modules/bar/Bar.qml +++ b/modules/bar/Bar.qml @@ -7,63 +7,73 @@ import qs import qs.settings Variants { - model: Quickshell.screens - delegate: WlrLayershell { - id: root - required property var modelData - property double moduleHeight: implicitHeight - 12 - screen: modelData - anchors { - top: true - left: true - right: true - } - implicitHeight: Config.barHeight - color: Qt.rgba(Colors.base00.r, Colors.base00.g, Colors.base00.b, Config.opacity) - layer: WlrLayer.Top + model: Quickshell.screens + delegate: WlrLayershell { + id: root + required property var modelData + property double moduleHeight: implicitHeight - 12 + screen: modelData + anchors { + top: true + left: true + right: true + } + margins { + top: Config.floating ? 10 : 0 + left: Config.floating ? 10 : 0 + right: Config.floating ? 10 : 0 + } + color: 'transparent' + implicitHeight: Config.barHeight + layer: WlrLayer.Top + Rectangle { + radius: Config.floating ? Config.rounding : 0 + color: Qt.rgba(Colors.base00.r, Colors.base00.g, Colors.base00.b, Config.opacity) + id: container + anchors.fill: parent + RowLayout { + id: leftLayout + spacing: 5 + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: Config.rounding + Ws { + moduleHeight: root.moduleHeight + barScreen: root.modelData + } + ActiveWindow { + moduleHeight: root.moduleHeight + } + } - RowLayout { - id: leftLayout - spacing: 5 - anchors.left: parent.left - anchors.verticalCenter: parent.verticalCenter - anchors.leftMargin: Config.rounding - Ws { - moduleHeight: root.moduleHeight - barScreen: root.modelData - } - ActiveWindow { - moduleHeight: root.moduleHeight - } - } + RowLayout { + id: centerLayout + anchors.centerIn: parent + spacing: 5 + Clock { + moduleHeight: root.moduleHeight + } + } - RowLayout { - id: centerLayout - anchors.centerIn: parent - spacing: 5 - Clock { - moduleHeight: root.moduleHeight - } + RowLayout { + id: rightLayout + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + spacing: 5 + anchors.rightMargin: Config.rounding + Mpris { + moduleHeight: root.moduleHeight + } + Bat { + moduleHeight: root.moduleHeight + } + Pw { + moduleHeight: root.moduleHeight + } + Tray { + moduleHeight: root.moduleHeight + } + } + } } - - RowLayout { - id: rightLayout - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - spacing: 5 - anchors.rightMargin: Config.rounding - Mpris { - moduleHeight: root.moduleHeight - } - Bat { - moduleHeight: root.moduleHeight - } - Pw { - moduleHeight: root.moduleHeight - } - Tray { - moduleHeight: root.moduleHeight - } - } - } } diff --git a/modules/corners/ScreenCorners.qml b/modules/corners/ScreenCorners.qml index d5728a3..c0473b9 100644 --- a/modules/corners/ScreenCorners.qml +++ b/modules/corners/ScreenCorners.qml @@ -6,192 +6,239 @@ import Quickshell.Wayland import qs import qs.settings -Item { - Variants { +/** +* ScreenCorners - Shape component for rendering screen corners +* +* Renders concave corners at the screen edges to create a rounded screen effect. +* Self-contained Shape component (no shadows). +*/ +Variants { model: Quickshell.screens - delegate: WlrLayershell { - id: tlWin - required property var modelData - screen: modelData - visible: Config.rounding > 0 - layer: WlrLayer.Top - anchors { - top: true - left: true - } -// margins.top: Config.barHeight - implicitWidth: Config.rounding - implicitHeight: Config.rounding - color: "transparent" - - Shape { - anchors.fill: parent - preferredRendererType: Shape.CurveRenderer - ShapePath { - fillColor: Qt.rgba(Colors.base00.r, Colors.base00.g, Colors.base00.b, Config.opacity) - strokeWidth: -1 - startX: 0 - startY: 0 - PathLine { - x: tlWin.implicitWidth - y: 0 - } - PathArc { - x: 0 - y: tlWin.implicitHeight - radiusX: tlWin.implicitWidth - radiusY: tlWin.implicitHeight - direction: PathArc.Counterclockwise - } - PathLine { - x: 0 - y: 0 - } + delegate: PanelWindow { + required property ShellScreen modelData + screen: modelData + id: root + anchors { + top: true + bottom: true + left: true + right: true } - } - } - } - - // Top-right corners - Variants { - model: Quickshell.screens - delegate: WlrLayershell { - id: trWin - required property var modelData - screen: modelData - visible: Config.rounding > 0 - exclusionMode: ExclusionMode.Ignore - layer: WlrLayer.Overlay - anchors { - top: true - right: true - } - margins.top: Config.barHeight - implicitWidth: Config.rounding - implicitHeight: Config.rounding - color: "transparent" - - Shape { - anchors.fill: parent - preferredRendererType: Shape.CurveRenderer - ShapePath { - fillColor: Qt.rgba(Colors.base00.r, Colors.base00.g, Colors.base00.b, Config.opacity) - strokeWidth: -1 - startX: 0 - startY: 0 - PathLine { - x: trWin.implicitWidth - y: 0 - } - PathLine { - x: trWin.implicitWidth - y: trWin.implicitHeight - } - PathArc { - x: 0 - y: 0 - radiusX: trWin.implicitWidth - radiusY: trWin.implicitHeight - direction: PathArc.Counterclockwise - } - PathLine { - x: 0 - y: 0 - } + margins.top: Config.floating ? 0 : Config.barHeight + mask: Region { + width: root.implicitWidth + height: root.implicitHeight } - } - } - } + color: 'transparent' + exclusionMode: ExclusionMode.Ignore - // Bottom-left corners - Variants { - model: Quickshell.screens - delegate: WlrLayershell { - id: blWin - required property var modelData - screen: modelData - visible: Config.rounding > 0 - exclusionMode: ExclusionMode.Ignore - layer: WlrLayer.Overlay - anchors { - bottom: true - left: true - } - implicitWidth: Config.rounding - implicitHeight: Config.rounding - color: "transparent" + // Wrapper with layer caching to reduce GPU tessellation overhead + Item { + id: container + anchors.fill: parent - Shape { - anchors.fill: parent - preferredRendererType: Shape.CurveRenderer - ShapePath { - fillColor: Qt.rgba(Colors.base00.r, Colors.base00.g, Colors.base00.b, Config.opacity) - strokeWidth: -1 - startX: 0 - startY: 0 - PathArc { - x: blWin.implicitWidth - y: blWin.implicitHeight - radiusX: blWin.implicitWidth - radiusY: blWin.implicitHeight - direction: PathArc.Counterclockwise - } - PathLine { - x: 0 - y: blWin.implicitHeight - } - PathLine { - x: 0 - y: 0 - } + // Cache the Shape to a texture to prevent continuous re-tessellation + layer.enabled: true + + Shape { + id: cornersShape + + anchors.fill: parent + preferredRendererType: Shape.CurveRenderer + asynchronous: true + enabled: false // Disable mouse input + visible: Config.rounding != 0 + + ShapePath { + id: cornersPath + + // Corner configuration + readonly property color cornerColor: Config.floating ? "black" : Colors.base00 + readonly property real cornerRadius: Config.rounding + readonly property real cornerSize: Config.rounding + + // Determine margins based on bar position + readonly property real topMargin: 0 + readonly property real bottomMargin: 0 + readonly property real leftMargin: 0 + readonly property real rightMargin: 0 + + // Screen dimensions + readonly property real screenWidth: cornersShape.width + readonly property real screenHeight: cornersShape.height + + // Only show screen corners if enabled and appropriate conditions are met + readonly property bool shouldShow: Config.rounding != 0 + + // ShapePath configuration + strokeWidth: -1 // No stroke, fill only + fillColor: shouldShow ? cornerColor : "transparent" + + // ========== PATH DEFINITION ========== + // Draws 4 separate corner squares at screen edges + // Each corner square has a concave arc on the inner diagonal + + // ========== TOP-LEFT CORNER ========== + // Arc is at the bottom-right of this square (inner diagonal) + // Start at top-left screen corner + startX: leftMargin + startY: topMargin + + // Top edge (moving right) + PathLine { + relativeX: cornersPath.cornerSize + relativeY: 0 + } + + // Right edge (moving down toward arc) + PathLine { + relativeX: 0 + relativeY: cornersPath.cornerSize - cornersPath.cornerRadius + } + + // Concave arc (bottom-right corner of square, curving inward toward screen center) + PathArc { + relativeX: -cornersPath.cornerRadius + relativeY: cornersPath.cornerRadius + radiusX: cornersPath.cornerRadius + radiusY: cornersPath.cornerRadius + direction: PathArc.Counterclockwise + } + + // Bottom edge (moving left) + PathLine { + relativeX: -(cornersPath.cornerSize - cornersPath.cornerRadius) + relativeY: 0 + } + + // Left edge (moving up) - closes back to start + PathLine { + relativeX: 0 + relativeY: -cornersPath.cornerSize + } + + // ========== TOP-RIGHT CORNER ========== + // Arc is at the bottom-left of this square (inner diagonal) + PathMove { + x: cornersPath.screenWidth - cornersPath.rightMargin - cornersPath.cornerSize + y: cornersPath.topMargin + } + + // Top edge (moving right) + PathLine { + relativeX: cornersPath.cornerSize + relativeY: 0 + } + + // Right edge (moving down) + PathLine { + relativeX: 0 + relativeY: cornersPath.cornerSize + } + + // Bottom edge (moving left toward arc) + PathLine { + relativeX: -(cornersPath.cornerSize - cornersPath.cornerRadius) + relativeY: 0 + } + + // Concave arc (bottom-left corner of square, curving inward toward screen center) + PathArc { + relativeX: -cornersPath.cornerRadius + relativeY: -cornersPath.cornerRadius + radiusX: cornersPath.cornerRadius + radiusY: cornersPath.cornerRadius + direction: PathArc.Counterclockwise + } + + // Left edge (moving up) - closes back to start + PathLine { + relativeX: 0 + relativeY: -(cornersPath.cornerSize - cornersPath.cornerRadius) + } + + // ========== BOTTOM-LEFT CORNER ========== + // Arc is at the top-right of this square (inner diagonal) + PathMove { + x: cornersPath.leftMargin + y: cornersPath.screenHeight - cornersPath.bottomMargin - cornersPath.cornerSize + } + + // Top edge (moving right toward arc) + PathLine { + relativeX: cornersPath.cornerSize - cornersPath.cornerRadius + relativeY: 0 + } + + // Concave arc (top-right corner of square, curving inward toward screen center) + PathArc { + relativeX: cornersPath.cornerRadius + relativeY: cornersPath.cornerRadius + radiusX: cornersPath.cornerRadius + radiusY: cornersPath.cornerRadius + direction: PathArc.Counterclockwise + } + + // Right edge (moving down) + PathLine { + relativeX: 0 + relativeY: cornersPath.cornerSize - cornersPath.cornerRadius + } + + // Bottom edge (moving left) + PathLine { + relativeX: -cornersPath.cornerSize + relativeY: 0 + } + + // Left edge (moving up) - closes back to start + PathLine { + relativeX: 0 + relativeY: -cornersPath.cornerSize + } + + // ========== BOTTOM-RIGHT CORNER ========== + // Arc is at the top-left of this square (inner diagonal) + // Start at bottom-right of square (different from other corners!) + PathMove { + x: cornersPath.screenWidth - cornersPath.rightMargin + y: cornersPath.screenHeight - cornersPath.bottomMargin + } + + // Bottom edge (moving left) + PathLine { + relativeX: -cornersPath.cornerSize + relativeY: 0 + } + + // Left edge (moving up toward arc) + PathLine { + relativeX: 0 + relativeY: -(cornersPath.cornerSize - cornersPath.cornerRadius) + } + + // Concave arc (top-left corner of square, curving inward toward screen center) + PathArc { + relativeX: cornersPath.cornerRadius + relativeY: -cornersPath.cornerRadius + radiusX: cornersPath.cornerRadius + radiusY: cornersPath.cornerRadius + direction: PathArc.Counterclockwise + } + + // Top edge (moving right) + PathLine { + relativeX: cornersPath.cornerSize - cornersPath.cornerRadius + relativeY: 0 + } + + // Right edge (moving down) - closes back to start + PathLine { + relativeX: 0 + relativeY: cornersPath.cornerSize + } + } + } } - } } - } - - // Bottom-right corners - Variants { - model: Quickshell.screens - delegate: WlrLayershell { - id: brWin - required property var modelData - screen: modelData - visible: Config.rounding > 0 - exclusionMode: ExclusionMode.Ignore - layer: WlrLayer.Overlay - anchors { - bottom: true - right: true - } - implicitWidth: Config.rounding - implicitHeight: Config.rounding - color: "transparent" - - Shape { - anchors.fill: parent - preferredRendererType: Shape.CurveRenderer - ShapePath { - fillColor: Qt.rgba(Colors.base00.r, Colors.base00.g, Colors.base00.b, Config.opacity) - strokeWidth: -1 - startX: brWin.implicitWidth - startY: brWin.implicitHeight - PathLine { - x: 0 - y: brWin.implicitHeight - } - PathArc { - x: brWin.implicitWidth - y: 0 - radiusX: brWin.implicitWidth - radiusY: brWin.implicitHeight - direction: PathArc.Counterclockwise - } - PathLine { - x: brWin.implicitWidth - y: brWin.implicitHeight - } - } - } - } - } } diff --git a/modules/ipc/Ipc.qml b/modules/ipc/Ipc.qml index 7c1d137..3abb6eb 100644 --- a/modules/ipc/Ipc.qml +++ b/modules/ipc/Ipc.qml @@ -33,6 +33,10 @@ IpcHandler { Config.opacity = newOpacity; } + function floating(toggle: bool) { + Config.floating = toggle + } + function setWall(newWall: string) { if (newWall.startsWith("/")) { Config.wallpaper = "file://" + newWall; diff --git a/modules/notifications/NotiPopup.qml b/modules/notifications/NotiPopup.qml index 69d1791..24798cd 100644 --- a/modules/notifications/NotiPopup.qml +++ b/modules/notifications/NotiPopup.qml @@ -26,7 +26,7 @@ WlrLayershell { top: true right: true } - margins.top: Config.barHeight + 8 + margins.top: Config.barHeight + 8 + (Config.floating ? 10 : 0) margins.right: 8 implicitHeight: notiList.contentHeight implicitWidth: activeScreen.width / 6 diff --git a/settings/Config.qml b/settings/Config.qml index 0391d07..135ac96 100644 --- a/settings/Config.qml +++ b/settings/Config.qml @@ -20,9 +20,10 @@ Singleton { property alias font: root.font property alias fontSize: root.fontSize property alias barHeight: root.barHeight - property alias roudning: root.rounding + property alias rounding: root.rounding property alias wallpaper: root.wallpaper property alias opacity: root.opacity - property string primaryMon: root.primaryMon + property alias primaryMon: root.primaryMon + property alias floating: root.floating } } diff --git a/shell.qml b/shell.qml index f758e5a..62dc5eb 100644 --- a/shell.qml +++ b/shell.qml @@ -8,9 +8,9 @@ import qs.modules.notifications import qs.modules.corners ShellRoot { - Bar {} - Ipc {} - Wallpaper {} - NotiPopup {} - ScreenCorners {} + ScreenCorners {} + Bar {} + Ipc {} + Wallpaper {} + NotiPopup {} }