diff --git a/modules/bar/popouts/ClipWrapper.qml b/modules/bar/popouts/ClipWrapper.qml new file mode 100644 index 00000000..74dec841 --- /dev/null +++ b/modules/bar/popouts/ClipWrapper.qml @@ -0,0 +1,55 @@ +pragma ComponentBehavior: Bound + +import QtQuick +import Quickshell +import qs.components +import qs.config + +Item { + id: root + + required property ShellScreen screen + + readonly property alias content: content + property real offsetScale: x > 0 || content.hasCurrent ? 0 : 1 + + visible: width > 0 && height > 0 + clip: true + + implicitWidth: content.implicitWidth * (1 - offsetScale) + implicitHeight: content.implicitHeight + + Behavior on offsetScale { + Anim { + duration: Appearance.anim.durations.expressiveDefaultSpatial + easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial + } + } + + Behavior on x { + Anim { + duration: content.animLength + easing.bezierCurve: content.animCurve + } + } + + Behavior on y { + enabled: root.offsetScale < 1 + + Anim { + duration: content.animLength + easing.bezierCurve: content.animCurve + } + } + + Wrapper { + id: content + + screen: root.screen + offsetScale: root.offsetScale + + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: (-implicitWidth - 5) * root.offsetScale + } +} diff --git a/modules/bar/popouts/Wrapper.qml b/modules/bar/popouts/Wrapper.qml index 99440865..a04a5e8a 100644 --- a/modules/bar/popouts/Wrapper.qml +++ b/modules/bar/popouts/Wrapper.qml @@ -14,46 +14,50 @@ Item { id: root required property ShellScreen screen + required property real offsetScale - readonly property real shownWidth: children.find(c => c.shouldBeActive)?.implicitWidth ?? content.implicitWidth - readonly property real nonAnimWidth: x > 0 || hasCurrent ? shownWidth : 0 + readonly property alias content: content + readonly property alias winfo: winfo + readonly property alias controlCenter: controlCenter + + readonly property real nonAnimWidth: children.find(c => c.shouldBeActive)?.implicitWidth ?? content.implicitWidth readonly property real nonAnimHeight: children.find(c => c.shouldBeActive)?.implicitHeight ?? content.implicitHeight readonly property Item current: (content.item as Content)?.current ?? null + readonly property bool isDetached: detachedMode.length > 0 property alias currentName: popoutState.currentName - property real currentCenter property alias hasCurrent: popoutState.hasCurrent - readonly property PopoutState popState: popoutState + property real currentCenter property string detachedMode property string queuedMode - readonly property bool isDetached: detachedMode.length > 0 - property int animLength: Appearance.anim.durations.normal - property list animCurve: Appearance.anim.curves.emphasized + property int animLength: Appearance.anim.durations.expressiveDefaultSpatial + property list animCurve: Appearance.anim.curves.expressiveDefaultSpatial + + function setAnims(detach: bool): void { + const type = `expressive${detach ? "Slow" : "Default"}Spatial`; + animLength = Appearance.anim.durations[type]; + animCurve = Appearance.anim.curves[type]; + } function detach(mode: string): void { - animLength = Appearance.anim.durations.large; + setAnims(true); if (mode === "winfo") { detachedMode = mode; } else { queuedMode = mode; detachedMode = "any"; } + setAnims(false); focus = true; } function close(): void { hasCurrent = false; - animCurve = Appearance.anim.curves.emphasizedAccel; - animLength = Appearance.anim.durations.normal; detachedMode = ""; - animCurve = Appearance.anim.curves.emphasized; } - visible: width > 0 && height > 0 - clip: true - implicitWidth: nonAnimWidth implicitHeight: nonAnimHeight @@ -90,15 +94,7 @@ Item { } Binding { - when: root.isDetached - - target: QsWindow.window - property: "WlrLayershell.keyboardFocus" - value: WlrKeyboardFocus.OnDemand - } - - Binding { - when: root.hasCurrent && root.currentName === "wirelesspassword" + when: root.isDetached || (root.hasCurrent && root.currentName === "wirelesspassword") target: QsWindow.window property: "WlrLayershell.keyboardFocus" @@ -118,6 +114,8 @@ Item { } Comp { + id: winfo + shouldBeActive: root.detachedMode === "winfo" anchors.centerIn: parent @@ -128,32 +126,15 @@ Item { } Comp { + id: controlCenter + shouldBeActive: root.detachedMode === "any" anchors.centerIn: parent sourceComponent: ControlCenter { - function close(): void { - root.close(); - } - screen: root.screen active: root.queuedMode - } - } - - Behavior on x { - Anim { - duration: root.animLength - easing.bezierCurve: root.animCurve - } - } - - Behavior on y { - enabled: root.implicitWidth > 0 - - Anim { - duration: root.animLength - easing.bezierCurve: root.animCurve + onClose: root.close() } } @@ -165,7 +146,7 @@ Item { } Behavior on implicitHeight { - enabled: root.implicitWidth > 0 + enabled: root.offsetScale < 1 Anim { duration: root.animLength @@ -181,6 +162,7 @@ Item { active: false opacity: 0 + // Makes the loader load on the same frame shouldBeActive becomes true, which ensures size is set states: State { name: "active" when: comp.shouldBeActive diff --git a/modules/controlcenter/ControlCenter.qml b/modules/controlcenter/ControlCenter.qml index f542b597..5b067fc0 100644 --- a/modules/controlcenter/ControlCenter.qml +++ b/modules/controlcenter/ControlCenter.qml @@ -25,8 +25,7 @@ Item { root: root } - function close(): void { - } + signal close implicitWidth: implicitHeight * Config.controlCenter.sizes.ratio implicitHeight: screen.height * Config.controlCenter.sizes.heightMult diff --git a/modules/controlcenter/WindowFactory.qml b/modules/controlcenter/WindowFactory.qml index 266af909..dc0dc4a0 100644 --- a/modules/controlcenter/WindowFactory.qml +++ b/modules/controlcenter/WindowFactory.qml @@ -45,12 +45,9 @@ Singleton { ControlCenter { id: cc - function close(): void { - win.destroy(); - } - anchors.fill: parent screen: win.screen + onClose: win.destroy() floating: true } diff --git a/modules/drawers/ContentWindow.qml b/modules/drawers/ContentWindow.qml index cc09bbbd..f914be2d 100644 --- a/modules/drawers/ContentWindow.qml +++ b/modules/drawers/ContentWindow.qml @@ -211,23 +211,10 @@ StyledWindow { PanelBg { id: popoutBg - panel: panels.popouts - x: bar.implicitWidth - (panels.popouts.isDetached ? -(root.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 - } - } + panel: panels.popoutsWrapper + deformAmount: panels.popouts.isDetached ? 0.05 : panels.popouts.hasCurrent ? 0.15 : 0.1 + x: panels.popoutsWrapper.x + panels.popouts.x + bar.implicitWidth + implicitWidth: panels.popouts.width } } diff --git a/modules/drawers/Interactions.qml b/modules/drawers/Interactions.qml index aeabf401..ad17a0f2 100644 --- a/modules/drawers/Interactions.qml +++ b/modules/drawers/Interactions.qml @@ -211,7 +211,7 @@ CustomMouseArea { // Show popouts on hover if (x < bar.implicitWidth) { bar.checkPopout(y); - } else if ((!popouts.currentName.startsWith("traymenu") || ((popouts.current as StackView)?.depth ?? 0) <= 1) && !inLeftPanel(panels.popouts, x, y)) { + } else if ((!popouts.currentName.startsWith("traymenu") || ((popouts.current as StackView)?.depth ?? 0) <= 1) && !inLeftPanel(panels.popoutsWrapper, x, y)) { popouts.hasCurrent = false; bar.closeTray(); } diff --git a/modules/drawers/Panels.qml b/modules/drawers/Panels.qml index b018b94d..3cfabaab 100644 --- a/modules/drawers/Panels.qml +++ b/modules/drawers/Panels.qml @@ -28,13 +28,14 @@ Item { readonly property alias sessionWrapper: sessionWrapper readonly property alias launcher: launcher readonly property alias dashboard: dashboard - readonly property alias popouts: popouts + readonly property alias popouts: popoutsWrapper.content + readonly property alias popoutsWrapper: popoutsWrapper readonly property alias utilities: utilities readonly property alias toasts: toasts readonly property alias sidebar: sidebar anchors.fill: parent - anchors.margins: root.borderThickness + anchors.margins: borderThickness anchors.leftMargin: bar.implicitWidth Item { @@ -114,18 +115,18 @@ Item { anchors.top: parent.top } - BarPopouts.Wrapper { - id: popouts + BarPopouts.ClipWrapper { + id: popoutsWrapper screen: root.screen - x: isDetached ? (root.width - nonAnimWidth) / 2 : 0 + x: content.isDetached ? (root.width - content.nonAnimWidth) / 2 : 0 y: { - if (isDetached) - return (root.height - nonAnimHeight) / 2; + if (content.isDetached) + return (root.height - content.nonAnimHeight) / 2; - const off = currentCenter - root.borderThickness - nonAnimHeight / 2; - const diff = root.height - Math.floor(off + nonAnimHeight); + const off = content.currentCenter - root.borderThickness - content.nonAnimHeight / 2; + const diff = root.height - Math.floor(off + content.nonAnimHeight); if (diff < 0) return off + diff; return Math.max(off, 0); @@ -137,7 +138,7 @@ Item { visibilities: root.visibilities sidebar: sidebar - popouts: popouts + popouts: popoutsWrapper.content anchors.bottom: parent.bottom anchors.right: parent.right diff --git a/modules/drawers/Regions.qml b/modules/drawers/Regions.qml index c646809f..d4281762 100644 --- a/modules/drawers/Regions.qml +++ b/modules/drawers/Regions.qml @@ -65,7 +65,8 @@ Region { } R { - panel: root.panels.popouts + panel: root.panels.popoutsWrapper + width: panel.width * (1 - root.panels.popoutsWrapper.offsetScale) } component R: Region {