diff --git a/Drawers/Interactions.qml b/Drawers/Interactions.qml index 3371f0d..6d6ae56 100644 --- a/Drawers/Interactions.qml +++ b/Drawers/Interactions.qml @@ -72,9 +72,6 @@ CustomMouseArea { } } onPositionChanged: event => { - if (popouts.isDetached) - return; - const x = event.x; const y = event.y; const dragX = x - dragStart.x; diff --git a/Drawers/Panels.qml b/Drawers/Panels.qml index 6d09072..e23e3d3 100644 --- a/Drawers/Panels.qml +++ b/Drawers/Panels.qml @@ -26,7 +26,8 @@ Item { readonly property alias launcher: launcher readonly property alias notifications: notifications readonly property alias osd: osd - readonly property alias popouts: popouts + readonly property alias popouts: popouts.content + readonly property alias popoutsWrapper: popouts readonly property alias resources: resources required property ShellScreen screen readonly property alias settings: settings @@ -73,13 +74,6 @@ Item { anchors.top: parent.top screen: root.screen - x: { - const off = currentCenter - nonAnimWidth / 2; - const diff = root.width - Math.floor(off + nonAnimWidth); - if (diff < 0) - return off + diff; - return Math.floor(Math.max(off, 0)); - } } Toasts.Toasts { diff --git a/Drawers/Windows.qml b/Drawers/Windows.qml index 9cc51ee..48c329f 100644 --- a/Drawers/Windows.qml +++ b/Drawers/Windows.qml @@ -5,6 +5,7 @@ import QtQuick.Effects import Quickshell import Quickshell.Wayland import Quickshell.Hyprland +import ZShell.Blobs import qs.Daemons import qs.Components import qs.Modules @@ -161,7 +162,7 @@ Variants { borderBottom: Config.barConfig.border - anchors.margins borderLeft: Config.barConfig.border - anchors.margins borderRight: Config.barConfig.border - anchors.margins - borderTop: Config.barConfig.border - anchors.margins + borderTop: bar.implicitHeight - anchors.margins group: blobGroup radius: Config.barConfig.rounding } @@ -171,6 +172,7 @@ Variants { deformAmount: 0.1 panel: panels.dashboard + radius: Appearance.rounding.normal } PanelBg { @@ -178,12 +180,13 @@ Variants { deformAmount: 0.1 panel: panels.launcher + radius: Appearance.rounding.smallest + 5 } PanelBg { id: sidebarBg - bottomLeftRadius: Math.max(0, Math.min(1, panels.sidebar.offsetScale / 0.3)) * radius + bottomLeftRadius: 0 deformAmount: 0.03 exclude: panels.sidebar.offsetscale > 0.08 ? [] : [utilsBg] implicitHeight: panel.height * (1 / rawDeformMatrix.m22) + 2 @@ -195,6 +198,7 @@ Variants { deformAmount: 0.25 panel: panels.osd + radius: 20 } PanelBg { @@ -209,7 +213,7 @@ Variants { deformAmount: panels.sidebar.visible ? 0.1 : 0.15 exclude: panels.sidebar.offsetScale > 0.08 ? [] : [sidebarBg] panel: panels.utilities - topLeftRadius: Math.max(0, Math.min(1, panels.sidebar.offsetScale / 0.3)) * radius + topLeftRadius: 0 } PanelBg { @@ -217,7 +221,15 @@ Variants { deformAmount: 0.15 implicitWidth: panels.popouts.width - panel: panels.popouts + panel: panels.popoutsWrapper + } + + PanelBg { + id: resourcesBg + + deformAmount: 0.15 + panel: panels.resources + radius: Appearance.rounding.normal } } @@ -275,6 +287,9 @@ Variants { popouts.transform: Matrix4x4 { matrix: popoutBg.deformMatrix } + resources.transform: Matrix4x4 { + matrix: resourcesBg.deformMatrix + } sidebar.transform: Matrix4x4 { matrix: sidebarBg.deformMatrix } @@ -289,6 +304,7 @@ Variants { anchors.left: parent.left anchors.right: parent.right popouts: panels.popouts + popoutsWrapper: panels.popoutsWrapper screen: scope.modelData visibilities: visibilities } diff --git a/Modules/Bar/Bar.qml b/Modules/Bar/Bar.qml index 74459f4..9ac299b 100644 --- a/Modules/Bar/Bar.qml +++ b/Modules/Bar/Bar.qml @@ -16,6 +16,7 @@ RowLayout { id: root required property Wrapper popouts + required property ClipWrapper popoutsWrapper required property ShellScreen screen readonly property int vPadding: 6 required property PersistentProperties visibilities diff --git a/Modules/Bar/BarLoader.qml b/Modules/Bar/BarLoader.qml index 6c16698..b5e0d75 100644 --- a/Modules/Bar/BarLoader.qml +++ b/Modules/Bar/BarLoader.qml @@ -20,6 +20,7 @@ Item { property bool isHovered readonly property int padding: Math.max(Appearance.padding.smaller, Config.barConfig.border) required property Wrapper popouts + required property ClipWrapper popoutsWrapper required property ShellScreen screen readonly property bool shouldBeVisible: (!Config.barConfig.autoHide || visibilities.bar || isHovered) readonly property int vPadding: 6 @@ -76,6 +77,7 @@ Item { sourceComponent: Bar { height: root.contentHeight popouts: root.popouts + popoutsWrapper: root.popoutsWrapper screen: root.screen visibilities: root.visibilities } diff --git a/Modules/ClipWrapper.qml b/Modules/ClipWrapper.qml index 6919f57..df891e5 100644 --- a/Modules/ClipWrapper.qml +++ b/Modules/ClipWrapper.qml @@ -9,13 +9,20 @@ Item { id: root readonly property alias content: content - property real offsetScale: x > 0 || content.hasCurrent ? 0 : 1 + property real offsetScale: y > 0 || content.hasCurrent ? 0 : 1 required property ShellScreen screen clip: true - implicitHeight: content.implicitHeight - implicitWidth: content.implicitWidth * (1 - offsetScale) + implicitHeight: content.implicitHeight * (1 - offsetScale) + implicitWidth: content.implicitWidth visible: width > 0 && height > 0 + x: { + const off = content.currentCenter - content.nonAnimWidth / 2; + const diff = parent.width - Math.floor(off + content.nonAnimWidth); + if (diff < 0) + return off + diff; + return Math.floor(Math.max(off, 0)); + } Behavior on offsetScale { Anim { @@ -41,9 +48,9 @@ Item { Wrapper { id: content - anchors.left: parent.left - anchors.leftMargin: (-implicitWidth - 5) * root.offsetScale - anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: parent.top + anchors.topMargin: (-implicitHeight - 5) * root.offsetScale offsetScale: root.offsetScale screen: root.screen } diff --git a/Modules/Content.qml b/Modules/Content.qml index 1f17be3..9ab78a2 100644 --- a/Modules/Content.qml +++ b/Modules/Content.qml @@ -15,7 +15,7 @@ Item { readonly property Item current: currentPopout?.item ?? null readonly property Popout currentPopout: content.children.find(c => c.shouldBeActive) ?? null - required property Item wrapper + required property PopoutState popouts implicitHeight: (currentPopout?.implicitHeight ?? 0) + 5 * 2 implicitWidth: (currentPopout?.implicitWidth ?? 0) + 5 * 2 @@ -49,40 +49,31 @@ Item { Connections { function onHasCurrentChanged(): void { - if (root.wrapper.hasCurrent && trayMenu.shouldBeActive) { + if (root.popouts.hasCurrent && trayMenu.shouldBeActive) { trayMenu.sourceComponent = null; trayMenu.sourceComponent = trayMenuComponent; } } - target: root.wrapper + target: root.popouts } Component { id: trayMenuComponent TrayMenuPopout { - popouts: root.wrapper + popouts: root.popouts trayItem: trayMenu.modelData.menu } } } } - Popout { - name: "overview" - - sourceComponent: OverviewPopout { - screen: root.wrapper.screen - wrapper: root.wrapper - } - } - Popout { name: "upower" sourceComponent: UPowerPopout { - wrapper: root.wrapper + wrapper: root.popouts } } @@ -90,7 +81,7 @@ Item { name: "network" sourceComponent: NetworkPopout { - wrapper: root.wrapper + wrapper: root.popouts } } @@ -98,7 +89,7 @@ Item { name: "updates" sourceComponent: UpdatesPopout { - wrapper: root.wrapper + wrapper: root.popouts } } } @@ -107,7 +98,7 @@ Item { id: popout required property string name - readonly property bool shouldBeActive: root.wrapper.currentName === name + readonly property bool shouldBeActive: root.popouts.currentName === name active: false anchors.centerIn: parent diff --git a/Modules/PopoutState.qml b/Modules/PopoutState.qml new file mode 100644 index 0000000..a5df520 --- /dev/null +++ b/Modules/PopoutState.qml @@ -0,0 +1,8 @@ +import QtQuick + +QtObject { + property string currentName + property bool hasCurrent + + signal detachRequested(mode: string) +} diff --git a/Modules/SysTray/Popouts/TrayMenuPopout.qml b/Modules/SysTray/Popouts/TrayMenuPopout.qml index 41a7d1a..f8cea7f 100644 --- a/Modules/SysTray/Popouts/TrayMenuPopout.qml +++ b/Modules/SysTray/Popouts/TrayMenuPopout.qml @@ -1,18 +1,19 @@ pragma ComponentBehavior: Bound -import qs.Components -import qs.Config import Quickshell import Quickshell.Widgets import QtQuick import QtQuick.Controls import QtQuick.Effects +import qs.Components +import qs.Modules +import qs.Config StackView { id: root property int biggestWidth: 0 - required property Item popouts + required property PopoutState popouts property int rootWidth: 0 required property QsMenuHandle trayItem diff --git a/Modules/Wrapper.qml b/Modules/Wrapper.qml index 88a0f59..c51a360 100644 --- a/Modules/Wrapper.qml +++ b/Modules/Wrapper.qml @@ -11,19 +11,16 @@ Item { property list animCurve: Appearance.anim.curves.expressiveDefaultSpatial property int animLength: Appearance.anim.durations.expressiveDefaultSpatial readonly property alias content: content - readonly property alias controlCenter: controlCenter readonly property Item current: (content.item as Content)?.current ?? null property real currentCenter property alias currentName: popoutState.currentName property string detachedMode property alias hasCurrent: popoutState.hasCurrent - readonly property bool isDetached: detachedMode.length > 0 readonly property real nonAnimHeight: children.find(c => c.shouldBeActive)?.implicitHeight ?? content.implicitHeight readonly property real nonAnimWidth: children.find(c => c.shouldBeActive)?.implicitWidth ?? content.implicitWidth required property real offsetScale property string queuedMode required property ShellScreen screen - readonly property alias winfo: winfo function close(): void { hasCurrent = false; @@ -67,49 +64,14 @@ Item { } } - Keys.onEscapePressed: { - // Forward escape to password popout if active, otherwise close - if (currentName === "wirelesspassword" && content.item) { - const passwordPopout = (content.item as Content)?.children.find(c => c.name === "wirelesspassword"); - if (passwordPopout && passwordPopout.item) { - passwordPopout.item.closeDialog(); - return; - } - } - close(); - } - Keys.onPressed: event => { - // Don't intercept keys when password popout is active - let it handle them - if (currentName === "wirelesspassword") { - event.accepted = false; - } - } - PopoutState { id: popoutState - - onDetachRequested: mode => root.detach(mode) - } - - HyprlandFocusGrab { - active: root.isDetached - windows: [QsWindow.window] - - onCleared: root.close() - } - - Binding { - property: "WlrLayershell.keyboardFocus" - target: QsWindow.window - value: WlrKeyboardFocus.OnDemand - when: root.isDetached || (root.hasCurrent && root.currentName === "wirelesspassword") } Comp { id: content - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter + anchors.centerIn: parent shouldBeActive: root.hasCurrent && !root.detachedMode sourceComponent: Content { @@ -117,31 +79,31 @@ Item { } } - Comp { - id: winfo - - anchors.centerIn: parent - shouldBeActive: root.detachedMode === "winfo" - - sourceComponent: WindowInfo { - client: Hypr.activeToplevel - screen: root.screen - } - } - - Comp { - id: controlCenter - - anchors.centerIn: parent - shouldBeActive: root.detachedMode === "any" - - sourceComponent: ControlCenter { - active: root.queuedMode - screen: root.screen - - onClose: root.close() - } - } + // Comp { + // id: winfo + // + // anchors.centerIn: parent + // shouldBeActive: root.detachedMode === "winfo" + // + // sourceComponent: WindowInfo { + // client: Hypr.activeToplevel + // screen: root.screen + // } + // } + // + // Comp { + // id: controlCenter + // + // anchors.centerIn: parent + // shouldBeActive: root.detachedMode === "any" + // + // sourceComponent: ControlCenter { + // active: root.queuedMode + // screen: root.screen + // + // onClose: root.close() + // } + // } component Comp: Loader { id: comp