From 87f33d55ee8ef3ab3351d02493d810acad833ee9 Mon Sep 17 00:00:00 2001 From: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> Date: Wed, 25 Mar 2026 12:04:55 +1100 Subject: [PATCH] feat: sdf blob based drawers --- modules/bar/popouts/Wrapper.qml | 3 +- modules/dashboard/Wrapper.qml | 38 ++++---- modules/drawers/Drawers.qml | 145 +++++++++++++++++++++++++++++- modules/drawers/Interactions.qml | 2 +- modules/drawers/Panels.qml | 8 +- modules/launcher/Wrapper.qml | 33 +++---- modules/notifications/Wrapper.qml | 11 +-- modules/osd/Wrapper.qml | 37 ++++---- modules/session/Wrapper.qml | 37 ++++---- modules/sidebar/Wrapper.qml | 37 ++++---- modules/utilities/Wrapper.qml | 36 ++++---- 11 files changed, 273 insertions(+), 114 deletions(-) diff --git a/modules/bar/popouts/Wrapper.qml b/modules/bar/popouts/Wrapper.qml index 06bec9b0..f58b56da 100644 --- a/modules/bar/popouts/Wrapper.qml +++ b/modules/bar/popouts/Wrapper.qml @@ -15,7 +15,8 @@ Item { required property ShellScreen screen - readonly property real nonAnimWidth: x > 0 || hasCurrent ? children.find(c => c.shouldBeActive)?.implicitWidth ?? content.implicitWidth : 0 + readonly property real shownWidth: children.find(c => c.shouldBeActive)?.implicitWidth ?? content.implicitWidth + readonly property real nonAnimWidth: x > 0 || hasCurrent ? shownWidth : 0 readonly property real nonAnimHeight: children.find(c => c.shouldBeActive)?.implicitHeight ?? content.implicitHeight readonly property Item current: (content.item as Content)?.current ?? null diff --git a/modules/dashboard/Wrapper.qml b/modules/dashboard/Wrapper.qml index 596c21b7..8448faa6 100644 --- a/modules/dashboard/Wrapper.qml +++ b/modules/dashboard/Wrapper.qml @@ -30,8 +30,9 @@ Item { readonly property real nonAnimHeight: state === "visible" ? ((content.item as Content)?.nonAnimHeight ?? 0) : 0 - visible: height > 0 - implicitHeight: 0 + visible: anchors.topMargin > -implicitHeight - 5 + anchors.topMargin: -implicitHeight - 5 + implicitHeight: content.implicitHeight implicitWidth: content.implicitWidth onStateChanged: { @@ -46,32 +47,35 @@ Item { when: root.visibilities.dashboard && Config.dashboard.enabled PropertyChanges { - root.implicitHeight: content.implicitHeight + // root.implicitHeight: content.implicitHeight + root.anchors.topMargin: 0 } } transitions: [ Transition { - from: "" - to: "visible" + // from: "" + // to: "visible" Anim { - target: root - property: "implicitHeight" + target: root.anchors + property: "topMargin" duration: Appearance.anim.durations.expressiveDefaultSpatial easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial } - }, - Transition { - from: "visible" - to: "" - - Anim { - target: root - property: "implicitHeight" - easing.bezierCurve: Appearance.anim.curves.emphasized - } } + // Transition { + // from: "visible" + // to: "" + + // Anim { + // target: root.anchors + // property: "topMargin" + // easing.bezierCurve: Appearance.anim.curves.emphasized + // } + // } + + ] Timer { diff --git a/modules/drawers/Drawers.qml b/modules/drawers/Drawers.qml index 864ad5c4..1ae98c7a 100644 --- a/modules/drawers/Drawers.qml +++ b/modules/drawers/Drawers.qml @@ -6,6 +6,7 @@ import QtQuick.Effects import Quickshell import Quickshell.Hyprland import Quickshell.Wayland +import Caelestia.Blobs import qs.components import qs.components.containers import qs.services @@ -123,13 +124,113 @@ Variants { shadowColor: Qt.alpha(Colours.palette.m3shadow, 0.7) } - Border { + // Border { + // bar: bar + // } + + // Backgrounds { + // panels: panels + // bar: bar + // } + + BlobGroup { + id: blobGroup + + color: Colours.palette.m3surface + } + + BlobInvertedRect { + anchors.fill: parent + anchors.margins: -50 // Make border thicker to smooth out bulge from closed drawers + group: blobGroup + radius: Config.border.rounding + borderLeft: bar.implicitWidth - anchors.margins + borderRight: Config.border.thickness - anchors.margins + borderTop: Config.border.thickness - anchors.margins + borderBottom: Config.border.thickness - anchors.margins + } + + PanelBg { + id: dashBg + + group: blobGroup + panel: panels.dashboard bar: bar } - Backgrounds { - panels: panels + PanelBg { + id: launcherBg + + group: blobGroup + panel: panels.launcher bar: bar + deformAmount: 0.1 + } + + PanelBg { + id: sessionBg + + group: blobGroup + panel: panels.session + bar: bar + } + + PanelBg { + id: sidebarBg + + group: blobGroup + panel: panels.sidebar + bar: bar + deformAmount: 0 + } + + PanelBg { + id: osdBg + + group: blobGroup + panel: panels.osd + bar: bar + } + + PanelBg { + id: notifsBg + + group: blobGroup + panel: panels.notifications + bar: bar + } + + PanelBg { + id: utilsBg + + group: blobGroup + panel: panels.utilities + bar: bar + } + + PanelBg { + id: popoutBg + + group: blobGroup + panel: panels.popouts + bar: bar + + x: bar.implicitWidth - (panels.popouts.isDetached ? -(win.width - panels.popouts.shownWidth) / 2 : panels.popouts.hasCurrent ? 0 : panels.popouts.shownWidth + 5) + implicitWidth: panels.popouts.shownWidth + + Behavior on x { + Anim { + duration: Appearance.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + } + } + + Behavior on implicitWidth { + Anim { + duration: Appearance.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + } + } } } @@ -152,6 +253,31 @@ Variants { screen: scope.modelData visibilities: visibilities bar: bar + + dashboard.transform: Matrix4x4 { + matrix: dashBg.deformMatrix + } + launcher.transform: Matrix4x4 { + matrix: launcherBg.deformMatrix + } + session.transform: Matrix4x4 { + matrix: sessionBg.deformMatrix + } + sidebar.transform: Matrix4x4 { + matrix: sidebarBg.deformMatrix + } + osd.transform: Matrix4x4 { + matrix: osdBg.deformMatrix + } + notifications.transform: Matrix4x4 { + matrix: notifsBg.deformMatrix + } + utilities.transform: Matrix4x4 { + matrix: utilsBg.deformMatrix + } + popouts.transform: Matrix4x4 { + matrix: popoutBg.deformMatrix + } } BarWrapper { @@ -171,4 +297,17 @@ Variants { } } } + + component PanelBg: BlobRect { + required property Item panel + required property Item bar + property real deformAmount: 0.15 + + x: panel.x + bar.implicitWidth + y: panel.y + Config.border.thickness + implicitWidth: panel.width + implicitHeight: panel.height + radius: Config.border.rounding + deformScale: deformAmount / 10000 + } } diff --git a/modules/drawers/Interactions.qml b/modules/drawers/Interactions.qml index fcb128a9..6008a853 100644 --- a/modules/drawers/Interactions.qml +++ b/modules/drawers/Interactions.qml @@ -102,7 +102,7 @@ CustomMouseArea { visibilities.bar = false; } - if (panels.sidebar.width === 0) { + if (panels.sidebar.anchors.rightMargin === -panels.sidebar.implicitWidth - 5) { // Show osd on hover const showOsd = inRightPanel(panels.osd, x, y); diff --git a/modules/drawers/Panels.qml b/modules/drawers/Panels.qml index f2531cfa..006205fd 100644 --- a/modules/drawers/Panels.qml +++ b/modules/drawers/Panels.qml @@ -42,8 +42,8 @@ Item { visibilities: root.visibilities anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: session.width + sidebar.width + anchors.right: session.left + // anchors.rightMargin: session.width + sidebar.width } Notifications.Wrapper { @@ -66,8 +66,8 @@ Item { panels: root anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: sidebar.width + anchors.right: sidebar.left + // anchors.rightMargin: sidebar.width } Launcher.Wrapper { diff --git a/modules/launcher/Wrapper.qml b/modules/launcher/Wrapper.qml index cc5e86c6..f5c866af 100644 --- a/modules/launcher/Wrapper.qml +++ b/modules/launcher/Wrapper.qml @@ -24,8 +24,9 @@ Item { onMaxHeightChanged: timer.start() - visible: height > 0 - implicitHeight: 0 + visible: anchors.bottomMargin > -implicitHeight - 5 + anchors.bottomMargin: -implicitHeight - 5 + implicitHeight: content.implicitHeight implicitWidth: content.implicitWidth onShouldBeActiveChanged: { @@ -43,28 +44,30 @@ Item { id: showAnim Anim { - target: root - property: "implicitHeight" - to: root.contentHeight + target: root.anchors + property: "bottomMargin" + to: 0 duration: Appearance.anim.durations.expressiveDefaultSpatial easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial } - ScriptAction { - script: root.implicitHeight = Qt.binding(() => content.implicitHeight) - } + // ScriptAction { + // script: root.implicitHeight = Qt.binding(() => content.implicitHeight) + // } } SequentialAnimation { id: hideAnim - ScriptAction { - script: root.implicitHeight = root.implicitHeight - } + // ScriptAction { + // script: root.implicitHeight = root.implicitHeight + // } Anim { - target: root - property: "implicitHeight" - to: 0 - easing.bezierCurve: Appearance.anim.curves.emphasized + target: root.anchors + property: "bottomMargin" + to: -content.implicitHeight - 5 + // easing.bezierCurve: Appearance.anim.curves.emphasized + duration: Appearance.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial } } diff --git a/modules/notifications/Wrapper.qml b/modules/notifications/Wrapper.qml index 2b581e93..c0756b9a 100644 --- a/modules/notifications/Wrapper.qml +++ b/modules/notifications/Wrapper.qml @@ -10,23 +10,24 @@ Item { property alias osdPanel: content.osdPanel property alias sessionPanel: content.sessionPanel - visible: height > 0 + visible: anchors.topMargin > -implicitHeight - 5 + anchors.topMargin: -5 implicitWidth: Math.max(sidebarPanel.width, content.implicitWidth) implicitHeight: content.implicitHeight states: State { name: "hidden" - when: root.visibilities.sidebar && Config.sidebar.enabled + // when: root.visibilities.sidebar && Config.sidebar.enabled PropertyChanges { - root.implicitHeight: 0 + root.anchors.topMargin: -implicitHeight - 5 } } transitions: Transition { Anim { - target: root - property: "implicitHeight" + target: root.anchors + property: "topMargin" duration: Appearance.anim.durations.expressiveDefaultSpatial easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial } diff --git a/modules/osd/Wrapper.qml b/modules/osd/Wrapper.qml index 939b57de..87350d92 100644 --- a/modules/osd/Wrapper.qml +++ b/modules/osd/Wrapper.qml @@ -34,8 +34,9 @@ Item { brightness = root.monitor?.brightness ?? 0; } - visible: width > 0 - implicitWidth: 0 + visible: anchors.rightMargin > -implicitWidth + anchors.rightMargin: -implicitWidth + implicitWidth: content.implicitWidth implicitHeight: content.implicitHeight states: State { @@ -43,31 +44,33 @@ Item { when: root.shouldBeActive PropertyChanges { - root.implicitWidth: content.implicitWidth + root.anchors.rightMargin: 0 } } transitions: [ Transition { - from: "" - to: "visible" + // from: "" + // to: "visible" Anim { - target: root - property: "implicitWidth" + target: root.anchors + property: "rightMargin" easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial } - }, - Transition { - from: "visible" - to: "" - - Anim { - target: root - property: "implicitWidth" - easing.bezierCurve: Appearance.anim.curves.emphasized - } } + // Transition { + // from: "visible" + // to: "" + + // Anim { + // target: root + // property: "implicitWidth" + // easing.bezierCurve: Appearance.anim.curves.emphasized + // } + // } + + ] Connections { diff --git a/modules/session/Wrapper.qml b/modules/session/Wrapper.qml index 2924f776..b829409b 100644 --- a/modules/session/Wrapper.qml +++ b/modules/session/Wrapper.qml @@ -11,8 +11,9 @@ Item { required property var panels readonly property real nonAnimWidth: content.implicitWidth - visible: width > 0 - implicitWidth: 0 + visible: anchors.rightMargin > -implicitWidth - 1 + anchors.rightMargin: -implicitWidth - 1 + implicitWidth: content.implicitWidth implicitHeight: content.implicitHeight states: State { @@ -20,31 +21,33 @@ Item { when: root.visibilities.session && Config.session.enabled PropertyChanges { - root.implicitWidth: root.nonAnimWidth + root.anchors.rightMargin: 0 } } transitions: [ Transition { - from: "" - to: "visible" + // from: "" + // to: "visible" Anim { - target: root - property: "implicitWidth" + target: root.anchors + property: "rightMargin" easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial } - }, - Transition { - from: "visible" - to: "" - - Anim { - target: root - property: "implicitWidth" - easing.bezierCurve: root.panels.osd.width > 0 ? Appearance.anim.curves.expressiveDefaultSpatial : Appearance.anim.curves.emphasized - } } + // Transition { + // from: "visible" + // to: "" + + // Anim { + // target: root + // property: "implicitWidth" + // easing.bezierCurve: root.panels.osd.width > 0 ? Appearance.anim.curves.expressiveDefaultSpatial : Appearance.anim.curves.emphasized + // } + // } + + ] Loader { diff --git a/modules/sidebar/Wrapper.qml b/modules/sidebar/Wrapper.qml index ad256413..67929bd7 100644 --- a/modules/sidebar/Wrapper.qml +++ b/modules/sidebar/Wrapper.qml @@ -11,40 +11,43 @@ Item { required property var panels readonly property Props props: Props {} - visible: width > 0 - implicitWidth: 0 + visible: anchors.rightMargin > -implicitWidth - 5 + anchors.rightMargin: -implicitWidth - 5 + implicitWidth: Config.sidebar.sizes.width states: State { name: "visible" when: root.visibilities.sidebar && Config.sidebar.enabled PropertyChanges { - root.implicitWidth: Config.sidebar.sizes.width + root.anchors.rightMargin: 0 } } transitions: [ Transition { - from: "" - to: "visible" + // from: "" + // to: "visible" Anim { - target: root - property: "implicitWidth" + target: root.anchors + property: "rightMargin" duration: Appearance.anim.durations.expressiveDefaultSpatial easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial } - }, - Transition { - from: "visible" - to: "" - - Anim { - target: root - property: "implicitWidth" - easing.bezierCurve: root.panels.osd.width > 0 || root.panels.session.width > 0 ? Appearance.anim.curves.expressiveDefaultSpatial : Appearance.anim.curves.emphasized - } } + // Transition { + // from: "visible" + // to: "" + + // Anim { + // target: root + // property: "implicitWidth" + // easing.bezierCurve: root.panels.osd.width > 0 || root.panels.session.width > 0 ? Appearance.anim.curves.expressiveDefaultSpatial : Appearance.anim.curves.emphasized + // } + // } + + ] Loader { diff --git a/modules/utilities/Wrapper.qml b/modules/utilities/Wrapper.qml index 66a616f0..59288f5d 100644 --- a/modules/utilities/Wrapper.qml +++ b/modules/utilities/Wrapper.qml @@ -22,8 +22,9 @@ Item { } readonly property bool shouldBeActive: visibilities.sidebar || (visibilities.utilities && Config.utilities.enabled && !(visibilities.session && Config.session.enabled)) - visible: height > 0 - implicitHeight: 0 + visible: anchors.bottomMargin > -implicitHeight - 5 + anchors.bottomMargin: -implicitHeight - 5 + implicitHeight: content.implicitHeight implicitWidth: sidebar.visible ? sidebar.width : Config.utilities.sizes.width onStateChanged: { @@ -38,32 +39,33 @@ Item { when: root.shouldBeActive PropertyChanges { - root.implicitHeight: content.implicitHeight + Appearance.padding.large * 2 + root.anchors.bottomMargin: 0 } } transitions: [ Transition { - from: "" - to: "visible" + // from: "" + // to: "visible" Anim { - target: root - property: "implicitHeight" + target: root.anchors + property: "bottomMargin" duration: Appearance.anim.durations.expressiveDefaultSpatial easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial } - }, - Transition { - from: "visible" - to: "" - - Anim { - target: root - property: "implicitHeight" - easing.bezierCurve: Appearance.anim.curves.emphasized - } } + // Transition { + // from: "visible" + // to: "" + + // Anim { + // target: root + // property: "implicitHeight" + // easing.bezierCurve: Appearance.anim.curves.emphasized + // } + // } + ] Timer {