diff --git a/modules/Bar.qml b/modules/Bar.qml index 25673d1..48cf971 100644 --- a/modules/Bar.qml +++ b/modules/Bar.qml @@ -59,6 +59,7 @@ PanelWindow { Layout.maximumWidth: 400 visible: M.Modules.windowTitle } + Item { Layout.fillWidth: true } } // ---- right ---- diff --git a/modules/ScreenCorners.qml b/modules/ScreenCorners.qml new file mode 100644 index 0000000..a762917 --- /dev/null +++ b/modules/ScreenCorners.qml @@ -0,0 +1,87 @@ +import QtQuick +import Quickshell +import Quickshell.Wayland +import "." as M + +// Empty region = no input area — clicks pass through to windows below + +// Draws rounded black corners at the edges of each screen. +// Disabled when screenRadius is 0 (the default). +Item { + id: root + + required property var screen + + readonly property int _r: M.Theme.screenRadius + + Repeater { + model: root._r > 0 ? [ + { top: true, left: true, right: false, bottom: false, corner: 0 }, + { top: true, left: false, right: true, bottom: false, corner: 1 }, + { top: false, left: true, right: false, bottom: true, corner: 2 }, + { top: false, left: false, right: true, bottom: true, corner: 3 } + ] : [] + + delegate: PanelWindow { + id: cornerWindow + + required property var modelData + + screen: root.screen + color: "transparent" + + WlrLayershell.layer: WlrLayer.Overlay + WlrLayershell.exclusiveZone: 0 + WlrLayershell.namespace: "nova-corners" + mask: Region {} + + anchors.top: cornerWindow.modelData.top + anchors.left: cornerWindow.modelData.left + anchors.right: cornerWindow.modelData.right + anchors.bottom: cornerWindow.modelData.bottom + + implicitWidth: root._r + implicitHeight: root._r + + Canvas { + anchors.fill: parent + onPaint: { + const r = root._r; + const ctx = getContext("2d"); + ctx.clearRect(0, 0, r, r); + ctx.fillStyle = "black"; + ctx.beginPath(); + + switch (cornerWindow.modelData.corner) { + case 0: // top-left + ctx.moveTo(0, 0); + ctx.lineTo(r, 0); + ctx.arc(r, r, r, -Math.PI / 2, Math.PI, true); + ctx.closePath(); + break; + case 1: // top-right + ctx.moveTo(r, 0); + ctx.lineTo(0, 0); + ctx.arc(0, r, r, -Math.PI / 2, 0, false); + ctx.closePath(); + break; + case 2: // bottom-left + ctx.moveTo(0, r); + ctx.lineTo(0, 0); + ctx.arc(r, 0, r, Math.PI, Math.PI / 2, true); + ctx.closePath(); + break; + case 3: // bottom-right + ctx.moveTo(r, r); + ctx.lineTo(r, 0); + ctx.arc(0, 0, r, 0, Math.PI / 2, false); + ctx.closePath(); + break; + } + + ctx.fill(); + } + } + } + } +} diff --git a/modules/Theme.qml b/modules/Theme.qml index 80c6ba0..6c9e834 100644 --- a/modules/Theme.qml +++ b/modules/Theme.qml @@ -34,6 +34,7 @@ QtObject { property int barSpacing: 12 property int moduleSpacing: 4 property int radius: 4 + property int screenRadius: 15 property FileView _themeFile: FileView { path: (Quickshell.env("XDG_CONFIG_HOME") || (Quickshell.env("HOME") + "/.config")) + "/nova-shell/theme.json" @@ -72,5 +73,7 @@ QtObject { root.moduleSpacing = data.moduleSpacing; if (data.radius !== undefined) root.radius = data.radius; + if (data.screenRadius !== undefined) + root.screenRadius = data.screenRadius; } } diff --git a/modules/qmldir b/modules/qmldir index 2b06466..2df866b 100644 --- a/modules/qmldir +++ b/modules/qmldir @@ -12,6 +12,7 @@ Volume 1.0 Volume.qml Tray 1.0 Tray.qml TrayMenu 1.0 TrayMenu.qml PowerMenu 1.0 PowerMenu.qml +ScreenCorners 1.0 ScreenCorners.qml ThemedIcon 1.0 ThemedIcon.qml Battery 1.0 Battery.qml Mpris 1.0 Mpris.qml diff --git a/shell.qml b/shell.qml index 6b0317b..2476f27 100644 --- a/shell.qml +++ b/shell.qml @@ -18,6 +18,10 @@ ShellRoot { Flyout { screen: scope.modelData } + + ScreenCorners { + screen: scope.modelData + } } } }