mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-05-03 02:52:07 -04:00
de-dupe and cleanup
This commit is contained in:
@@ -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<real> 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<real> 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<real> 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<real> variantEnterCurve: _enterCurves[_variant] || _enterCurves[0]
|
||||
readonly property list<real> variantExitCurve: _exitCurves[_variant] || _exitCurves[0]
|
||||
|
||||
readonly property list<real> 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<real> variantModalEnterCurve: isDirectionalEffect && _variant !== 0 ? (_enterCurves[_variant] || _enterCurves[0]) : variantEnterCurve
|
||||
readonly property list<real> variantModalExitCurve: isDirectionalEffect ? (_directionalExitCurves[_variant] || _exitCurves[0]) : variantExitCurve
|
||||
|
||||
// Popout-specific entry curve
|
||||
readonly property list<real> 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<real> variantPopoutEnterCurve: isDirectionalEffect ? (_variant === 0 ? Anims.standardDecel : (_enterCurves[_variant] || _enterCurves[0])) : variantEnterCurve
|
||||
readonly property list<real> variantPopoutExitCurve: isDirectionalEffect ? (_directionalExitCurves[_variant] || _exitCurves[0]) : variantExitCurve
|
||||
|
||||
readonly property list<real> 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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
64
quickshell/Common/ConnectorGeometry.js
Normal file
64
quickshell/Common/ConnectorGeometry.js
Normal file
@@ -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";
|
||||
}
|
||||
@@ -244,25 +244,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;
|
||||
}
|
||||
|
||||
@@ -1548,43 +1544,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 {
|
||||
@@ -1592,26 +1553,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() {
|
||||
@@ -2176,54 +2164,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;
|
||||
|
||||
Reference in New Issue
Block a user