From 7a53bde9f46e2cee9ed9a0788cb7361acc3e134c Mon Sep 17 00:00:00 2001 From: bbedward Date: Fri, 17 Apr 2026 11:26:33 -0400 Subject: [PATCH] de-dupe and cleanup --- quickshell/Common/AnimVariants.qml | 175 +++---------- quickshell/Common/ConnectedModeState.qml | 194 +++++--------- quickshell/Common/ConnectorGeometry.js | 64 +++++ quickshell/Common/SettingsData.qml | 175 +++++++------ quickshell/Modals/Common/DankModal.qml | 2 + quickshell/Modules/Dock/Dock.qml | 49 +--- quickshell/Modules/Frame/Frame.qml | 1 - quickshell/Modules/Frame/FrameExclusions.qml | 46 ++-- quickshell/Modules/Frame/FrameInstance.qml | 1 - quickshell/Modules/Frame/FrameWindow.qml | 243 ++++-------------- .../Modules/Settings/TypographyMotionTab.qml | 10 +- quickshell/Widgets/ConnectedCorner.qml | 12 +- quickshell/Widgets/DankPopoutConnected.qml | 49 +--- 13 files changed, 343 insertions(+), 678 deletions(-) create mode 100644 quickshell/Common/ConnectorGeometry.js diff --git a/quickshell/Common/AnimVariants.qml b/quickshell/Common/AnimVariants.qml index 25c9edd7..44545001 100644 --- a/quickshell/Common/AnimVariants.qml +++ b/quickshell/Common/AnimVariants.qml @@ -5,121 +5,40 @@ import QtQuick import Quickshell import qs.Common -// AnimVariants — Central tuning for animation and Motion Effects variants -// (Material/Fluent/Dynamic) (Standard/Directional/Depth) +// AnimVariants — central tuning for animation variants (Material/Fluent/Dynamic) +// and motion effects (Standard/Directional/Depth). Lookups are indexed by enum +// value: animationVariant 0=Material, 1=Fluent, 2=Dynamic; motionEffect +// 0=Standard, 1=Directional, 2=Depth. Singleton { id: root - readonly property list variantEnterCurve: { - if (typeof SettingsData === "undefined") - return Anims.expressiveDefaultSpatial; - switch (SettingsData.animationVariant) { - case 1: - return Anims.standardDecel; - case 2: - return Anims.expressiveFastSpatial; - default: - return Anims.expressiveDefaultSpatial; - } - } + readonly property int _variant: (typeof SettingsData === "undefined") ? 0 : SettingsData.animationVariant + readonly property int _effect: (typeof SettingsData === "undefined") ? 0 : SettingsData.motionEffect - readonly property list variantExitCurve: { - if (typeof SettingsData === "undefined") - return Anims.emphasized; - switch (SettingsData.animationVariant) { - case 1: - return Anims.standard; - case 2: - return Anims.emphasized; - default: - return Anims.emphasized; - } - } + readonly property var _enterCurves: [Anims.expressiveDefaultSpatial, Anims.standardDecel, Anims.expressiveFastSpatial] + readonly property var _exitCurves: [Anims.emphasized, Anims.standard, Anims.emphasized] + readonly property var _directionalExitCurves: [Anims.emphasized, Anims.emphasizedAccel, Anims.emphasizedAccel] + readonly property var _enterDurationFactors: [1.0, 0.9, 1.08] + readonly property var _exitDurationFactors: [1.0, 0.85, 0.92] + readonly property var _cleanupPaddings: [50, 8, 24] + readonly property var _effectScaleCollapsed: [0.96, 1.0, 0.88] + readonly property var _effectAnimOffsets: [16, 144, 56] - // Modal-specific entry curve - readonly property list variantModalEnterCurve: { - if (typeof SettingsData === "undefined") - return Anims.expressiveDefaultSpatial; - if (isDirectionalEffect) { - if (SettingsData.animationVariant === 1) - return Anims.standardDecel; - if (SettingsData.animationVariant === 2) - return Anims.expressiveFastSpatial; - } - return variantEnterCurve; - } + readonly property list variantEnterCurve: _enterCurves[_variant] || _enterCurves[0] + readonly property list variantExitCurve: _exitCurves[_variant] || _exitCurves[0] - readonly property list variantModalExitCurve: { - if (typeof SettingsData === "undefined") - return Anims.emphasized; - if (isDirectionalEffect) { - if (SettingsData.animationVariant === 1) - return Anims.emphasizedAccel; - if (SettingsData.animationVariant === 2) - return Anims.emphasizedAccel; - } - return variantExitCurve; - } + readonly property list variantModalEnterCurve: isDirectionalEffect && _variant !== 0 ? (_enterCurves[_variant] || _enterCurves[0]) : variantEnterCurve + readonly property list variantModalExitCurve: isDirectionalEffect ? (_directionalExitCurves[_variant] || _exitCurves[0]) : variantExitCurve - // Popout-specific entry curve - readonly property list variantPopoutEnterCurve: { - if (typeof SettingsData === "undefined") - return Anims.expressiveDefaultSpatial; - if (isDirectionalEffect) { - if (SettingsData.animationVariant === 1) - return Anims.standardDecel; - if (SettingsData.animationVariant === 2) - return Anims.expressiveFastSpatial; - return Anims.standardDecel; - } - return variantEnterCurve; - } + readonly property list variantPopoutEnterCurve: isDirectionalEffect ? (_variant === 0 ? Anims.standardDecel : (_enterCurves[_variant] || _enterCurves[0])) : variantEnterCurve + readonly property list variantPopoutExitCurve: isDirectionalEffect ? (_directionalExitCurves[_variant] || _exitCurves[0]) : variantExitCurve - readonly property list variantPopoutExitCurve: { - if (typeof SettingsData === "undefined") - return Anims.emphasized; - if (isDirectionalEffect) { - if (SettingsData.animationVariant === 1) - return Anims.emphasizedAccel; - if (SettingsData.animationVariant === 2) - return Anims.emphasizedAccel; - } - return variantExitCurve; - } - - readonly property real variantEnterDurationFactor: { - if (typeof SettingsData === "undefined") - return 1.0; - switch (SettingsData.animationVariant) { - case 1: - return 0.9; - case 2: - return 1.08; - default: - return 1.0; - } - } - - readonly property real variantExitDurationFactor: { - if (typeof SettingsData === "undefined") - return 1.0; - switch (SettingsData.animationVariant) { - case 1: - return 0.85; - case 2: - return 0.92; - default: - return 1.0; - } - } + readonly property real variantEnterDurationFactor: _enterDurationFactors[_variant] !== undefined ? _enterDurationFactors[_variant] : 1.0 + readonly property real variantExitDurationFactor: _exitDurationFactors[_variant] !== undefined ? _exitDurationFactors[_variant] : 1.0 // Fluent: opacity at ~55% of duration; Material/Dynamic: 1:1 with position - readonly property real variantOpacityDurationScale: { - if (typeof SettingsData === "undefined") - return 1.0; - return SettingsData.animationVariant === 1 ? 0.55 : 1.0; - } + readonly property real variantOpacityDurationScale: _variant === 1 ? 0.55 : 1.0 function variantDuration(baseDuration, entering) { const factor = entering ? variantEnterDurationFactor : variantExitDurationFactor; @@ -127,53 +46,17 @@ Singleton { } function variantExitCleanupPadding() { - if (typeof SettingsData === "undefined") - return 50; - switch (SettingsData.motionEffect) { - case 1: - return 8; - case 2: - return 24; - default: - return 50; - } + return _cleanupPaddings[_effect] !== undefined ? _cleanupPaddings[_effect] : 50; } function variantCloseInterval(baseDuration) { return variantDuration(baseDuration, false) + variantExitCleanupPadding(); } - readonly property bool isDirectionalEffect: isConnectedEffect - || (typeof SettingsData !== "undefined" && SettingsData.motionEffect === 1) - readonly property bool isDepthEffect: typeof SettingsData !== "undefined" && SettingsData.motionEffect === 2 - readonly property bool isConnectedEffect: typeof SettingsData !== "undefined" - && SettingsData.frameEnabled - && SettingsData.motionEffect === 1 - && SettingsData.directionalAnimationMode === 3 + readonly property bool isDirectionalEffect: isConnectedEffect || _effect === 1 + readonly property bool isDepthEffect: _effect === 2 + readonly property bool isConnectedEffect: (typeof SettingsData !== "undefined") && SettingsData.frameEnabled && _effect === 1 && SettingsData.directionalAnimationMode === 3 - readonly property real effectScaleCollapsed: { - if (typeof SettingsData === "undefined") - return 0.96; - switch (SettingsData.motionEffect) { - case 1: - return 1.0; - case 2: - return 0.88; - default: - return 0.96; - } - } - - readonly property real effectAnimOffset: { - if (typeof SettingsData === "undefined") - return 16; - switch (SettingsData.motionEffect) { - case 1: - return 144; - case 2: - return 56; - default: - return 16; - } - } + readonly property real effectScaleCollapsed: _effectScaleCollapsed[_effect] !== undefined ? _effectScaleCollapsed[_effect] : 0.96 + readonly property real effectAnimOffset: _effectAnimOffsets[_effect] !== undefined ? _effectAnimOffsets[_effect] : 16 } diff --git a/quickshell/Common/ConnectedModeState.qml b/quickshell/Common/ConnectedModeState.qml index d00a3b4f..7e63bea3 100644 --- a/quickshell/Common/ConnectedModeState.qml +++ b/quickshell/Common/ConnectedModeState.qml @@ -38,6 +38,13 @@ Singleton { // Dock slide offsets — hot-path updates separated from full geometry state property var dockSlides: ({}) + function _cloneDict(src) { + const next = {}; + for (const k in src) + next[k] = src[k]; + return next; + } + function hasPopoutOwner(claimId) { return !!claimId && popoutOwnerId === claimId; } @@ -141,13 +148,6 @@ Singleton { return true; } - function _cloneDockStates() { - const next = {}; - for (const screenName in dockStates) - next[screenName] = dockStates[screenName]; - return next; - } - function _normalizeDockState(state) { return { "reveal": !!(state && state.reveal), @@ -165,7 +165,7 @@ Singleton { if (!screenName || !state) return false; - const next = _cloneDockStates(); + const next = _cloneDict(dockStates); next[screenName] = _normalizeDockState(state); dockStates = next; return true; @@ -175,15 +175,13 @@ Singleton { if (!screenName || !dockStates[screenName]) return false; - const next = _cloneDockStates(); + const next = _cloneDict(dockStates); delete next[screenName]; dockStates = next; // Also clear corresponding slide if (dockSlides[screenName]) { - const nextSlides = {}; - for (const k in dockSlides) - nextSlides[k] = dockSlides[k]; + const nextSlides = _cloneDict(dockSlides); delete nextSlides[screenName]; dockSlides = nextSlides; } @@ -193,10 +191,11 @@ Singleton { function setDockSlide(screenName, x, y) { if (!screenName) return false; - const next = {}; - for (const k in dockSlides) - next[k] = dockSlides[k]; - next[screenName] = { "x": Number(x), "y": Number(y) }; + const next = _cloneDict(dockSlides); + next[screenName] = { + "x": Number(x), + "y": Number(y) + }; dockSlides = next; return true; } @@ -204,25 +203,18 @@ Singleton { // ─── Notification state (per screen, updated by NotificationSurface) ────── readonly property var emptyNotificationState: ({ - "visible": false, - "barSide": "top", - "bodyX": 0, - "bodyY": 0, - "bodyW": 0, - "bodyH": 0, - "omitStartConnector": false, - "omitEndConnector": false - }) + "visible": false, + "barSide": "top", + "bodyX": 0, + "bodyY": 0, + "bodyW": 0, + "bodyH": 0, + "omitStartConnector": false, + "omitEndConnector": false + }) property var notificationStates: ({}) - function _cloneNotificationStates() { - const next = {}; - for (const screenName in notificationStates) - next[screenName] = notificationStates[screenName]; - return next; - } - function _normalizeNotificationState(state) { return { "visible": !!(state && state.visible), @@ -239,20 +231,13 @@ Singleton { function _sameNotificationGeometry(a, b) { if (!a || !b) return false; - return Math.abs(Number(a.bodyX) - Number(b.bodyX)) < 0.5 - && Math.abs(Number(a.bodyY) - Number(b.bodyY)) < 0.5 - && Math.abs(Number(a.bodyW) - Number(b.bodyW)) < 0.5 - && Math.abs(Number(a.bodyH) - Number(b.bodyH)) < 0.5; + return Math.abs(Number(a.bodyX) - Number(b.bodyX)) < 0.5 && Math.abs(Number(a.bodyY) - Number(b.bodyY)) < 0.5 && Math.abs(Number(a.bodyW) - Number(b.bodyW)) < 0.5 && Math.abs(Number(a.bodyH) - Number(b.bodyH)) < 0.5; } function _sameNotificationState(a, b) { if (!a || !b) return false; - return a.visible === b.visible - && a.barSide === b.barSide - && a.omitStartConnector === b.omitStartConnector - && a.omitEndConnector === b.omitEndConnector - && _sameNotificationGeometry(a, b); + return a.visible === b.visible && a.barSide === b.barSide && a.omitStartConnector === b.omitStartConnector && a.omitEndConnector === b.omitEndConnector && _sameNotificationGeometry(a, b); } function setNotificationState(screenName, state) { @@ -263,7 +248,7 @@ Singleton { if (_sameNotificationState(notificationStates[screenName], normalized)) return true; - const next = _cloneNotificationStates(); + const next = _cloneDict(notificationStates); next[screenName] = normalized; notificationStates = next; return true; @@ -273,7 +258,7 @@ Singleton { if (!screenName || !notificationStates[screenName]) return false; - const next = _cloneNotificationStates(); + const next = _cloneDict(notificationStates); delete next[screenName]; notificationStates = next; return true; @@ -281,27 +266,20 @@ Singleton { // DankModal / DankLauncherV2Modal State readonly property var emptyModalState: ({ - "visible": false, - "barSide": "bottom", - "bodyX": 0, - "bodyY": 0, - "bodyW": 0, - "bodyH": 0, - "animX": 0, - "animY": 0, - "omitStartConnector": false, - "omitEndConnector": false - }) + "visible": false, + "barSide": "bottom", + "bodyX": 0, + "bodyY": 0, + "bodyW": 0, + "bodyH": 0, + "animX": 0, + "animY": 0, + "omitStartConnector": false, + "omitEndConnector": false + }) property var modalStates: ({}) - function _cloneModalStates() { - const next = {}; - for (const screenName in modalStates) - next[screenName] = modalStates[screenName]; - return next; - } - function _normalizeModalState(state) { return { "visible": !!(state && state.visible), @@ -320,22 +298,13 @@ Singleton { function _sameModalGeometry(a, b) { if (!a || !b) return false; - return Math.abs(Number(a.bodyX) - Number(b.bodyX)) < 0.5 - && Math.abs(Number(a.bodyY) - Number(b.bodyY)) < 0.5 - && Math.abs(Number(a.bodyW) - Number(b.bodyW)) < 0.5 - && Math.abs(Number(a.bodyH) - Number(b.bodyH)) < 0.5 - && Math.abs(Number(a.animX) - Number(b.animX)) < 0.5 - && Math.abs(Number(a.animY) - Number(b.animY)) < 0.5; + return Math.abs(Number(a.bodyX) - Number(b.bodyX)) < 0.5 && Math.abs(Number(a.bodyY) - Number(b.bodyY)) < 0.5 && Math.abs(Number(a.bodyW) - Number(b.bodyW)) < 0.5 && Math.abs(Number(a.bodyH) - Number(b.bodyH)) < 0.5 && Math.abs(Number(a.animX) - Number(b.animX)) < 0.5 && Math.abs(Number(a.animY) - Number(b.animY)) < 0.5; } function _sameModalState(a, b) { if (!a || !b) return false; - return a.visible === b.visible - && a.barSide === b.barSide - && a.omitStartConnector === b.omitStartConnector - && a.omitEndConnector === b.omitEndConnector - && _sameModalGeometry(a, b); + return a.visible === b.visible && a.barSide === b.barSide && a.omitStartConnector === b.omitStartConnector && a.omitEndConnector === b.omitEndConnector && _sameModalGeometry(a, b); } function setModalState(screenName, state) { @@ -346,7 +315,7 @@ Singleton { if (_sameModalState(modalStates[screenName], normalized)) return true; - const next = _cloneModalStates(); + const next = _cloneDict(modalStates); next[screenName] = normalized; modalStates = next; return true; @@ -356,71 +325,46 @@ Singleton { if (!screenName || !modalStates[screenName]) return false; - const next = _cloneModalStates(); + const next = _cloneDict(modalStates); delete next[screenName]; modalStates = next; return true; } function setModalAnim(screenName, animX, animY) { - if (!screenName) - return false; - const cur = modalStates[screenName]; + const cur = screenName ? modalStates[screenName] : null; if (!cur) return false; - let changed = false; - const nextAnimX = animX !== undefined ? Number(animX) : cur.animX; - const nextAnimY = animY !== undefined ? Number(animY) : cur.animY; - if (Math.abs(nextAnimX - cur.animX) >= 0.5 || Math.abs(nextAnimY - cur.animY) >= 0.5) { - const updated = { - "visible": cur.visible, - "barSide": cur.barSide, - "bodyX": cur.bodyX, - "bodyY": cur.bodyY, - "bodyW": cur.bodyW, - "bodyH": cur.bodyH, - "animX": nextAnimX, - "animY": nextAnimY, - "omitStartConnector": cur.omitStartConnector, - "omitEndConnector": cur.omitEndConnector - }; - const next = _cloneModalStates(); - next[screenName] = updated; - modalStates = next; - changed = true; - } - return changed; + const nax = animX !== undefined ? Number(animX) : cur.animX; + const nay = animY !== undefined ? Number(animY) : cur.animY; + if (Math.abs(nax - cur.animX) < 0.5 && Math.abs(nay - cur.animY) < 0.5) + return false; + const next = _cloneDict(modalStates); + next[screenName] = Object.assign({}, cur, { + "animX": nax, + "animY": nay + }); + modalStates = next; + return true; } function setModalBody(screenName, bodyX, bodyY, bodyW, bodyH) { - if (!screenName) - return false; - const cur = modalStates[screenName]; + const cur = screenName ? modalStates[screenName] : null; if (!cur) return false; const nx = bodyX !== undefined ? Number(bodyX) : cur.bodyX; const ny = bodyY !== undefined ? Number(bodyY) : cur.bodyY; const nw = bodyW !== undefined ? Number(bodyW) : cur.bodyW; const nh = bodyH !== undefined ? Number(bodyH) : cur.bodyH; - if (Math.abs(nx - cur.bodyX) < 0.5 - && Math.abs(ny - cur.bodyY) < 0.5 - && Math.abs(nw - cur.bodyW) < 0.5 - && Math.abs(nh - cur.bodyH) < 0.5) + if (Math.abs(nx - cur.bodyX) < 0.5 && Math.abs(ny - cur.bodyY) < 0.5 && Math.abs(nw - cur.bodyW) < 0.5 && Math.abs(nh - cur.bodyH) < 0.5) return false; - const updated = { - "visible": cur.visible, - "barSide": cur.barSide, + const next = _cloneDict(modalStates); + next[screenName] = Object.assign({}, cur, { "bodyX": nx, "bodyY": ny, "bodyW": nw, - "bodyH": nh, - "animX": cur.animX, - "animY": cur.animY, - "omitStartConnector": cur.omitStartConnector, - "omitEndConnector": cur.omitEndConnector - }; - const next = _cloneModalStates(); - next[screenName] = updated; + "bodyH": nh + }); modalStates = next; return true; } @@ -429,21 +373,17 @@ Singleton { property var dockRetractRequests: ({}) - function _cloneRetractRequests() { - const next = {}; - for (const k in dockRetractRequests) - next[k] = dockRetractRequests[k]; - return next; - } - function requestDockRetract(requesterId, screenName, side) { if (!requesterId || !screenName || !side) return false; const existing = dockRetractRequests[requesterId]; if (existing && existing.screenName === screenName && existing.side === side) return true; - const next = _cloneRetractRequests(); - next[requesterId] = { "screenName": screenName, "side": side }; + const next = _cloneDict(dockRetractRequests); + next[requesterId] = { + "screenName": screenName, + "side": side + }; dockRetractRequests = next; return true; } @@ -451,7 +391,7 @@ Singleton { function releaseDockRetract(requesterId) { if (!requesterId || !dockRetractRequests[requesterId]) return false; - const next = _cloneRetractRequests(); + const next = _cloneDict(dockRetractRequests); delete next[requesterId]; dockRetractRequests = next; return true; diff --git a/quickshell/Common/ConnectorGeometry.js b/quickshell/Common/ConnectorGeometry.js new file mode 100644 index 00000000..9116f451 --- /dev/null +++ b/quickshell/Common/ConnectorGeometry.js @@ -0,0 +1,64 @@ +.pragma library + +// Geometry for connected-frame arc connectors. +// `barSide` is one of "top" | "bottom" | "left" | "right" — the edge where the +// host bar/dock sits. `placement` is "left" (start) or "right" (end) of the +// body's far edge. `radius` is the connector's arc radius. `spacing` is the +// gap between the host edge and the body. + +function isVertical(barSide) { + return barSide === "left" || barSide === "right"; +} + +function connectorWidth(barSide, spacing, radius) { + return isVertical(barSide) ? (spacing + radius) : radius; +} + +function connectorHeight(barSide, spacing, radius) { + return isVertical(barSide) ? radius : (spacing + radius); +} + +function seamX(barSide, baseX, bodyWidth, placement) { + if (!isVertical(barSide)) + return placement === "left" ? baseX : baseX + bodyWidth; + return barSide === "left" ? baseX : baseX + bodyWidth; +} + +function seamY(barSide, baseY, bodyHeight, placement) { + if (barSide === "top") + return baseY; + if (barSide === "bottom") + return baseY + bodyHeight; + return placement === "left" ? baseY : baseY + bodyHeight; +} + +function connectorX(barSide, baseX, bodyWidth, placement, spacing, radius) { + var s = seamX(barSide, baseX, bodyWidth, placement); + var w = connectorWidth(barSide, spacing, radius); + if (!isVertical(barSide)) + return placement === "left" ? s - w : s; + return barSide === "left" ? s : s - w; +} + +function connectorY(barSide, baseY, bodyHeight, placement, spacing, radius) { + var s = seamY(barSide, baseY, bodyHeight, placement); + var h = connectorHeight(barSide, spacing, radius); + if (barSide === "top") + return s; + if (barSide === "bottom") + return s - h; + return placement === "left" ? s - h : s; +} + +// Which corner of the connector's bounding rect hosts the concave arc that +// carves into the body. Used for arc-sweep orientation. +function arcCorner(barSide, placement) { + var left = placement === "left"; + if (barSide === "top") + return left ? "bottomLeft" : "bottomRight"; + if (barSide === "bottom") + return left ? "topLeft" : "topRight"; + if (barSide === "left") + return left ? "topRight" : "bottomRight"; + return left ? "topLeft" : "bottomLeft"; +} diff --git a/quickshell/Common/SettingsData.qml b/quickshell/Common/SettingsData.qml index 0ab9ec6b..7379fd68 100644 --- a/quickshell/Common/SettingsData.qml +++ b/quickshell/Common/SettingsData.qml @@ -248,25 +248,21 @@ Singleton { onPreviousDirectionalModeChanged: saveSettings() property var connectedFrameBarStyleBackups: ({}) onConnectedFrameBarStyleBackupsChanged: saveSettings() - readonly property bool connectedFrameModeActive: frameEnabled - && motionEffect === SettingsData.AnimationEffect.Directional - && directionalAnimationMode === 3 + readonly property bool connectedFrameModeActive: frameEnabled && motionEffect === SettingsData.AnimationEffect.Directional && directionalAnimationMode === 3 onConnectedFrameModeActiveChanged: { if (_loading) return; - if (connectedFrameModeActive) { - _captureConnectedFrameBarStyleBackups(barConfigs, true); - _enforceConnectedModeBarStyleReset(); - } else { - _restoreConnectedFrameBarStyleBackups(); - } + _reconcileConnectedFrameBarStyles(); } readonly property color effectiveFrameColor: { const fc = frameColor; - if (!fc || fc === "default") return Theme.surfaceContainer; - if (fc === "primary") return Theme.primary; - if (fc === "surface") return Theme.surface; + if (!fc || fc === "default") + return Theme.surfaceContainer; + if (fc === "primary") + return Theme.primary; + if (fc === "surface") + return Theme.surface; return fc; } @@ -1557,43 +1553,8 @@ Singleton { updateBarConfigs(); } - function _reconcileConnectedFrameBarStyles() { - if (connectedFrameModeActive) { - if (!_hasConnectedFrameBarStyleBackups()) - _captureConnectedFrameBarStyleBackups(barConfigs, true); - _enforceConnectedModeBarStyleReset(); - return; - } - _restoreConnectedFrameBarStyleBackups(); - } - - function _sanitizeBarConfigForConnectedFrame(config) { - if (!connectedFrameModeActive || !config) - return config; - - let changed = false; - const sanitized = Object.assign({}, config); - - if ((sanitized.shadowIntensity ?? 0) !== 0) { - sanitized.shadowIntensity = 0; - changed = true; - } - if (sanitized.squareCorners ?? false) { - sanitized.squareCorners = false; - changed = true; - } - if (sanitized.gothCornersEnabled ?? false) { - sanitized.gothCornersEnabled = false; - changed = true; - } - if (sanitized.borderEnabled ?? false) { - sanitized.borderEnabled = false; - changed = true; - } - - return changed ? sanitized : config; - } - + // Zeroes out connected-mode-hostile fields (shadow, square/goth corners, border). + // Returns { configs, changed } — `configs` is the same ref when no change. function _sanitizeBarConfigsForConnectedFrame(configs) { if (!connectedFrameModeActive || !Array.isArray(configs)) return { @@ -1601,26 +1562,53 @@ Singleton { "changed": false }; - let changed = false; - const sanitizedConfigs = configs.map(config => { - const sanitized = _sanitizeBarConfigForConnectedFrame(config); - if (sanitized !== config) - changed = true; - return sanitized; + let anyChanged = false; + const out = configs.map(cfg => { + if (!cfg) + return cfg; + let dirty = false; + const s = Object.assign({}, cfg); + if ((s.shadowIntensity ?? 0) !== 0) { + s.shadowIntensity = 0; + dirty = true; + } + if (s.squareCorners ?? false) { + s.squareCorners = false; + dirty = true; + } + if (s.gothCornersEnabled ?? false) { + s.gothCornersEnabled = false; + dirty = true; + } + if (s.borderEnabled ?? false) { + s.borderEnabled = false; + dirty = true; + } + if (dirty) + anyChanged = true; + return dirty ? s : cfg; }); - return { - "configs": changed ? sanitizedConfigs : configs, - "changed": changed + "configs": anyChanged ? out : configs, + "changed": anyChanged }; } - function _enforceConnectedModeBarStyleReset() { - const result = _sanitizeBarConfigsForConnectedFrame(barConfigs); - if (!result.changed) + // Single entry point for connected-mode bar-style state. + // active → capture backups (if not yet) and sanitize bar configs + // !active → restore backups + function _reconcileConnectedFrameBarStyles() { + if (!connectedFrameModeActive) { + _restoreConnectedFrameBarStyleBackups(); return; - barConfigs = result.configs; - updateBarConfigs(); + } + if (!_hasConnectedFrameBarStyleBackups()) + _captureConnectedFrameBarStyleBackups(barConfigs, true); + const result = _sanitizeBarConfigsForConnectedFrame(barConfigs); + if (result.changed) { + barConfigs = result.configs; + updateBarConfigs(); + } } function detectAvailableIconThemes() { @@ -2185,54 +2173,77 @@ Singleton { } function getActiveBarEdgeForScreen(screen) { - if (!screen) return ""; + if (!screen) + return ""; for (var i = 0; i < barConfigs.length; i++) { var bc = barConfigs[i]; - if (!bc.enabled) continue; + if (!bc.enabled) + continue; var prefs = bc.screenPreferences || ["all"]; - if (!prefs.includes("all") && !isScreenInPreferences(screen, prefs)) continue; + if (!prefs.includes("all") && !isScreenInPreferences(screen, prefs)) + continue; switch (bc.position ?? 0) { - case SettingsData.Position.Top: return "top"; - case SettingsData.Position.Bottom: return "bottom"; - case SettingsData.Position.Left: return "left"; - case SettingsData.Position.Right: return "right"; + case SettingsData.Position.Top: + return "top"; + case SettingsData.Position.Bottom: + return "bottom"; + case SettingsData.Position.Left: + return "left"; + case SettingsData.Position.Right: + return "right"; } } return ""; } function getActiveBarEdgesForScreen(screen) { - if (!screen) return []; + if (!screen) + return []; var edges = []; for (var i = 0; i < barConfigs.length; i++) { var bc = barConfigs[i]; - if (!bc.enabled) continue; + if (!bc.enabled) + continue; var prefs = bc.screenPreferences || ["all"]; - if (!prefs.includes("all") && !isScreenInPreferences(screen, prefs)) continue; + if (!prefs.includes("all") && !isScreenInPreferences(screen, prefs)) + continue; switch (bc.position ?? 0) { - case SettingsData.Position.Top: edges.push("top"); break; - case SettingsData.Position.Bottom: edges.push("bottom"); break; - case SettingsData.Position.Left: edges.push("left"); break; - case SettingsData.Position.Right: edges.push("right"); break; + case SettingsData.Position.Top: + edges.push("top"); + break; + case SettingsData.Position.Bottom: + edges.push("bottom"); + break; + case SettingsData.Position.Left: + edges.push("left"); + break; + case SettingsData.Position.Right: + edges.push("right"); + break; } } return edges; } function frameEdgeInsetForSide(screen, side) { - if (!frameEnabled || !screen) return 0; + if (!frameEnabled || !screen) + return 0; const edges = getActiveBarEdgesForScreen(screen); return edges.includes(side) ? frameBarSize : frameThickness; } function getActiveBarThicknessForScreen(screen) { - if (frameEnabled) return frameBarSize; - if (!screen) return frameThickness; + if (frameEnabled) + return frameBarSize; + if (!screen) + return frameThickness; for (var i = 0; i < barConfigs.length; i++) { var bc = barConfigs[i]; - if (!bc.enabled) continue; + if (!bc.enabled) + continue; var prefs = bc.screenPreferences || ["all"]; - if (!prefs.includes("all") && !isScreenInPreferences(screen, prefs)) continue; + if (!prefs.includes("all") && !isScreenInPreferences(screen, prefs)) + continue; const innerPadding = bc.innerPadding ?? 4; const barT = Math.max(26 + innerPadding * 0.6, Theme.barHeight - 4 - (8 - innerPadding)); const spacing = bc.spacing ?? 4; diff --git a/quickshell/Modals/Common/DankModal.qml b/quickshell/Modals/Common/DankModal.qml index 69b9030a..350ab06f 100644 --- a/quickshell/Modals/Common/DankModal.qml +++ b/quickshell/Modals/Common/DankModal.qml @@ -1,9 +1,11 @@ import QtQuick import qs.Common +import qs.Services Item { id: root + readonly property bool useHyprlandFocusGrab: CompositorService.useHyprlandFocusGrab property string layerNamespace: "dms:modal" property Component content: null property Item directContent: null diff --git a/quickshell/Modules/Dock/Dock.qml b/quickshell/Modules/Dock/Dock.qml index 75eca5a7..9f65a6b2 100644 --- a/quickshell/Modules/Dock/Dock.qml +++ b/quickshell/Modules/Dock/Dock.qml @@ -145,46 +145,6 @@ Variants { return Math.round(v * _dpr) / _dpr; } - function connectorWidth(spacing) { - return dock.isVertical ? (spacing + Theme.connectedCornerRadius) : Theme.connectedCornerRadius; - } - - function connectorHeight(spacing) { - return dock.isVertical ? Theme.connectedCornerRadius : (spacing + Theme.connectedCornerRadius); - } - - function connectorSeamX(baseX, bodyWidth, placement) { - if (!dock.isVertical) - return placement === "left" ? baseX : baseX + bodyWidth; - return SettingsData.dockPosition === SettingsData.Position.Left ? baseX : baseX + bodyWidth; - } - - function connectorSeamY(baseY, bodyHeight, placement) { - if (SettingsData.dockPosition === SettingsData.Position.Top) - return baseY; - if (SettingsData.dockPosition === SettingsData.Position.Bottom) - return baseY + bodyHeight; - return placement === "left" ? baseY : baseY + bodyHeight; - } - - function connectorX(baseX, bodyWidth, placement, spacing) { - const seamX = connectorSeamX(baseX, bodyWidth, placement); - const width = connectorWidth(spacing); - if (!dock.isVertical) - return placement === "left" ? seamX - width : seamX; - return SettingsData.dockPosition === SettingsData.Position.Left ? seamX : seamX - width; - } - - function connectorY(baseY, bodyHeight, placement, spacing) { - const seamY = connectorSeamY(baseY, bodyHeight, placement); - const height = connectorHeight(spacing); - if (SettingsData.dockPosition === SettingsData.Position.Top) - return seamY; - if (SettingsData.dockPosition === SettingsData.Position.Bottom) - return seamY - height; - return placement === "left" ? seamY - height : seamY; - } - // ─── ConnectedModeState sync ──────────────────────────────────────── // Dock window origin in screen-relative coordinates (FrameWindow space). function _dockWindowOriginX() { @@ -384,7 +344,8 @@ Variants { // Flip `reveal` false when a modal claims this edge; reuses the slide animation readonly property bool _modalRetractActive: { - if (!dock._dockScreenName) return false; + if (!dock._dockScreenName) + return false; return ConnectedModeState.dockRetractActiveForSide(dock._dockScreenName, dock.connectedBarSide); } @@ -689,7 +650,8 @@ Variants { duration: Theme.isConnectedEffect ? Theme.variantDuration(Theme.popoutAnimationDuration, dock.reveal) : Theme.shortDuration easing.type: Theme.isConnectedEffect ? Easing.BezierSpline : Easing.OutCubic easing.bezierCurve: Theme.isConnectedEffect ? (dock.reveal ? Theme.variantPopoutEnterCurve : Theme.variantPopoutExitCurve) : [] - onRunningChanged: if (!running) dock._syncDockChromeState() + onRunningChanged: if (!running) + dock._syncDockChromeState() } } @@ -699,7 +661,8 @@ Variants { duration: Theme.isConnectedEffect ? Theme.variantDuration(Theme.popoutAnimationDuration, dock.reveal) : Theme.shortDuration easing.type: Theme.isConnectedEffect ? Easing.BezierSpline : Easing.OutCubic easing.bezierCurve: Theme.isConnectedEffect ? (dock.reveal ? Theme.variantPopoutEnterCurve : Theme.variantPopoutExitCurve) : [] - onRunningChanged: if (!running) dock._syncDockChromeState() + onRunningChanged: if (!running) + dock._syncDockChromeState() } } diff --git a/quickshell/Modules/Frame/Frame.qml b/quickshell/Modules/Frame/Frame.qml index b84b3c37..735a4cd7 100644 --- a/quickshell/Modules/Frame/Frame.qml +++ b/quickshell/Modules/Frame/Frame.qml @@ -2,7 +2,6 @@ pragma ComponentBehavior: Bound import QtQuick import Quickshell -import qs.Common Variants { id: root diff --git a/quickshell/Modules/Frame/FrameExclusions.qml b/quickshell/Modules/Frame/FrameExclusions.qml index fed46062..0ca1449b 100644 --- a/quickshell/Modules/Frame/FrameExclusions.qml +++ b/quickshell/Modules/Frame/FrameExclusions.qml @@ -23,40 +23,40 @@ Scope { Loader { active: root.screenEnabled && !root.barEdges.includes("top") sourceComponent: EdgeExclusion { - targetScreen: root.screen - anchorTop: true - anchorLeft: true - anchorRight: true + targetScreen: root.screen + anchorTop: true + anchorLeft: true + anchorRight: true } } Loader { active: root.screenEnabled && !root.barEdges.includes("bottom") sourceComponent: EdgeExclusion { - targetScreen: root.screen - anchorBottom: true - anchorLeft: true - anchorRight: true + targetScreen: root.screen + anchorBottom: true + anchorLeft: true + anchorRight: true } } Loader { active: root.screenEnabled && !root.barEdges.includes("left") sourceComponent: EdgeExclusion { - targetScreen: root.screen - anchorLeft: true - anchorTop: true - anchorBottom: true + targetScreen: root.screen + anchorLeft: true + anchorTop: true + anchorBottom: true } } Loader { active: root.screenEnabled && !root.barEdges.includes("right") sourceComponent: EdgeExclusion { - targetScreen: root.screen - anchorRight: true - anchorTop: true - anchorBottom: true + targetScreen: root.screen + anchorRight: true + anchorTop: true + anchorBottom: true } } @@ -64,24 +64,24 @@ Scope { required property var targetScreen screen: targetScreen - property bool anchorTop: false + property bool anchorTop: false property bool anchorBottom: false - property bool anchorLeft: false - property bool anchorRight: false + property bool anchorLeft: false + property bool anchorRight: false WlrLayershell.namespace: "dms:frame-exclusion" WlrLayershell.layer: WlrLayer.Top exclusiveZone: SettingsData.frameThickness color: "transparent" mask: Region {} - implicitWidth: 1 + implicitWidth: 1 implicitHeight: 1 anchors { - top: anchorTop + top: anchorTop bottom: anchorBottom - left: anchorLeft - right: anchorRight + left: anchorLeft + right: anchorRight } } } diff --git a/quickshell/Modules/Frame/FrameInstance.qml b/quickshell/Modules/Frame/FrameInstance.qml index bb434a8a..1afdd92e 100644 --- a/quickshell/Modules/Frame/FrameInstance.qml +++ b/quickshell/Modules/Frame/FrameInstance.qml @@ -1,7 +1,6 @@ pragma ComponentBehavior: Bound import QtQuick -import Quickshell Item { id: root diff --git a/quickshell/Modules/Frame/FrameWindow.qml b/quickshell/Modules/Frame/FrameWindow.qml index 9ec89ab8..67eca814 100644 --- a/quickshell/Modules/Frame/FrameWindow.qml +++ b/quickshell/Modules/Frame/FrameWindow.qml @@ -7,6 +7,7 @@ import Quickshell.Wayland import qs.Common import qs.Services import qs.Widgets +import "../../Common/ConnectorGeometry.js" as ConnectorGeometry PanelWindow { id: win @@ -218,11 +219,11 @@ PanelWindow { readonly property real _radius: win._popoutConnectorRadius("left") readonly property bool _active: _popoutBodyBlurAnchor._active && _radius > 0 - readonly property real _w: win._popoutConnectorWidth(0, "left") - readonly property real _h: win._popoutConnectorHeight(0, "left") + readonly property real _w: ConnectorGeometry.connectorWidth(ConnectedModeState.popoutBarSide, 0, win._popoutConnectorRadius("left")) + readonly property real _h: ConnectorGeometry.connectorHeight(ConnectedModeState.popoutBarSide, 0, win._popoutConnectorRadius("left")) - x: _active ? Theme.snap(win._popoutConnectorX(_popoutBodyBlurAnchor.x, _popoutBodyBlurAnchor.width, "left", 0), win._dpr) : 0 - y: _active ? Theme.snap(win._popoutConnectorY(_popoutBodyBlurAnchor.y, _popoutBodyBlurAnchor.height, "left", 0), win._dpr) : 0 + x: _active ? Theme.snap(ConnectorGeometry.connectorX(ConnectedModeState.popoutBarSide, _popoutBodyBlurAnchor.x, _popoutBodyBlurAnchor.width, "left", 0, win._popoutConnectorRadius("left")), win._dpr) : 0 + y: _active ? Theme.snap(ConnectorGeometry.connectorY(ConnectedModeState.popoutBarSide, _popoutBodyBlurAnchor.y, _popoutBodyBlurAnchor.height, "left", 0, win._popoutConnectorRadius("left")), win._dpr) : 0 width: _active ? _w : 0 height: _active ? _h : 0 } @@ -233,11 +234,11 @@ PanelWindow { readonly property real _radius: win._popoutConnectorRadius("right") readonly property bool _active: _popoutBodyBlurAnchor._active && _radius > 0 - readonly property real _w: win._popoutConnectorWidth(0, "right") - readonly property real _h: win._popoutConnectorHeight(0, "right") + readonly property real _w: ConnectorGeometry.connectorWidth(ConnectedModeState.popoutBarSide, 0, win._popoutConnectorRadius("right")) + readonly property real _h: ConnectorGeometry.connectorHeight(ConnectedModeState.popoutBarSide, 0, win._popoutConnectorRadius("right")) - x: _active ? Theme.snap(win._popoutConnectorX(_popoutBodyBlurAnchor.x, _popoutBodyBlurAnchor.width, "right", 0), win._dpr) : 0 - y: _active ? Theme.snap(win._popoutConnectorY(_popoutBodyBlurAnchor.y, _popoutBodyBlurAnchor.height, "right", 0), win._dpr) : 0 + x: _active ? Theme.snap(ConnectorGeometry.connectorX(ConnectedModeState.popoutBarSide, _popoutBodyBlurAnchor.x, _popoutBodyBlurAnchor.width, "right", 0, win._popoutConnectorRadius("right")), win._dpr) : 0 + y: _active ? Theme.snap(ConnectorGeometry.connectorY(ConnectedModeState.popoutBarSide, _popoutBodyBlurAnchor.y, _popoutBodyBlurAnchor.height, "right", 0, win._popoutConnectorRadius("right")), win._dpr) : 0 width: _active ? _w : 0 height: _active ? _h : 0 } @@ -247,7 +248,7 @@ PanelWindow { opacity: 0 readonly property bool _active: _popoutLeftConnectorBlurAnchor.width > 0 && _popoutLeftConnectorBlurAnchor.height > 0 - readonly property string _arcCorner: win._connectorArcCorner(ConnectedModeState.popoutBarSide, "left") + readonly property string _arcCorner: ConnectorGeometry.arcCorner(ConnectedModeState.popoutBarSide, "left") readonly property real _radius: win._popoutConnectorRadius("left") x: _active ? win._connectorCutoutX(_popoutLeftConnectorBlurAnchor.x, _popoutLeftConnectorBlurAnchor.width, _arcCorner, _radius) : 0 @@ -261,7 +262,7 @@ PanelWindow { opacity: 0 readonly property bool _active: _popoutRightConnectorBlurAnchor.width > 0 && _popoutRightConnectorBlurAnchor.height > 0 - readonly property string _arcCorner: win._connectorArcCorner(ConnectedModeState.popoutBarSide, "right") + readonly property string _arcCorner: ConnectorGeometry.arcCorner(ConnectedModeState.popoutBarSide, "right") readonly property real _radius: win._popoutConnectorRadius("right") x: _active ? win._connectorCutoutX(_popoutRightConnectorBlurAnchor.x, _popoutRightConnectorBlurAnchor.width, _arcCorner, _radius) : 0 @@ -329,7 +330,7 @@ PanelWindow { readonly property bool _active: _popoutFarStartConnectorBlurAnchor.width > 0 && _popoutFarStartConnectorBlurAnchor.height > 0 readonly property string _barSide: win._farConnectorBarSide(ConnectedModeState.popoutBarSide, "left") readonly property string _placement: win._farConnectorPlacement(ConnectedModeState.popoutBarSide, "left") - readonly property string _arcCorner: win._connectorArcCorner(_barSide, _placement) + readonly property string _arcCorner: ConnectorGeometry.arcCorner(_barSide, _placement) readonly property real _radius: win._effectivePopoutFarStartCcr x: _active ? win._connectorCutoutX(_popoutFarStartConnectorBlurAnchor.x, _popoutFarStartConnectorBlurAnchor.width, _arcCorner, _radius) : 0 @@ -345,7 +346,7 @@ PanelWindow { readonly property bool _active: _popoutFarEndConnectorBlurAnchor.width > 0 && _popoutFarEndConnectorBlurAnchor.height > 0 readonly property string _barSide: win._farConnectorBarSide(ConnectedModeState.popoutBarSide, "right") readonly property string _placement: win._farConnectorPlacement(ConnectedModeState.popoutBarSide, "right") - readonly property string _arcCorner: win._connectorArcCorner(_barSide, _placement) + readonly property string _arcCorner: ConnectorGeometry.arcCorner(_barSide, _placement) readonly property real _radius: win._effectivePopoutFarEndCcr x: _active ? win._connectorCutoutX(_popoutFarEndConnectorBlurAnchor.x, _popoutFarEndConnectorBlurAnchor.width, _arcCorner, _radius) : 0 @@ -359,11 +360,11 @@ PanelWindow { opacity: 0 readonly property bool _active: _dockBodyBlurAnchor._active && win._dockConnectorRadius() > 0 - readonly property real _w: win._dockConnectorWidth(0) - readonly property real _h: win._dockConnectorHeight(0) + readonly property real _w: ConnectorGeometry.connectorWidth(win._dockState.barSide, 0, win._dockConnectorRadius()) + readonly property real _h: ConnectorGeometry.connectorHeight(win._dockState.barSide, 0, win._dockConnectorRadius()) - x: _active ? Theme.snap(win._dockConnectorX(_dockBodyBlurAnchor.x, _dockBodyBlurAnchor.width, "left", 0), win._dpr) : 0 - y: _active ? Theme.snap(win._dockConnectorY(_dockBodyBlurAnchor.y, _dockBodyBlurAnchor.height, "left", 0), win._dpr) : 0 + x: _active ? Theme.snap(ConnectorGeometry.connectorX(win._dockState.barSide, _dockBodyBlurAnchor.x, _dockBodyBlurAnchor.width, "left", 0, win._dockConnectorRadius()), win._dpr) : 0 + y: _active ? Theme.snap(ConnectorGeometry.connectorY(win._dockState.barSide, _dockBodyBlurAnchor.y, _dockBodyBlurAnchor.height, "left", 0, win._dockConnectorRadius()), win._dpr) : 0 width: _active ? _w : 0 height: _active ? _h : 0 } @@ -373,11 +374,11 @@ PanelWindow { opacity: 0 readonly property bool _active: _dockBodyBlurAnchor._active && win._dockConnectorRadius() > 0 - readonly property real _w: win._dockConnectorWidth(0) - readonly property real _h: win._dockConnectorHeight(0) + readonly property real _w: ConnectorGeometry.connectorWidth(win._dockState.barSide, 0, win._dockConnectorRadius()) + readonly property real _h: ConnectorGeometry.connectorHeight(win._dockState.barSide, 0, win._dockConnectorRadius()) - x: _active ? Theme.snap(win._dockConnectorX(_dockBodyBlurAnchor.x, _dockBodyBlurAnchor.width, "right", 0), win._dpr) : 0 - y: _active ? Theme.snap(win._dockConnectorY(_dockBodyBlurAnchor.y, _dockBodyBlurAnchor.height, "right", 0), win._dpr) : 0 + x: _active ? Theme.snap(ConnectorGeometry.connectorX(win._dockState.barSide, _dockBodyBlurAnchor.x, _dockBodyBlurAnchor.width, "right", 0, win._dockConnectorRadius()), win._dpr) : 0 + y: _active ? Theme.snap(ConnectorGeometry.connectorY(win._dockState.barSide, _dockBodyBlurAnchor.y, _dockBodyBlurAnchor.height, "right", 0, win._dockConnectorRadius()), win._dpr) : 0 width: _active ? _w : 0 height: _active ? _h : 0 } @@ -387,7 +388,7 @@ PanelWindow { opacity: 0 readonly property bool _active: _dockLeftConnectorBlurAnchor.width > 0 && _dockLeftConnectorBlurAnchor.height > 0 - readonly property string _arcCorner: win._connectorArcCorner(win._dockState.barSide, "left") + readonly property string _arcCorner: ConnectorGeometry.arcCorner(win._dockState.barSide, "left") x: _active ? win._connectorCutoutX(_dockLeftConnectorBlurAnchor.x, _dockLeftConnectorBlurAnchor.width, _arcCorner, win._dockConnectorRadius()) : 0 y: _active ? win._connectorCutoutY(_dockLeftConnectorBlurAnchor.y, _dockLeftConnectorBlurAnchor.height, _arcCorner, win._dockConnectorRadius()) : 0 @@ -400,7 +401,7 @@ PanelWindow { opacity: 0 readonly property bool _active: _dockRightConnectorBlurAnchor.width > 0 && _dockRightConnectorBlurAnchor.height > 0 - readonly property string _arcCorner: win._connectorArcCorner(win._dockState.barSide, "right") + readonly property string _arcCorner: ConnectorGeometry.arcCorner(win._dockState.barSide, "right") x: _active ? win._connectorCutoutX(_dockRightConnectorBlurAnchor.x, _dockRightConnectorBlurAnchor.width, _arcCorner, win._dockConnectorRadius()) : 0 y: _active ? win._connectorCutoutY(_dockRightConnectorBlurAnchor.y, _dockRightConnectorBlurAnchor.height, _arcCorner, win._dockConnectorRadius()) : 0 @@ -458,11 +459,11 @@ PanelWindow { readonly property real _radius: win._modalConnectorRadius("left") readonly property bool _active: _modalBodyBlurAnchor._active && _radius > 0 - readonly property real _w: win._modalConnectorWidth(0, "left") - readonly property real _h: win._modalConnectorHeight(0, "left") + readonly property real _w: ConnectorGeometry.connectorWidth(win._modalState.barSide, 0, win._modalConnectorRadius("left")) + readonly property real _h: ConnectorGeometry.connectorHeight(win._modalState.barSide, 0, win._modalConnectorRadius("left")) - x: _active ? Theme.snap(win._modalConnectorX(_modalBodyBlurAnchor.x, _modalBodyBlurAnchor.width, "left", 0), win._dpr) : 0 - y: _active ? Theme.snap(win._modalConnectorY(_modalBodyBlurAnchor.y, _modalBodyBlurAnchor.height, "left", 0), win._dpr) : 0 + x: _active ? Theme.snap(ConnectorGeometry.connectorX(win._modalState.barSide, _modalBodyBlurAnchor.x, _modalBodyBlurAnchor.width, "left", 0, win._modalConnectorRadius("left")), win._dpr) : 0 + y: _active ? Theme.snap(ConnectorGeometry.connectorY(win._modalState.barSide, _modalBodyBlurAnchor.y, _modalBodyBlurAnchor.height, "left", 0, win._modalConnectorRadius("left")), win._dpr) : 0 width: _active ? _w : 0 height: _active ? _h : 0 } @@ -473,11 +474,11 @@ PanelWindow { readonly property real _radius: win._modalConnectorRadius("right") readonly property bool _active: _modalBodyBlurAnchor._active && _radius > 0 - readonly property real _w: win._modalConnectorWidth(0, "right") - readonly property real _h: win._modalConnectorHeight(0, "right") + readonly property real _w: ConnectorGeometry.connectorWidth(win._modalState.barSide, 0, win._modalConnectorRadius("right")) + readonly property real _h: ConnectorGeometry.connectorHeight(win._modalState.barSide, 0, win._modalConnectorRadius("right")) - x: _active ? Theme.snap(win._modalConnectorX(_modalBodyBlurAnchor.x, _modalBodyBlurAnchor.width, "right", 0), win._dpr) : 0 - y: _active ? Theme.snap(win._modalConnectorY(_modalBodyBlurAnchor.y, _modalBodyBlurAnchor.height, "right", 0), win._dpr) : 0 + x: _active ? Theme.snap(ConnectorGeometry.connectorX(win._modalState.barSide, _modalBodyBlurAnchor.x, _modalBodyBlurAnchor.width, "right", 0, win._modalConnectorRadius("right")), win._dpr) : 0 + y: _active ? Theme.snap(ConnectorGeometry.connectorY(win._modalState.barSide, _modalBodyBlurAnchor.y, _modalBodyBlurAnchor.height, "right", 0, win._modalConnectorRadius("right")), win._dpr) : 0 width: _active ? _w : 0 height: _active ? _h : 0 } @@ -487,7 +488,7 @@ PanelWindow { opacity: 0 readonly property bool _active: _modalLeftConnectorBlurAnchor.width > 0 && _modalLeftConnectorBlurAnchor.height > 0 - readonly property string _arcCorner: win._connectorArcCorner(win._modalState.barSide, "left") + readonly property string _arcCorner: ConnectorGeometry.arcCorner(win._modalState.barSide, "left") readonly property real _radius: win._modalConnectorRadius("left") x: _active ? win._connectorCutoutX(_modalLeftConnectorBlurAnchor.x, _modalLeftConnectorBlurAnchor.width, _arcCorner, _radius) : 0 @@ -501,7 +502,7 @@ PanelWindow { opacity: 0 readonly property bool _active: _modalRightConnectorBlurAnchor.width > 0 && _modalRightConnectorBlurAnchor.height > 0 - readonly property string _arcCorner: win._connectorArcCorner(win._modalState.barSide, "right") + readonly property string _arcCorner: ConnectorGeometry.arcCorner(win._modalState.barSide, "right") readonly property real _radius: win._modalConnectorRadius("right") x: _active ? win._connectorCutoutX(_modalRightConnectorBlurAnchor.x, _modalRightConnectorBlurAnchor.width, _arcCorner, _radius) : 0 @@ -569,7 +570,7 @@ PanelWindow { readonly property bool _active: _modalFarStartConnectorBlurAnchor.width > 0 && _modalFarStartConnectorBlurAnchor.height > 0 readonly property string _barSide: win._farConnectorBarSide(win._modalState.barSide, "left") readonly property string _placement: win._farConnectorPlacement(win._modalState.barSide, "left") - readonly property string _arcCorner: win._connectorArcCorner(_barSide, _placement) + readonly property string _arcCorner: ConnectorGeometry.arcCorner(_barSide, _placement) readonly property real _radius: win._effectiveModalFarStartCcr x: _active ? win._connectorCutoutX(_modalFarStartConnectorBlurAnchor.x, _modalFarStartConnectorBlurAnchor.width, _arcCorner, _radius) : 0 @@ -585,7 +586,7 @@ PanelWindow { readonly property bool _active: _modalFarEndConnectorBlurAnchor.width > 0 && _modalFarEndConnectorBlurAnchor.height > 0 readonly property string _barSide: win._farConnectorBarSide(win._modalState.barSide, "right") readonly property string _placement: win._farConnectorPlacement(win._modalState.barSide, "right") - readonly property string _arcCorner: win._connectorArcCorner(_barSide, _placement) + readonly property string _arcCorner: ConnectorGeometry.arcCorner(_barSide, _placement) readonly property real _radius: win._effectiveModalFarEndCcr x: _active ? win._connectorCutoutX(_modalFarEndConnectorBlurAnchor.x, _modalFarEndConnectorBlurAnchor.width, _arcCorner, _radius) : 0 @@ -628,11 +629,11 @@ PanelWindow { readonly property real _radius: win._notifConnectorRadius("left") readonly property bool _active: _notifBodySceneBlurAnchor._active && _radius > 0 - readonly property real _w: win._notifConnectorWidth(0, "left") - readonly property real _h: win._notifConnectorHeight(0, "left") + readonly property real _w: ConnectorGeometry.connectorWidth(win._notifState.barSide, 0, win._notifConnectorRadius("left")) + readonly property real _h: ConnectorGeometry.connectorHeight(win._notifState.barSide, 0, win._notifConnectorRadius("left")) - x: _active ? Theme.snap(win._notifConnectorX(_notifBodySceneBlurAnchor.x, _notifBodySceneBlurAnchor.width, "left", 0), win._dpr) : 0 - y: _active ? Theme.snap(win._notifConnectorY(_notifBodySceneBlurAnchor.y, _notifBodySceneBlurAnchor.height, "left", 0), win._dpr) : 0 + x: _active ? Theme.snap(ConnectorGeometry.connectorX(win._notifState.barSide, _notifBodySceneBlurAnchor.x, _notifBodySceneBlurAnchor.width, "left", 0, win._notifConnectorRadius("left")), win._dpr) : 0 + y: _active ? Theme.snap(ConnectorGeometry.connectorY(win._notifState.barSide, _notifBodySceneBlurAnchor.y, _notifBodySceneBlurAnchor.height, "left", 0, win._notifConnectorRadius("left")), win._dpr) : 0 width: _active ? _w : 0 height: _active ? _h : 0 } @@ -643,11 +644,11 @@ PanelWindow { readonly property real _radius: win._notifConnectorRadius("right") readonly property bool _active: _notifBodySceneBlurAnchor._active && _radius > 0 - readonly property real _w: win._notifConnectorWidth(0, "right") - readonly property real _h: win._notifConnectorHeight(0, "right") + readonly property real _w: ConnectorGeometry.connectorWidth(win._notifState.barSide, 0, win._notifConnectorRadius("right")) + readonly property real _h: ConnectorGeometry.connectorHeight(win._notifState.barSide, 0, win._notifConnectorRadius("right")) - x: _active ? Theme.snap(win._notifConnectorX(_notifBodySceneBlurAnchor.x, _notifBodySceneBlurAnchor.width, "right", 0), win._dpr) : 0 - y: _active ? Theme.snap(win._notifConnectorY(_notifBodySceneBlurAnchor.y, _notifBodySceneBlurAnchor.height, "right", 0), win._dpr) : 0 + x: _active ? Theme.snap(ConnectorGeometry.connectorX(win._notifState.barSide, _notifBodySceneBlurAnchor.x, _notifBodySceneBlurAnchor.width, "right", 0, win._notifConnectorRadius("right")), win._dpr) : 0 + y: _active ? Theme.snap(ConnectorGeometry.connectorY(win._notifState.barSide, _notifBodySceneBlurAnchor.y, _notifBodySceneBlurAnchor.height, "right", 0, win._notifConnectorRadius("right")), win._dpr) : 0 width: _active ? _w : 0 height: _active ? _h : 0 } @@ -657,7 +658,7 @@ PanelWindow { opacity: 0 readonly property bool _active: _notifLeftConnectorBlurAnchor.width > 0 && _notifLeftConnectorBlurAnchor.height > 0 - readonly property string _arcCorner: win._connectorArcCorner(win._notifState.barSide, "left") + readonly property string _arcCorner: ConnectorGeometry.arcCorner(win._notifState.barSide, "left") readonly property real _radius: win._notifConnectorRadius("left") x: _active ? win._connectorCutoutX(_notifLeftConnectorBlurAnchor.x, _notifLeftConnectorBlurAnchor.width, _arcCorner, _radius) : 0 @@ -671,7 +672,7 @@ PanelWindow { opacity: 0 readonly property bool _active: _notifRightConnectorBlurAnchor.width > 0 && _notifRightConnectorBlurAnchor.height > 0 - readonly property string _arcCorner: win._connectorArcCorner(win._notifState.barSide, "right") + readonly property string _arcCorner: ConnectorGeometry.arcCorner(win._notifState.barSide, "right") readonly property real _radius: win._notifConnectorRadius("right") x: _active ? win._connectorCutoutX(_notifRightConnectorBlurAnchor.x, _notifRightConnectorBlurAnchor.width, _arcCorner, _radius) : 0 @@ -739,7 +740,7 @@ PanelWindow { readonly property bool _active: _notifFarStartConnectorBlurAnchor.width > 0 && _notifFarStartConnectorBlurAnchor.height > 0 readonly property string _barSide: win._farConnectorBarSide(win._notifState.barSide, "left") readonly property string _placement: win._farConnectorPlacement(win._notifState.barSide, "left") - readonly property string _arcCorner: win._connectorArcCorner(_barSide, _placement) + readonly property string _arcCorner: ConnectorGeometry.arcCorner(_barSide, _placement) readonly property real _radius: win._effectiveNotifFarStartCcr x: _active ? win._connectorCutoutX(_notifFarStartConnectorBlurAnchor.x, _notifFarStartConnectorBlurAnchor.width, _arcCorner, _radius) : 0 @@ -755,7 +756,7 @@ PanelWindow { readonly property bool _active: _notifFarEndConnectorBlurAnchor.width > 0 && _notifFarEndConnectorBlurAnchor.height > 0 readonly property string _barSide: win._farConnectorBarSide(win._notifState.barSide, "right") readonly property string _placement: win._farConnectorPlacement(win._notifState.barSide, "right") - readonly property string _arcCorner: win._connectorArcCorner(_barSide, _placement) + readonly property string _arcCorner: ConnectorGeometry.arcCorner(_barSide, _placement) readonly property real _radius: win._effectiveNotifFarEndCcr x: _active ? win._connectorCutoutX(_notifFarEndConnectorBlurAnchor.x, _notifFarEndConnectorBlurAnchor.width, _arcCorner, _radius) : 0 @@ -960,39 +961,6 @@ PanelWindow { return Math.max(0, Math.min(win._ccr, bodyRadius, maxConnectorRadius)); } - function _dockConnectorWidth(spacing) { - const isVert = win._dockState.barSide === "left" || win._dockState.barSide === "right"; - const radius = win._dockConnectorRadius(); - return isVert ? (spacing + radius) : radius; - } - - function _dockConnectorHeight(spacing) { - const isVert = win._dockState.barSide === "left" || win._dockState.barSide === "right"; - const radius = win._dockConnectorRadius(); - return isVert ? radius : (spacing + radius); - } - - function _dockConnectorX(baseX, bodyWidth, placement, spacing) { - const dockSide = win._dockState.barSide; - const isVert = dockSide === "left" || dockSide === "right"; - const seamX = !isVert ? (placement === "left" ? baseX : baseX + bodyWidth) : (dockSide === "left" ? baseX : baseX + bodyWidth); - const w = _dockConnectorWidth(spacing); - if (!isVert) - return placement === "left" ? seamX - w : seamX; - return dockSide === "left" ? seamX : seamX - w; - } - - function _dockConnectorY(baseY, bodyHeight, placement, spacing) { - const dockSide = win._dockState.barSide; - const seamY = dockSide === "top" ? baseY : dockSide === "bottom" ? baseY + bodyHeight : (placement === "left" ? baseY : baseY + bodyHeight); - const h = _dockConnectorHeight(spacing); - if (dockSide === "top") - return seamY; - if (dockSide === "bottom") - return seamY - h; - return placement === "left" ? seamY - h : seamY; - } - function _notifSideUnderlap() { const side = win._notifState.barSide; return (side === "left" || side === "right") ? win._seamOverlap : 0; @@ -1046,76 +1014,10 @@ PanelWindow { return win._effectiveNotifMaxCcr; } - function _notifConnectorWidth(spacing, placement) { - const isVert = win._notifState.barSide === "left" || win._notifState.barSide === "right"; - const radius = win._notifConnectorRadius(placement); - return isVert ? (spacing + radius) : radius; - } - - function _notifConnectorHeight(spacing, placement) { - const isVert = win._notifState.barSide === "left" || win._notifState.barSide === "right"; - const radius = win._notifConnectorRadius(placement); - return isVert ? radius : (spacing + radius); - } - - function _notifConnectorX(baseX, bodyWidth, placement, spacing) { - const notifSide = win._notifState.barSide; - const isVert = notifSide === "left" || notifSide === "right"; - const seamX = !isVert ? (placement === "left" ? baseX : baseX + bodyWidth) : (notifSide === "left" ? baseX : baseX + bodyWidth); - const w = _notifConnectorWidth(spacing, placement); - if (!isVert) - return placement === "left" ? seamX - w : seamX; - return notifSide === "left" ? seamX : seamX - w; - } - - function _notifConnectorY(baseY, bodyHeight, placement, spacing) { - const notifSide = win._notifState.barSide; - const seamY = notifSide === "top" ? baseY : notifSide === "bottom" ? baseY + bodyHeight : (placement === "left" ? baseY : baseY + bodyHeight); - const h = _notifConnectorHeight(spacing, placement); - if (notifSide === "top") - return seamY; - if (notifSide === "bottom") - return seamY - h; - return placement === "left" ? seamY - h : seamY; - } - function _popoutConnectorRadius(placement) { return placement === "right" ? win._effectivePopoutEndCcr : win._effectivePopoutStartCcr; } - function _popoutConnectorWidth(spacing, placement) { - const isVert = ConnectedModeState.popoutBarSide === "left" || ConnectedModeState.popoutBarSide === "right"; - const radius = win._popoutConnectorRadius(placement); - return isVert ? (spacing + radius) : radius; - } - - function _popoutConnectorHeight(spacing, placement) { - const isVert = ConnectedModeState.popoutBarSide === "left" || ConnectedModeState.popoutBarSide === "right"; - const radius = win._popoutConnectorRadius(placement); - return isVert ? radius : (spacing + radius); - } - - function _popoutConnectorX(baseX, bodyWidth, placement, spacing) { - const popoutSide = ConnectedModeState.popoutBarSide; - const isVert = popoutSide === "left" || popoutSide === "right"; - const seamX = !isVert ? (placement === "left" ? baseX : baseX + bodyWidth) : (popoutSide === "left" ? baseX : baseX + bodyWidth); - const w = _popoutConnectorWidth(spacing, placement); - if (!isVert) - return placement === "left" ? seamX - w : seamX; - return popoutSide === "left" ? seamX : seamX - w; - } - - function _popoutConnectorY(baseY, bodyHeight, placement, spacing) { - const popoutSide = ConnectedModeState.popoutBarSide; - const seamY = popoutSide === "top" ? baseY : popoutSide === "bottom" ? baseY + bodyHeight : (placement === "left" ? baseY : baseY + bodyHeight); - const h = _popoutConnectorHeight(spacing, placement); - if (popoutSide === "top") - return seamY; - if (popoutSide === "bottom") - return seamY - h; - return placement === "left" ? seamY - h : seamY; - } - function _popoutFillOverlapX() { return (ConnectedModeState.popoutBarSide === "top" || ConnectedModeState.popoutBarSide === "bottom") ? win._seamOverlap : 0; } @@ -1145,39 +1047,6 @@ PanelWindow { return placement === "right" ? win._effectiveModalEndCcr : win._effectiveModalStartCcr; } - function _modalConnectorWidth(spacing, placement) { - const isVert = win._modalState.barSide === "left" || win._modalState.barSide === "right"; - const radius = win._modalConnectorRadius(placement); - return isVert ? (spacing + radius) : radius; - } - - function _modalConnectorHeight(spacing, placement) { - const isVert = win._modalState.barSide === "left" || win._modalState.barSide === "right"; - const radius = win._modalConnectorRadius(placement); - return isVert ? radius : (spacing + radius); - } - - function _modalConnectorX(baseX, bodyWidth, placement, spacing) { - const barSide = win._modalState.barSide; - const isVert = barSide === "left" || barSide === "right"; - const seamX = !isVert ? (placement === "left" ? baseX : baseX + bodyWidth) : (barSide === "left" ? baseX : baseX + bodyWidth); - const w = _modalConnectorWidth(spacing, placement); - if (!isVert) - return placement === "left" ? seamX - w : seamX; - return barSide === "left" ? seamX : seamX - w; - } - - function _modalConnectorY(baseY, bodyHeight, placement, spacing) { - const barSide = win._modalState.barSide; - const seamY = barSide === "top" ? baseY : barSide === "bottom" ? baseY + bodyHeight : (placement === "left" ? baseY : baseY + bodyHeight); - const h = _modalConnectorHeight(spacing, placement); - if (barSide === "top") - return seamY; - if (barSide === "bottom") - return seamY - h; - return placement === "left" ? seamY - h : seamY; - } - function _popoutArcExtent() { return (ConnectedModeState.popoutBarSide === "top" || ConnectedModeState.popoutBarSide === "bottom") ? _popoutBodyBlurAnchor.height : _popoutBodyBlurAnchor.width; } @@ -1349,16 +1218,6 @@ PanelWindow { return placement === "left" ? baseY : baseY + bodyHeight - radius; } - function _connectorArcCorner(barSide, placement) { - if (barSide === "top") - return placement === "left" ? "bottomLeft" : "bottomRight"; - if (barSide === "bottom") - return placement === "left" ? "topLeft" : "topRight"; - if (barSide === "left") - return placement === "left" ? "topRight" : "bottomRight"; - return placement === "left" ? "topLeft" : "bottomLeft"; - } - function _connectorCutoutX(connectorX, connectorWidth, arcCorner, radius) { const r = radius === undefined ? win._effectivePopoutCcr : radius; return (arcCorner === "topLeft" || arcCorner === "bottomLeft") ? connectorX - r : connectorX + connectorWidth - r; @@ -1572,8 +1431,8 @@ PanelWindow { connectorRadius: win._dockConnectorRadius() color: win._opaqueSurfaceColor dpr: win._dpr - x: Theme.snap(win._dockConnectorX(_dockBodyBlurAnchor.x, _dockBodyBlurAnchor.width, "left", 0) - _dockChrome.x, win._dpr) - y: Theme.snap(win._dockConnectorY(_dockBodyBlurAnchor.y, _dockBodyBlurAnchor.height, "left", 0) - _dockChrome.y, win._dpr) + x: Theme.snap(ConnectorGeometry.connectorX(win._dockState.barSide, _dockBodyBlurAnchor.x, _dockBodyBlurAnchor.width, "left", 0, win._dockConnectorRadius()) - _dockChrome.x, win._dpr) + y: Theme.snap(ConnectorGeometry.connectorY(win._dockState.barSide, _dockBodyBlurAnchor.y, _dockBodyBlurAnchor.height, "left", 0, win._dockConnectorRadius()) - _dockChrome.y, win._dpr) } ConnectedCorner { @@ -1585,8 +1444,8 @@ PanelWindow { connectorRadius: win._dockConnectorRadius() color: win._opaqueSurfaceColor dpr: win._dpr - x: Theme.snap(win._dockConnectorX(_dockBodyBlurAnchor.x, _dockBodyBlurAnchor.width, "right", 0) - _dockChrome.x, win._dpr) - y: Theme.snap(win._dockConnectorY(_dockBodyBlurAnchor.y, _dockBodyBlurAnchor.height, "right", 0) - _dockChrome.y, win._dpr) + x: Theme.snap(ConnectorGeometry.connectorX(win._dockState.barSide, _dockBodyBlurAnchor.x, _dockBodyBlurAnchor.width, "right", 0, win._dockConnectorRadius()) - _dockChrome.x, win._dpr) + y: Theme.snap(ConnectorGeometry.connectorY(win._dockState.barSide, _dockBodyBlurAnchor.y, _dockBodyBlurAnchor.height, "right", 0, win._dockConnectorRadius()) - _dockChrome.y, win._dpr) } } } diff --git a/quickshell/Modules/Settings/TypographyMotionTab.qml b/quickshell/Modules/Settings/TypographyMotionTab.qml index 9dc0841b..56e23a59 100644 --- a/quickshell/Modules/Settings/TypographyMotionTab.qml +++ b/quickshell/Modules/Settings/TypographyMotionTab.qml @@ -211,9 +211,7 @@ Item { return I18n.tr("Popouts emerge flush from the bar edge as a single continuous piece, with corner connectors bridging the junction"); return I18n.tr("How the popout emerges from the DankBar"); } - options: SettingsData.frameEnabled - ? [I18n.tr("Overlap"), I18n.tr("Slide"), I18n.tr("Roll"), I18n.tr("Connected")] - : [I18n.tr("Overlap"), I18n.tr("Slide"), I18n.tr("Roll")] + options: SettingsData.frameEnabled ? [I18n.tr("Overlap"), I18n.tr("Slide"), I18n.tr("Roll"), I18n.tr("Connected")] : [I18n.tr("Overlap"), I18n.tr("Slide"), I18n.tr("Roll")] currentValue: { switch (SettingsData.directionalAnimationMode) { case 1: @@ -471,12 +469,6 @@ Item { description: I18n.tr("Popouts and Modals follow global Animation Speed (disable to customize independently)") checked: SettingsData.syncComponentAnimationSpeeds onToggled: checked => SettingsData.set("syncComponentAnimationSpeeds", checked) - - Connections { - target: SettingsData - function onSyncComponentAnimationSpeedsChanged() { - } - } } } diff --git a/quickshell/Widgets/ConnectedCorner.qml b/quickshell/Widgets/ConnectedCorner.qml index 25383b2e..44fb9c15 100644 --- a/quickshell/Widgets/ConnectedCorner.qml +++ b/quickshell/Widgets/ConnectedCorner.qml @@ -1,6 +1,6 @@ import QtQuick import QtQuick.Shapes -import qs.Common +import "../Common/ConnectorGeometry.js" as ConnectorGeometry // Concave arc connector filling the gap between a bar corner and an adjacent surface. // @@ -23,15 +23,7 @@ Item { readonly property bool isHorizontalBar: barSide === "top" || barSide === "bottom" readonly property bool isPlacementLeft: placement === "left" readonly property real _edgeStrokeWidth: Math.max(0, edgeStrokeWidth) - readonly property string arcCorner: { - if (barSide === "top") - return isPlacementLeft ? "bottomLeft" : "bottomRight"; - if (barSide === "bottom") - return isPlacementLeft ? "topLeft" : "topRight"; - if (barSide === "left") - return isPlacementLeft ? "topRight" : "bottomRight"; - return isPlacementLeft ? "topLeft" : "bottomLeft"; - } + readonly property string arcCorner: ConnectorGeometry.arcCorner(barSide, placement) readonly property real pathStartX: { switch (arcCorner) { case "topLeft": diff --git a/quickshell/Widgets/DankPopoutConnected.qml b/quickshell/Widgets/DankPopoutConnected.qml index c7c1acbd..ebcbf273 100644 --- a/quickshell/Widgets/DankPopoutConnected.qml +++ b/quickshell/Widgets/DankPopoutConnected.qml @@ -3,6 +3,7 @@ import Quickshell import Quickshell.Wayland import qs.Common import qs.Services +import "../Common/ConnectorGeometry.js" as ConnectorGeometry Item { id: root @@ -802,46 +803,6 @@ Item { readonly property real horizontalConnectorExtent: Theme.isConnectedEffect && (barTop || barBottom) ? Theme.connectedCornerRadius : 0 readonly property real verticalConnectorExtent: Theme.isConnectedEffect && (barLeft || barRight) ? Theme.connectedCornerRadius : 0 - function connectorWidth(spacing) { - return (barTop || barBottom) ? Theme.connectedCornerRadius : (spacing + Theme.connectedCornerRadius); - } - - function connectorHeight(spacing) { - return (barTop || barBottom) ? (spacing + Theme.connectedCornerRadius) : Theme.connectedCornerRadius; - } - - function connectorSeamX(baseX, bodyWidth, placement) { - if (barTop || barBottom) - return placement === "left" ? baseX : baseX + bodyWidth; - return barLeft ? baseX : baseX + bodyWidth; - } - - function connectorSeamY(baseY, bodyHeight, placement) { - if (barTop) - return baseY; - if (barBottom) - return baseY + bodyHeight; - return placement === "left" ? baseY : baseY + bodyHeight; - } - - function connectorX(baseX, bodyWidth, placement, spacing) { - const seamX = connectorSeamX(baseX, bodyWidth, placement); - const width = connectorWidth(spacing); - if (barTop || barBottom) - return placement === "left" ? seamX - width : seamX; - return barLeft ? seamX : seamX - width; - } - - function connectorY(baseY, bodyHeight, placement, spacing) { - const seamY = connectorSeamY(baseY, bodyHeight, placement); - const height = connectorHeight(spacing); - if (barTop) - return seamY; - if (barBottom) - return seamY - height; - return placement === "left" ? seamY - height : seamY; - } - readonly property real offsetX: { if (directionalEffect) { if (typeof SettingsData !== "undefined" && SettingsData.directionalAnimationMode === 2) @@ -1057,8 +1018,8 @@ Item { connectorRadius: Theme.connectedCornerRadius color: contentContainer.surfaceColor dpr: root.dpr - x: Theme.snap(contentContainer.connectorX(shadowSource.bodyX, shadowSource.bodyWidth, placement, spacing), root.dpr) - y: Theme.snap(contentContainer.connectorY(shadowSource.bodyY, shadowSource.bodyHeight, placement, spacing), root.dpr) + x: Theme.snap(ConnectorGeometry.connectorX(contentContainer.connectedBarSide, shadowSource.bodyX, shadowSource.bodyWidth, placement, spacing, Theme.connectedCornerRadius), root.dpr) + y: Theme.snap(ConnectorGeometry.connectorY(contentContainer.connectedBarSide, shadowSource.bodyY, shadowSource.bodyHeight, placement, spacing, Theme.connectedCornerRadius), root.dpr) } ConnectedCorner { @@ -1069,8 +1030,8 @@ Item { connectorRadius: Theme.connectedCornerRadius color: contentContainer.surfaceColor dpr: root.dpr - x: Theme.snap(contentContainer.connectorX(shadowSource.bodyX, shadowSource.bodyWidth, placement, spacing), root.dpr) - y: Theme.snap(contentContainer.connectorY(shadowSource.bodyY, shadowSource.bodyHeight, placement, spacing), root.dpr) + x: Theme.snap(ConnectorGeometry.connectorX(contentContainer.connectedBarSide, shadowSource.bodyX, shadowSource.bodyWidth, placement, spacing, Theme.connectedCornerRadius), root.dpr) + y: Theme.snap(ConnectorGeometry.connectorY(contentContainer.connectedBarSide, shadowSource.bodyY, shadowSource.bodyHeight, placement, spacing, Theme.connectedCornerRadius), root.dpr) } } }