From 50e99501de904d878753788e9effdd3ca3538a37 Mon Sep 17 00:00:00 2001 From: zach Date: Sat, 6 Jun 2026 21:13:44 +0200 Subject: [PATCH] switches and popouts --- Components/CustomSplitButton.qml | 103 ++-- Components/CustomSplitButtonRow.qml | 12 +- Components/CustomSwitch.qml | 26 +- Components/Elevation.qml | 3 +- Components/Menu.qml | 198 ++++--- Config/AppearanceConf.qml | 10 +- Drawers/Drawers.qml | 25 + Drawers/Interactions.qml | 2 +- Drawers/Windows.qml | 701 ++++++++++++------------ Modules/Settings/Categories/General.qml | 3 +- shell.qml | 2 +- 11 files changed, 566 insertions(+), 519 deletions(-) create mode 100644 Drawers/Drawers.qml diff --git a/Components/CustomSplitButton.qml b/Components/CustomSplitButton.qml index 3621a71..76364cc 100644 --- a/Components/CustomSplitButton.qml +++ b/Components/CustomSplitButton.qml @@ -1,7 +1,6 @@ import QtQuick import QtQuick.Layouts import qs.Config -import qs.Helpers Row { id: root @@ -12,62 +11,46 @@ Row { } property alias active: menu.active - property color color: type == CustomSplitButton.Filled ? DynamicColors.palette.m3primary : DynamicColors.palette.m3secondaryContainer + property color colour: type == CustomSplitButton.Filled ? DynamicColors.palette.m3primary : DynamicColors.palette.m3secondaryContainer property bool disabled - property color disabledColor: Qt.alpha(DynamicColors.palette.m3onSurface, 0.1) - property color disabledTextColor: Qt.alpha(DynamicColors.palette.m3onSurface, 0.38) + property color disabledColour: Qt.alpha(DynamicColors.palette.m3onSurface, 0.1) + property color disabledTextColour: Qt.alpha(DynamicColors.palette.m3onSurface, 0.38) + readonly property alias expandBtn: expandBtn property alias expanded: menu.expanded property string fallbackIcon property string fallbackText - property real horizontalPadding: Appearance.padding.normal - property alias iconLabel: iconLabel - property alias label: label - property alias menu: menu + property real horizontalPadding: Appearance.padding.larger + readonly property alias iconLabel: iconLabel + readonly property alias label: label + readonly property alias menu: menu property alias menuItems: menu.items property bool menuOnTop - property alias stateLayer: stateLayer - property color textColor: type == CustomSplitButton.Filled ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSecondaryContainer + property real minLeftWidth + readonly property alias stateLayer: stateLayer + property color textColour: type == CustomSplitButton.Filled ? DynamicColors.palette.m3onPrimary : DynamicColors.palette.m3onSecondaryContainer + readonly property alias textRow: textRow property int type: CustomSplitButton.Filled - property real verticalPadding: Appearance.padding.smaller + property real verticalPadding: Appearance.padding.small - function closeDropdown(): void { - SettingsDropdowns.close(menu); - } - - function openDropdown(): void { - SettingsDropdowns.open(menu, root); - } - - function toggleDropdown(): void { - SettingsDropdowns.toggle(menu, root); - } - - spacing: Math.floor(Appearance.spacing.small / 2) - - onExpandedChanged: { - if (!expanded) - SettingsDropdowns.forget(menu); - } + spacing: Math.floor(Appearance.spacing.extraSmall) CustomRect { bottomRightRadius: Appearance.rounding.small / 2 - color: !root.enabled ? root.disabledColor : root.color + color: root.disabled ? root.disabledColour : root.colour implicitHeight: expandBtn.implicitHeight - implicitWidth: textRow.implicitWidth + root.horizontalPadding * 2 + implicitWidth: Math.max(root.minLeftWidth, textRow.implicitWidth + root.horizontalPadding * 2) radius: implicitHeight / 2 * Math.min(1, Appearance.rounding.scale) topRightRadius: Appearance.rounding.small / 2 StateLayer { id: stateLayer - function onClicked(): void { - root.active?.clicked(); - } + bottomRightRadius: parent.bottomRightRadius + color: root.textColour + disabled: root.disabled + topRightRadius: parent.topRightRadius - color: root.textColor - disabled: !root.enabled - rect.bottomRightRadius: parent.bottomRightRadius - rect.topRightRadius: parent.topRightRadius + onClicked: root.active?.clicked() } RowLayout { @@ -82,7 +65,7 @@ Row { Layout.alignment: Qt.AlignVCenter animate: true - color: !root.enabled ? root.disabledTextColor : root.textColor + color: root.disabled ? root.disabledTextColour : root.textColour fill: 1 text: root.active?.activeIcon ?? root.fallbackIcon } @@ -94,12 +77,12 @@ Row { Layout.preferredWidth: implicitWidth animate: true clip: true - color: !root.enabled ? root.disabledTextColor : root.textColor + color: root.disabled ? root.disabledTextColour : root.textColour text: root.active?.activeText ?? root.fallbackText Behavior on Layout.preferredWidth { Anim { - easing.bezierCurve: Appearance.anim.curves.emphasized + type: Anim.Emphasized } } } @@ -112,7 +95,7 @@ Row { property real rad: root.expanded ? implicitHeight / 2 * Math.min(1, Appearance.rounding.scale) : Appearance.rounding.small / 2 bottomLeftRadius: rad - color: !root.enabled ? root.disabledColor : root.color + color: root.disabled ? root.disabledColour : root.colour implicitHeight: expandIcon.implicitHeight + root.verticalPadding * 2 implicitWidth: implicitHeight radius: implicitHeight / 2 * Math.min(1, Appearance.rounding.scale) @@ -126,14 +109,12 @@ Row { StateLayer { id: expandStateLayer - function onClicked(): void { - root.toggleDropdown(); - } - - color: root.textColor - disabled: !root.enabled + color: root.textColour + disabled: root.disabled rect.bottomLeftRadius: parent.bottomLeftRadius rect.topLeftRadius: parent.topLeftRadius + + onClicked: root.expanded = !root.expanded } MaterialIcon { @@ -141,7 +122,7 @@ Row { anchors.centerIn: parent anchors.horizontalCenterOffset: root.expanded ? 0 : -Math.floor(root.verticalPadding / 4) - color: !root.enabled ? root.disabledTextColor : root.textColor + color: root.disabled ? root.disabledTextColour : root.textColour rotation: root.expanded ? 180 : 0 text: "expand_more" @@ -154,24 +135,14 @@ Row { } } } + } - Menu { - id: menu + Menu { + id: menu - anchors.bottomMargin: Appearance.spacing.small - anchors.right: parent.right - anchors.top: parent.bottom - anchors.topMargin: Appearance.spacing.small - - states: State { - when: root.menuOnTop - - AnchorChanges { - anchors.bottom: expandBtn.top - anchors.top: undefined - target: menu - } - } - } + attachSideY: root.menuOnTop ? Menu.Top : Menu.Bottom + attachTo: expandBtn + marginY: Appearance.spacing.small * (root.menuOnTop ? -1 : 1) + thisSideY: root.menuOnTop ? Menu.Bottom : Menu.Top } } diff --git a/Components/CustomSplitButtonRow.qml b/Components/CustomSplitButtonRow.qml index 15bb182..2e59738 100644 --- a/Components/CustomSplitButtonRow.qml +++ b/Components/CustomSplitButtonRow.qml @@ -9,7 +9,6 @@ Item { property alias active: splitButton.active property alias buttonAlias: splitButton - property bool enabled: true property alias expanded: splitButton.expanded property int expandedZ: 100 required property string label @@ -25,7 +24,7 @@ Item { implicitHeight: row.implicitHeight + Appearance.padding.smaller * 2 opacity: shouldBeActive ? 1 : 0 scale: shouldBeActive ? 1 : 0.8 - z: root.expanded ? expandedZ : -1 + z: splitButton.menu.implicitHeight > 0 ? expandedZ : 1 Behavior on opacity { Anim { @@ -50,7 +49,6 @@ Item { color: root.enabled ? DynamicColors.palette.m3onSurface : DynamicColors.palette.m3onSurfaceVariant font.pointSize: Appearance.font.size.larger text: root.label - z: root.expanded ? root.expandedZ : -1 } CustomSplitButton { @@ -58,14 +56,16 @@ Item { enabled: root.enabled type: CustomSplitButton.Filled - z: root.expanded ? root.expandedZ : -1 + z: 2 menu.onItemSelected: item => { root.selected(item); - splitButton.closeDropdown(); + // splitButton.closeDropdown(); } stateLayer.onClicked: { - splitButton.toggleDropdown(); + // splitButton.toggleDropdown(); + splitButton.expanded = !splitButton.expanded; + console.log(root.z); } } } diff --git a/Components/CustomSwitch.qml b/Components/CustomSwitch.qml index 45f4246..e715f15 100644 --- a/Components/CustomSwitch.qml +++ b/Components/CustomSwitch.qml @@ -1,6 +1,6 @@ import QtQuick -import QtQuick.Templates import QtQuick.Shapes +import QtQuick.Templates import qs.Config Switch { @@ -13,26 +13,28 @@ Switch { indicator: CustomRect { color: root.checked && root.enabled ? DynamicColors.palette.m3primary : DynamicColors.layer(DynamicColors.palette.m3surfaceContainerHighest, root.cLayer) - implicitHeight: 13 + 7 * 2 + implicitHeight: Appearance.font.size.medium + Appearance.padding.normal * 2 implicitWidth: implicitHeight * 1.7 radius: Appearance.rounding.full CustomRect { - readonly property real nonAnimWidth: root.pressed ? implicitHeight * 1.3 : implicitHeight + readonly property real nonAnimWidth: root.pressed ? implicitHeight * 1.2 : implicitHeight anchors.verticalCenter: parent.verticalCenter color: root.checked && root.enabled ? DynamicColors.palette.m3onPrimary : DynamicColors.layer(DynamicColors.palette.m3outline, root.cLayer + 1) - implicitHeight: parent.implicitHeight - 10 + implicitHeight: parent.implicitHeight - Appearance.padding.extraSmall implicitWidth: nonAnimWidth radius: Appearance.rounding.full - x: root.checked ? parent.implicitWidth - nonAnimWidth - 10 / 2 : 10 / 2 + x: root.checked ? parent.implicitWidth - nonAnimWidth - Appearance.padding.extraSmall / 2 : Appearance.padding.extraSmall / 2 Behavior on implicitWidth { Anim { + type: Anim.FastSpatial } } Behavior on x { Anim { + type: Anim.FastSpatial } } @@ -44,6 +46,7 @@ Switch { Behavior on opacity { Anim { + type: Anim.DefaultEffects } } } @@ -63,14 +66,14 @@ Switch { } property point end2: { if (root.pressed) - return Qt.point(width, height / 2); + return Qt.point(width * 0.8, height / 2); if (root.checked) return Qt.point(width * 0.85, height * 0.2); return Qt.point(width * 0.85, height * 0.15); } property point start1: { if (root.pressed) - return Qt.point(width * 0.1, height / 2); + return Qt.point(width * 0.2, height / 2); if (root.checked) return Qt.point(width * 0.15, height / 2); return Qt.point(width * 0.15, height * 0.15); @@ -88,7 +91,7 @@ Switch { anchors.centerIn: parent asynchronous: true - height: parent.implicitHeight - Appearance.padding.small * 2 + height: parent.implicitHeight - Appearance.padding.larger preferredRendererType: Shape.CurveRenderer width: height @@ -110,7 +113,7 @@ Switch { } ShapePath { - capStyle: Appearance.rounding.scale === 0 ? ShapePath.SquareCap : ShapePath.RoundCap + capStyle: ShapePath.RoundCap fillColor: "transparent" startX: icon.start1.x startY: icon.start1.y @@ -148,8 +151,7 @@ Switch { } component PropAnim: PropertyAnimation { - duration: MaterialEasing.expressiveEffectsTime - easing.bezierCurve: MaterialEasing.expressiveEffects - easing.type: Easing.BezierSpline + duration: Appearance.anim.durations.expressiveFastSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveFastSpatial } } diff --git a/Components/Elevation.qml b/Components/Elevation.qml index 26b8fe6..bdef51e 100644 --- a/Components/Elevation.qml +++ b/Components/Elevation.qml @@ -1,6 +1,6 @@ -import qs.Config import QtQuick import QtQuick.Effects +import qs.Config RectangularShadow { property real dp: [0, 1, 3, 6, 8, 12][level] @@ -13,6 +13,7 @@ RectangularShadow { Behavior on dp { Anim { + type: Anim.SlowEffects } } } diff --git a/Components/Menu.qml b/Components/Menu.qml index 8222359..a633a9c 100644 --- a/Components/Menu.qml +++ b/Components/Menu.qml @@ -2,109 +2,169 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts +import Quickshell import qs.Config +import qs.Drawers -Elevation { +MouseArea { id: root + enum Side { + Top, + Bottom, + Left, + Right + } + property MenuItem active: items[0] ?? null + property int attachSideX: Menu.Right + property int attachSideY: Menu.Bottom + required property Item attachTo property bool expanded property list items + property real marginX + property real marginY + property int thisSideX: Menu.Right + property int thisSideY: Menu.Top signal itemSelected(item: MenuItem) - implicitHeight: root.expanded ? column.implicitHeight + Appearance.padding.small * 2 : 0 - implicitWidth: Math.max(200, column.implicitWidth) - level: 2 - opacity: root.expanded ? 1 : 0 - radius: Appearance.rounding.normal - - Behavior on implicitHeight { - Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial - easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial - } + anchors.fill: parent + enabled: expanded + layer.enabled: opacity < 1 + opacity: expanded ? 1 : 0 + parent: { + const win = QsWindow.window; + const contentWin = win as Windows; + return contentWin ? contentWin.interactionWrapper : (win as QsWindow).contentItem; } + Behavior on opacity { Anim { - duration: Appearance.anim.durations.expressiveDefaultSpatial + type: Anim.DefaultEffects } } - CustomClippingRect { - anchors.fill: parent - color: DynamicColors.palette.m3surfaceContainer - radius: parent.radius + onClicked: expanded = false - ColumnLayout { - id: column + TransformWatcher { + id: watcher - anchors.left: parent.left - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - spacing: 5 + a: root.parent + b: root.attachTo + } - Repeater { - model: root.items + Elevation { + id: menu - CustomRect { - id: item + implicitHeight: column.implicitHeight + column.anchors.margins * 2 + implicitWidth: Math.max(200, column.implicitWidth + column.anchors.margins * 2) + level: 2 + radius: Appearance.rounding.medium + x: { + watcher.transform; + const item = root.attachTo; + let off = root.attachSideX === Menu.Left ? 0 : item.width; + if (root.thisSideX === Menu.Right) + off -= width; + return item.mapToItem(root.parent, off, 0).x + root.marginX; + } + y: { + watcher.transform; + const item = root.attachTo; + let off = root.attachSideY === Menu.Top ? 0 : item.height; + if (root.thisSideY === Menu.Bottom) + off -= height; + return item.mapToItem(root.parent, 0, off).y + root.marginY; + } - readonly property bool active: modelData === root.active - required property int index - required property MenuItem modelData + transform: Scale { + origin.y: root.thisSideY === Menu.Bottom ? menu.height : 0 + yScale: root.expanded ? 1 : 0.1 - Layout.fillWidth: true - implicitHeight: menuOptionRow.implicitHeight + Appearance.padding.normal * 2 - implicitWidth: menuOptionRow.implicitWidth + Appearance.padding.normal * 2 + Behavior on yScale { + Anim { + } + } + } + + CustomRect { + anchors.fill: parent + color: DynamicColors.palette.m3surfaceContainerLow + radius: parent.radius + + ColumnLayout { + id: column + + anchors.fill: parent + anchors.margins: Appearance.padding.extraSmall + spacing: Appearance.spacing.extraSmall + + Repeater { + id: repeater + + model: root.items CustomRect { - anchors.fill: parent - anchors.leftMargin: Appearance.padding.small - anchors.rightMargin: Appearance.padding.small - color: Qt.alpha(DynamicColors.palette.m3secondaryContainer, active ? 1 : 0) - radius: Appearance.rounding.normal - Appearance.padding.small + id: item + + readonly property bool active: modelData === root.active + required property int index + required property MenuItem modelData + + Layout.fillWidth: true + color: Qt.alpha(DynamicColors.palette.m3tertiaryContainer, active ? 1 : 0) + implicitHeight: menuOptionRow.implicitHeight + Appearance.padding.larger * 2 + implicitWidth: menuOptionRow.implicitWidth + Appearance.padding.larger * 2 + radius: Appearance.rounding.small + + Behavior on radius { + Anim { + } + } StateLayer { - function onClicked(): void { + color: item.active ? DynamicColors.palette.m3onTertiaryContainer : DynamicColors.palette.m3onSurface + disabled: !root.expanded + + onClicked: { root.itemSelected(item.modelData); root.active = item.modelData; + item.modelData.clicked(); root.expanded = false; } - - color: item.active ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurface - disabled: !root.expanded - } - } - - RowLayout { - id: menuOptionRow - - anchors.fill: parent - anchors.margins: Appearance.padding.normal - spacing: Appearance.spacing.small - - MaterialIcon { - Layout.alignment: Qt.AlignVCenter - color: item.active ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurfaceVariant - text: item.modelData.icon } - CustomText { - Layout.alignment: Qt.AlignVCenter - Layout.fillWidth: true - color: item.active ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurface - text: item.modelData.text - } + RowLayout { + id: menuOptionRow - Loader { - Layout.alignment: Qt.AlignVCenter - active: item.modelData.trailingIcon.length > 0 - visible: active + anchors.fill: parent + anchors.margins: Appearance.padding.larger + spacing: Appearance.spacing.small - sourceComponent: MaterialIcon { - color: item.active ? DynamicColors.palette.m3onSecondaryContainer : DynamicColors.palette.m3onSurface - text: item.modelData.trailingIcon + MaterialIcon { + Layout.alignment: Qt.AlignVCenter + color: item.active ? DynamicColors.palette.m3onTertiaryContainer : DynamicColors.palette.m3onSurfaceVariant + text: item.modelData.icon + } + + CustomText { + Layout.alignment: Qt.AlignVCenter + Layout.fillWidth: true + color: item.active ? DynamicColors.palette.m3onTertiaryContainer : DynamicColors.palette.m3onSurface + text: item.modelData.text + } + + Loader { + Layout.alignment: Qt.AlignVCenter + active: item.modelData.trailingIcon.length > 0 + asynchronous: true + visible: active + + sourceComponent: MaterialIcon { + color: item.active ? DynamicColors.palette.m3onTertiaryContainer : DynamicColors.palette.m3onSurfaceVariant + text: item.modelData.trailingIcon + } } } } diff --git a/Config/AppearanceConf.qml b/Config/AppearanceConf.qml index 7d3b375..859e0a3 100644 --- a/Config/AppearanceConf.qml +++ b/Config/AppearanceConf.qml @@ -63,7 +63,8 @@ JsonObject { component FontSize: JsonObject { property int extraLarge: 28 * scale property int large: 18 * scale - property int larger: 15 * scale + property int larger: 16 * scale + property int medium: 14 * scale property int normal: 13 * scale property real scale: 1 property int small: 11 * scale @@ -76,9 +77,11 @@ JsonObject { } } component Padding: JsonObject { - property int large: 15 * scale + property int extraLargeIncreased: 32 * scale + property int extraSmall: 4 * scale + property int large: 16 * scale property int larger: 12 * scale - property int normal: 9 * scale + property int normal: 8 * scale property real scale: 1 property int small: 5 * scale property int smaller: 7 * scale @@ -88,6 +91,7 @@ JsonObject { property int extraSmall: 4 * scale property int full: 1000 * scale property int large: 24 * scale + property int medium: 16 * scale property int normal: 18 * scale property real scale: 1 property int small: 12 * scale diff --git a/Drawers/Drawers.qml b/Drawers/Drawers.qml new file mode 100644 index 0000000..b026775 --- /dev/null +++ b/Drawers/Drawers.qml @@ -0,0 +1,25 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import Quickshell + +Variants { + model: Quickshell.screens + + Scope { + id: scope + + required property ShellScreen modelData + + Exclusions { + bar: content.bar + screen: scope.modelData + } + + Windows { + id: content + + screen: scope.modelData + } + } +} diff --git a/Drawers/Interactions.qml b/Drawers/Interactions.qml index ab7a246..56b1cb2 100644 --- a/Drawers/Interactions.qml +++ b/Drawers/Interactions.qml @@ -59,7 +59,7 @@ Item { cursorShape: (active && centroid.pressPosition.y < root.bar.implicitHeight) ? Qt.ClosedHandCursor : undefined dragThreshold: 0 - grabPermissions: PointerHandler.CanTakeOverFromHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByAnything + grabPermissions: PointerHandler.CanTakeOverFromHandlersOfSameType | PointerHandler.ApprovesTakeOverByAnything maximumPointCount: 1 minimumPointCount: 1 target: null diff --git a/Drawers/Windows.qml b/Drawers/Windows.qml index f417c43..b59b95e 100644 --- a/Drawers/Windows.qml +++ b/Drawers/Windows.qml @@ -9,397 +9,382 @@ import Quickshell.Hyprland import ZShell.Blobs import qs.Daemons import qs.Components -import qs.Modules import qs.Modules.Bar import qs.Config import qs.Helpers import qs.Drawers -Variants { - model: Quickshell.screens +CustomWindow { + id: root - Scope { - id: scope + readonly property alias bar: bar + readonly property bool hasFullscreen: Hypr.monitorFor(screen)?.activeWorkspace?.toplevels.values.some(t => t.lastIpcObject.fullscreen === 2) + readonly property alias interactionWrapper: interactions + property var root: Quickshell.shellDir - required property var modelData + WlrLayershell.exclusionMode: ExclusionMode.Ignore + // WlrLayershell.keyboardFocus: visibilities.dock || visibilities.launcher || visibilities.sidebar || visibilities.dashboard || visibilities.settings || visibilities.resources ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None + color: "transparent" + contentItem.focus: true + mask: visibilities.isDrawing ? null : region + name: "Bar" - Exclusions { - bar: bar - screen: scope.modelData + contentItem.Keys.onEscapePressed: { + if (Config.barConfig.autoHide) + visibilities.bar = false; + visibilities.sidebar = false; + visibilities.dashboard = false; + visibilities.osd = false; + visibilities.settings = false; + visibilities.resources = false; + } + onHasFullscreenChanged: { + visibilities.launcher = false; + visibilities.dashboard = false; + visibilities.osd = false; + visibilities.settings = false; + visibilities.resources = false; + } + + Region { + id: region + + height: root.height - bar.implicitHeight - Config.barConfig.border + intersection: Intersection.Xor + regions: popoutRegions.instances + width: root.width - Config.barConfig.border * 2 + x: Config.barConfig.border + y: bar.implicitHeight + } + + anchors { + bottom: true + left: true + right: true + top: true + } + + Variants { + id: popoutRegions + + model: panels.children + + Region { + required property Item modelData + + height: modelData.height + intersection: Intersection.Subtract + width: modelData.width + x: modelData.x + Config.barConfig.border + y: modelData.y + bar.implicitHeight + } + } + + HyprlandFocusGrab { + id: focusGrab + + active: visibilities.dock || visibilities.resources || visibilities.launcher || visibilities.sidebar || visibilities.dashboard || visibilities.settings || (panels.popouts.hasCurrent && panels.popouts.currentName.startsWith("traymenu")) + windows: [root] + + onCleared: { + visibilities.launcher = false; + visibilities.sidebar = false; + visibilities.dashboard = false; + visibilities.osd = false; + visibilities.settings = false; + visibilities.resources = false; + visibilities.dock = false; + panels.popouts.hasCurrent = false; + } + } + + PersistentProperties { + id: visibilities + + property bool bar + property bool dashboard + property bool dock + property bool isDrawing + property bool launcher + property bool notif: NotifServer.popups.length > 0 + property bool osd + property bool resources + property bool settings + property bool sidebar + + Component.onCompleted: Visibilities.load(root.screen, this) + } + + IpcHandler { + function toggleLauncher(fix: string): void { + visibilities.launcher = !visibilities.launcher; } - CustomWindow { - id: win + target: "visibilities" + } - readonly property bool hasFullscreen: Hypr.monitorFor(screen)?.activeWorkspace?.toplevels.values.some(t => t.lastIpcObject.fullscreen === 2) - property var root: Quickshell.shellDir + Binding { + property: "bar" + target: visibilities + value: visibilities.sidebar || visibilities.dashboard || visibilities.osd || (!Config.barConfig.hideWhenNotif && visibilities.notif) || visibilities.resources || visibilities.settings || bar.isHovered + when: Config.barConfig.autoHide + } - WlrLayershell.exclusionMode: ExclusionMode.Ignore - // WlrLayershell.keyboardFocus: visibilities.dock || visibilities.launcher || visibilities.sidebar || visibilities.dashboard || visibilities.settings || visibilities.resources ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None - color: "transparent" - contentItem.focus: true - mask: visibilities.isDrawing ? null : region - name: "Bar" - screen: scope.modelData + Item { + anchors.fill: parent + layer.enabled: true + opacity: Appearance.transparency.enabled ? DynamicColors.transparency.base : 1 - contentItem.Keys.onEscapePressed: { - if (Config.barConfig.autoHide) - visibilities.bar = false; - visibilities.sidebar = false; - visibilities.dashboard = false; - visibilities.osd = false; - visibilities.settings = false; - visibilities.resources = false; - } - onHasFullscreenChanged: { - visibilities.launcher = false; - visibilities.dashboard = false; - visibilities.osd = false; - visibilities.settings = false; - visibilities.resources = false; - } + layer.effect: MultiEffect { + blurMax: 32 + shadowColor: Qt.alpha(DynamicColors.palette.m3shadow, 1) + shadowEnabled: true + } - Region { - id: region + BlobGroup { + id: blobGroup - height: win.height - bar.implicitHeight - Config.barConfig.border - intersection: Intersection.Xor - regions: popoutRegions.instances - width: win.width - Config.barConfig.border * 2 - x: Config.barConfig.border - y: bar.implicitHeight - } + color: DynamicColors.palette.m3surface + smoothing: Config.barConfig.smoothing - anchors { - bottom: true - left: true - right: true - top: true - } - - Variants { - id: popoutRegions - - model: panels.children - - Region { - required property Item modelData - - height: modelData.height - intersection: Intersection.Subtract - width: modelData.width - x: modelData.x + Config.barConfig.border - y: modelData.y + bar.implicitHeight + Behavior on color { + CAnim { } } + } - HyprlandFocusGrab { - id: focusGrab + BlobInvertedRect { + anchors.fill: parent + anchors.margins: -50 + borderBottom: Config.barConfig.border - anchors.margins + borderLeft: Config.barConfig.border - anchors.margins + borderRight: Config.barConfig.border - anchors.margins + borderTop: bar.implicitHeight - anchors.margins + group: blobGroup + radius: Config.barConfig.rounding + } - active: visibilities.dock || visibilities.resources || visibilities.launcher || visibilities.sidebar || visibilities.dashboard || visibilities.settings || (panels.popouts.hasCurrent && panels.popouts.currentName.startsWith("traymenu")) - windows: [win] + PanelBg { + id: dashBg - onCleared: { - visibilities.launcher = false; - visibilities.sidebar = false; - visibilities.dashboard = false; - visibilities.osd = false; - visibilities.settings = false; - visibilities.resources = false; - visibilities.dock = false; - panels.popouts.hasCurrent = false; + property real extraHeight: 0.2 + + deformAmount: 0.06 + implicitHeight: panels.dashboard.height * (1 + extraHeight) + implicitWidth: panels.dashboard.width + panel: panels.dashboardWrapper + radius: Appearance.rounding.normal + x: panels.dashboardWrapper.x + panels.dashboard.x + Config.barConfig.border + y: panels.dashboardWrapper.y + panels.dashboard.y + bar.implicitHeight - panels.dashboard.height * extraHeight + } + + PanelBg { + id: launcherBg + + property real extraHeight: 0.2 + + deformAmount: 0.06 + implicitHeight: panels.launcher.height * (1 + extraHeight) + panel: panels.launcher + radius: Appearance.rounding.smallest + 5 + y: panels.launcher.y + bar.implicitHeight + } + + PanelBg { + id: sidebarBg + + bottomLeftRadius: 0 + deformAmount: 0.04 + exclude: panels.sidebar.offsetScale > 0.08 ? [] : [utilsBg] + implicitHeight: panel.height * (1 / rawDeformMatrix.m22) + 2 + panel: panels.sidebar + } + + PanelBg { + id: osdBg + + deformAmount: 0.1 + implicitHeight: panels.osd.height + implicitWidth: panels.osd.width + panel: panels.osdWrapper + radius: 20 + x: panels.osdWrapper.x + panels.osd.x + Config.barConfig.border + y: panels.osdWrapper.y + panels.osd.y + bar.implicitHeight + } + + PanelBg { + id: notifsBg + + panel: panels.notifications + radius: Appearance.rounding.normal + } + + PanelBg { + id: utilsBg + + deformAmount: panels.sidebar.visible ? (0.1) : (0.1) + exclude: panels.sidebar.offsetScale > 0.08 ? [] : [sidebarBg] + panel: panels.utilities + topLeftRadius: 0 + } + + PanelBg { + id: popoutBg + + property real extraHeight: panels.popouts.isDetached ? 0 : 0.2 + + deformAmount: panels.popouts.isDetached ? 0.05 : panels.popouts.hasCurrent ? 0.15 : 0.1 + implicitHeight: panels.popouts.height * (1 + extraHeight) + implicitWidth: panels.popouts.width + panel: panels.popoutsWrapper + radius: (panels.popouts.currentName.startsWith("audio") || panels.popouts.currentName.startsWith("updates")) ? Appearance.rounding.normal : 20 * Appearance.rounding.scale + x: panels.popoutsWrapper.x + panels.popouts.x + Config.barConfig.border + y: panels.popoutsWrapper.y + panels.popouts.y + bar.implicitHeight - panels.popouts.height * extraHeight + + Behavior on extraHeight { + Anim { } } + } - PersistentProperties { - id: visibilities + PanelBg { + id: resourcesBg - property bool bar - property bool dashboard - property bool dock - property bool isDrawing - property bool launcher - property bool notif: NotifServer.popups.length > 0 - property bool osd - property bool resources - property bool settings - property bool sidebar + deformAmount: 0.05 + implicitHeight: panels.resources.height + implicitWidth: panels.resources.width + panel: panels.resourcesWrapper + radius: Appearance.rounding.normal + x: panels.resourcesWrapper.x + panels.resources.x + Config.barConfig.border + y: panels.resourcesWrapper.y + panels.resources.y + bar.implicitHeight + } - Component.onCompleted: Visibilities.load(scope.modelData, this) + PanelBg { + id: settingsBg + + property real extraHeight: 0.2 + + deformAmount: 0.03 + implicitHeight: panels.settings.height * (1 + extraHeight) + implicitWidth: panels.settings.width + panel: panels.settings + radius: Appearance.rounding.large + topLeftRadius: Appearance.rounding.large + Appearance.padding.smaller + topRightRadius: Appearance.rounding.large + Appearance.padding.smaller + x: panels.settingsWrapper.x + panels.settings.x + Config.barConfig.border + y: panels.settingsWrapper.y + panels.settings.y + bar.implicitHeight - panels.settings.height * extraHeight + } + + PanelBg { + id: dockBg + + deformAmount: 0.08 + panel: panels.dock + radius: Appearance.rounding.normal + } + + PanelBg { + id: drawingBg + + deformAmount: 0.08 + panel: panels.drawing + radius: Appearance.rounding.normal + } + } + + Loader { + id: drawingLoader + + active: visibilities.isDrawing + anchors.fill: parent + z: 2 + + sourceComponent: Drawing { + id: drawing + } + } + + Loader { + id: inputLoader + + active: visibilities.isDrawing + anchors.fill: parent + z: 2 + + sourceComponent: DrawingInput { + id: input + + bar: bar + drawing: drawingLoader.item + panels: panels + popout: panels.drawing + visibilities: visibilities + } + } + + Interactions { + id: interactions + + anchors.fill: parent + bar: bar + drawing: drawingLoader.item + enabled: true + input: inputLoader.item + panels: panels + popouts: panels.popouts + screen: root.screen + visibilities: visibilities + z: 1 + + Panels { + id: panels + + bar: bar + drawingItem: drawingLoader.item + screen: root.screen + visibilities: visibilities + + dashboard.transform: Matrix4x4 { + matrix: dashBg.deformMatrix } - - IpcHandler { - function toggleLauncher(fix: string): void { - visibilities.launcher = !visibilities.launcher; - } - - target: "visibilities" + dock.transform: Matrix4x4 { + matrix: dockBg.deformMatrix } - - Binding { - property: "bar" - target: visibilities - value: visibilities.sidebar || visibilities.dashboard || visibilities.osd || (!Config.barConfig.hideWhenNotif && visibilities.notif) || visibilities.resources || visibilities.settings || bar.isHovered - when: Config.barConfig.autoHide + launcher.transform: Matrix4x4 { + matrix: launcherBg.deformMatrix } - - Item { - anchors.fill: parent - layer.enabled: true - opacity: Appearance.transparency.enabled ? DynamicColors.transparency.base : 1 - - layer.effect: MultiEffect { - blurMax: 32 - shadowColor: Qt.alpha(DynamicColors.palette.m3shadow, 1) - shadowEnabled: true - } - - BlobGroup { - id: blobGroup - - color: DynamicColors.palette.m3surface - smoothing: Config.barConfig.smoothing - - Behavior on color { - CAnim { - } - } - } - - BlobInvertedRect { - anchors.fill: parent - anchors.margins: -50 - borderBottom: Config.barConfig.border - anchors.margins - borderLeft: Config.barConfig.border - anchors.margins - borderRight: Config.barConfig.border - anchors.margins - borderTop: bar.implicitHeight - anchors.margins - group: blobGroup - radius: Config.barConfig.rounding - } - - PanelBg { - id: dashBg - - property real extraHeight: 0.2 - - deformAmount: 0.06 - implicitHeight: panels.dashboard.height * (1 + extraHeight) - implicitWidth: panels.dashboard.width - panel: panels.dashboardWrapper - radius: Appearance.rounding.normal - x: panels.dashboardWrapper.x + panels.dashboard.x + Config.barConfig.border - y: panels.dashboardWrapper.y + panels.dashboard.y + bar.implicitHeight - panels.dashboard.height * extraHeight - } - - PanelBg { - id: launcherBg - - property real extraHeight: 0.2 - - deformAmount: 0.06 - implicitHeight: panels.launcher.height * (1 + extraHeight) - panel: panels.launcher - radius: Appearance.rounding.smallest + 5 - y: panels.launcher.y + bar.implicitHeight - } - - PanelBg { - id: sidebarBg - - bottomLeftRadius: 0 - deformAmount: 0.04 - exclude: panels.sidebar.offsetScale > 0.08 ? [] : [utilsBg] - implicitHeight: panel.height * (1 / rawDeformMatrix.m22) + 2 - panel: panels.sidebar - } - - PanelBg { - id: osdBg - - deformAmount: 0.1 - implicitHeight: panels.osd.height - implicitWidth: panels.osd.width - panel: panels.osdWrapper - radius: 20 - x: panels.osdWrapper.x + panels.osd.x + Config.barConfig.border - y: panels.osdWrapper.y + panels.osd.y + bar.implicitHeight - } - - PanelBg { - id: notifsBg - - panel: panels.notifications - radius: Appearance.rounding.normal - } - - PanelBg { - id: utilsBg - - deformAmount: panels.sidebar.visible ? (0.1) : (0.1) - exclude: panels.sidebar.offsetScale > 0.08 ? [] : [sidebarBg] - panel: panels.utilities - topLeftRadius: 0 - } - - PanelBg { - id: popoutBg - - property real extraHeight: panels.popouts.isDetached ? 0 : 0.2 - - deformAmount: panels.popouts.isDetached ? 0.05 : panels.popouts.hasCurrent ? 0.15 : 0.1 - implicitHeight: panels.popouts.height * (1 + extraHeight) - implicitWidth: panels.popouts.width - panel: panels.popoutsWrapper - radius: (panels.popouts.currentName.startsWith("audio") || panels.popouts.currentName.startsWith("updates")) ? Appearance.rounding.normal : 20 * Appearance.rounding.scale - x: panels.popoutsWrapper.x + panels.popouts.x + Config.barConfig.border - y: panels.popoutsWrapper.y + panels.popouts.y + bar.implicitHeight - panels.popouts.height * extraHeight - - Behavior on extraHeight { - Anim { - } - } - } - - PanelBg { - id: resourcesBg - - deformAmount: 0.05 - implicitHeight: panels.resources.height - implicitWidth: panels.resources.width - panel: panels.resourcesWrapper - radius: Appearance.rounding.normal - x: panels.resourcesWrapper.x + panels.resources.x + Config.barConfig.border - y: panels.resourcesWrapper.y + panels.resources.y + bar.implicitHeight - } - - PanelBg { - id: settingsBg - - property real extraHeight: 0.2 - - deformAmount: 0.03 - implicitHeight: panels.settings.height * (1 + extraHeight) - implicitWidth: panels.settings.width - panel: panels.settings - radius: Appearance.rounding.large - topLeftRadius: Appearance.rounding.large + Appearance.padding.smaller - topRightRadius: Appearance.rounding.large + Appearance.padding.smaller - x: panels.settingsWrapper.x + panels.settings.x + Config.barConfig.border - y: panels.settingsWrapper.y + panels.settings.y + bar.implicitHeight - panels.settings.height * extraHeight - } - - PanelBg { - id: dockBg - - deformAmount: 0.08 - panel: panels.dock - radius: Appearance.rounding.normal - } - - PanelBg { - id: drawingBg - - deformAmount: 0.08 - panel: panels.drawing - radius: Appearance.rounding.normal - } + notifications.transform: Matrix4x4 { + matrix: notifsBg.deformMatrix } - - Loader { - id: drawingLoader - - active: visibilities.isDrawing - anchors.fill: parent - z: 2 - - sourceComponent: Drawing { - id: drawing - } + osd.transform: Matrix4x4 { + matrix: osdBg.deformMatrix } - - Loader { - id: inputLoader - - active: visibilities.isDrawing - anchors.fill: parent - z: 2 - - sourceComponent: DrawingInput { - id: input - - bar: bar - drawing: drawingLoader.item - panels: panels - popout: panels.drawing - visibilities: visibilities - } + popouts.transform: Matrix4x4 { + matrix: popoutBg.deformMatrix } - - Interactions { - id: mouseArea - - anchors.fill: parent - bar: bar - drawing: drawingLoader.item - enabled: true - input: inputLoader.item - panels: panels - popouts: panels.popouts - screen: scope.modelData - visibilities: visibilities - z: 1 - - Panels { - id: panels - - bar: bar - drawingItem: drawingLoader.item - screen: scope.modelData - visibilities: visibilities - - dashboard.transform: Matrix4x4 { - matrix: dashBg.deformMatrix - } - dock.transform: Matrix4x4 { - matrix: dockBg.deformMatrix - } - launcher.transform: Matrix4x4 { - matrix: launcherBg.deformMatrix - } - notifications.transform: Matrix4x4 { - matrix: notifsBg.deformMatrix - } - osd.transform: Matrix4x4 { - matrix: osdBg.deformMatrix - } - popouts.transform: Matrix4x4 { - matrix: popoutBg.deformMatrix - } - resources.transform: Matrix4x4 { - matrix: resourcesBg.deformMatrix - } - settings.transform: Matrix4x4 { - matrix: settingsBg.deformMatrix - } - sidebar.transform: Matrix4x4 { - matrix: sidebarBg.deformMatrix - } - utilities.transform: Matrix4x4 { - matrix: utilsBg.deformMatrix - } - } - - BarLoader { - id: bar - - anchors.left: parent.left - anchors.right: parent.right - popouts: panels.popouts - popoutsWrapper: panels.popoutsWrapper - screen: scope.modelData - visibilities: visibilities - } + resources.transform: Matrix4x4 { + matrix: resourcesBg.deformMatrix } + settings.transform: Matrix4x4 { + matrix: settingsBg.deformMatrix + } + sidebar.transform: Matrix4x4 { + matrix: sidebarBg.deformMatrix + } + utilities.transform: Matrix4x4 { + matrix: utilsBg.deformMatrix + } + } + + BarLoader { + id: bar + + anchors.left: parent.left + anchors.right: parent.right + popouts: panels.popouts + popoutsWrapper: panels.popoutsWrapper + screen: root.screen + visibilities: visibilities } } diff --git a/Modules/Settings/Categories/General.qml b/Modules/Settings/Categories/General.qml index 59ba5d2..46efcdc 100644 --- a/Modules/Settings/Categories/General.qml +++ b/Modules/Settings/Categories/General.qml @@ -62,6 +62,7 @@ SettingsPage { SettingsSection { sectionId: "Color" + z: 1 SettingsHeader { name: "Color" @@ -105,7 +106,6 @@ SettingsPage { active: root.schemeTypeItem(menuItems, Config.colors.schemeType) enabled: Config.general.color.schemeGeneration label: qsTr("Scheme type") - z: 2 menuItems: [ MenuItem { @@ -250,7 +250,6 @@ SettingsPage { SettingsSection { sectionId: "Default Apps" - z: -1 SettingsHeader { name: "Default Apps" diff --git a/shell.qml b/shell.qml index c5c5b7f..7482c32 100644 --- a/shell.qml +++ b/shell.qml @@ -22,7 +22,7 @@ ShellRoot { settings.watchFiles: true - Windows { + Drawers { } Wallpaper {