1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-08-06 05:28:29 -04:00

refactor(Xray): Update Xray & standalone to frame transitions

- Fix dbar autohide with Xray options that could have blocked bar area content
- Fixes #2729
This commit is contained in:
purian23
2026-07-01 21:39:47 -04:00
parent 7964b66827
commit 57d08f6b3b
23 changed files with 313 additions and 87 deletions
+1 -1
View File
@@ -55,7 +55,7 @@ Singleton {
readonly property bool isDirectionalEffect: isConnectedEffect || _effect === 1
readonly property bool isDepthEffect: _effect === 2
readonly property bool isConnectedEffect: (typeof SettingsData !== "undefined") && SettingsData.connectedFrameModeActive
readonly property bool isConnectedEffect: (typeof FrameTransitionState !== "undefined") && FrameTransitionState.effectiveConnectedFrameModeActive
readonly property real effectScaleCollapsed: _effectScaleCollapsed[_effect] !== undefined ? _effectScaleCollapsed[_effect] : 0.96
readonly property real effectAnimOffset: _effectAnimOffsets[_effect] !== undefined ? _effectAnimOffsets[_effect] : 16
@@ -0,0 +1,56 @@
pragma Singleton
pragma ComponentBehavior: Bound
import QtQuick
import Quickshell
Singleton {
id: root
property int revision: 0
property int appliedRevision: 0
readonly property bool ready: appliedRevision >= revision
// Latched: surfaces render the last compositor-acknowledged state until the atomic flip on ack
property bool effectiveFrameEnabled: false
property string effectiveFrameMode: "connected"
readonly property bool effectiveConnectedFrameModeActive: effectiveFrameEnabled && effectiveFrameMode === "connected"
signal transitionRequested(int revision)
function begin() {
revision++;
transitionRequested(revision);
return revision;
}
function acknowledge(requestRevision) {
if (requestRevision > appliedRevision)
appliedRevision = requestRevision;
}
function syncEffective() {
effectiveFrameEnabled = SettingsData.frameEnabled;
effectiveFrameMode = SettingsData.frameMode;
}
onReadyChanged: {
if (ready)
syncEffective();
}
// Tracks settings-load changes; live toggles begin() first (ready false) so the latch holds
Connections {
target: SettingsData
function onFrameEnabledChanged() {
if (root.ready)
root.syncEffective();
}
function onFrameModeChanged() {
if (root.ready)
root.syncEffective();
}
}
Component.onCompleted: syncEffective()
}
+39 -3
View File
@@ -266,7 +266,11 @@ Singleton {
}
property bool frameEnabled: false
onFrameEnabledChanged: saveSettings()
onFrameEnabledChanged: {
saveSettings();
if (!_loading)
updateFrameCompositorLayout();
}
property real frameThickness: 16
onFrameThicknessChanged: saveSettings()
property int barInsetPaddingShared: -1
@@ -299,7 +303,11 @@ Singleton {
onFrameLauncherEdgeHoverChanged: saveSettings()
readonly property string frameModalEmergeSide: frameLauncherEmergeSide === "top" ? "bottom" : "top"
property string frameMode: "connected"
onFrameModeChanged: saveSettings()
onFrameModeChanged: {
saveSettings();
if (!_loading && frameEnabled)
updateFrameCompositorLayout();
}
property var connectedFrameBarStyleBackups: ({})
onConnectedFrameBarStyleBackupsChanged: saveSettings()
readonly property bool connectedFrameModeActive: frameEnabled && frameMode === "connected"
@@ -1012,6 +1020,13 @@ Singleton {
}
]
function _standaloneBarXrayAvailable(configs) {
const activeBars = (configs || []).filter(c => c && c.enabled && (c.visible ?? true));
return activeBars.every(c => !c.autoHide);
}
readonly property bool standaloneBarXrayAvailable: _standaloneBarXrayAvailable(barConfigs)
property bool desktopClockEnabled: false
property string desktopClockStyle: "analog"
property real desktopClockTransparency: 0.8
@@ -1456,6 +1471,17 @@ Singleton {
MangoService.generateLayoutConfig();
}
function updateFrameCompositorLayout() {
// Generate before begin() so compositor readiness is already pending at transitionRequested
if (typeof CompositorService !== "undefined") {
if (CompositorService.isNiri && typeof NiriService !== "undefined")
NiriService.generateNiriLayoutConfig(true);
if (CompositorService.isHyprland && typeof HyprlandService !== "undefined")
HyprlandService.generateLayoutConfig(true);
}
FrameTransitionState.begin();
}
function resolveIconTheme() {
if (iconThemePerMode && typeof SessionData !== "undefined" && SessionData.isLightMode)
return iconThemeLight;
@@ -2403,13 +2429,17 @@ Singleton {
if (index === -1)
return;
const positionChanged = updates.position !== undefined && configs[index].position !== updates.position;
const barXrayTargetWasAvailable = _standaloneBarXrayAvailable(configs);
if (updates.autoHide === false || updates.visible === false)
setBarIpcReveal(barId, false);
Object.assign(configs[index], updates);
barConfigs = _sanitizeBarConfigsForConnectedFrame(configs).configs;
const sanitizedConfigs = _sanitizeBarConfigsForConnectedFrame(configs).configs;
barConfigs = sanitizedConfigs;
updateBarConfigs();
if (!frameEnabled && _standaloneBarXrayAvailable(sanitizedConfigs) !== barXrayTargetWasAvailable)
updateCompositorLayout();
if (positionChanged) {
NotificationService.dismissAllPopups();
}
@@ -3542,6 +3572,9 @@ Singleton {
onLoaded: {
if (isGreeterMode)
return;
const wasLoaded = _hasLoaded;
const prevFrameEnabled = frameEnabled;
const prevFrameMode = frameMode;
_loading = true;
_hasUnsavedChanges = false;
try {
@@ -3576,6 +3609,9 @@ Singleton {
} finally {
_loading = false;
}
// External edits reload under _loading, which skips the per-property transition triggers
if (wasLoaded && !_parseError && (frameEnabled !== prevFrameEnabled || (frameEnabled && frameMode !== prevFrameMode)))
updateFrameCompositorLayout();
}
onLoadFailed: error => {
if (!isGreeterMode) {
+1 -1
View File
@@ -1076,7 +1076,7 @@ Singleton {
readonly property real connectedCornerRadius: {
if (typeof SettingsData === "undefined")
return 12;
return SettingsData.connectedFrameModeActive ? SettingsData.frameRounding : cornerRadius;
return FrameTransitionState.effectiveConnectedFrameModeActive ? SettingsData.frameRounding : cornerRadius;
}
readonly property color connectedSurfaceColor: {
if (typeof SettingsData === "undefined")