mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-08-01 19:18:28 -04:00
refactor: (modals/popouts): sync functions & improve blur calculations across modals
This commit is contained in:
@@ -162,37 +162,16 @@ Item {
|
||||
_publishModalChromeState();
|
||||
}
|
||||
|
||||
property bool _animSyncQueued: false
|
||||
property bool _bodySyncQueued: false
|
||||
|
||||
function _queueFullSync() {
|
||||
_fullSyncPending = true;
|
||||
if (!_syncTimer.running)
|
||||
_syncTimer.restart();
|
||||
}
|
||||
function _queueAnimSync() {
|
||||
_animSyncQueued = true;
|
||||
if (!_syncTimer.running)
|
||||
_syncTimer.restart();
|
||||
}
|
||||
function _queueBodySync() {
|
||||
_bodySyncQueued = true;
|
||||
if (!_syncTimer.running)
|
||||
_syncTimer.restart();
|
||||
}
|
||||
function _flushSync() {
|
||||
const fullDirty = _fullSyncPending;
|
||||
const animDirty = _animSyncQueued;
|
||||
const bodyDirty = _bodySyncQueued;
|
||||
if (!_fullSyncPending)
|
||||
return;
|
||||
_fullSyncPending = false;
|
||||
_animSyncQueued = false;
|
||||
_bodySyncQueued = false;
|
||||
if (fullDirty)
|
||||
_syncModalChromeState();
|
||||
if (animDirty)
|
||||
_syncModalAnim();
|
||||
if (bodyDirty)
|
||||
_syncModalBody();
|
||||
_syncModalChromeState();
|
||||
}
|
||||
|
||||
function _syncModalAnim() {
|
||||
@@ -216,10 +195,11 @@ Item {
|
||||
onFrameOwnsConnectedChromeChanged: _syncModalChromeState()
|
||||
onResolvedConnectedBarSideChanged: _queueFullSync()
|
||||
onShouldBeVisibleChanged: _queueFullSync()
|
||||
onAlignedXChanged: _queueBodySync()
|
||||
onAlignedYChanged: _queueBodySync()
|
||||
onAlignedWidthChanged: _queueBodySync()
|
||||
onAlignedHeightChanged: _queueBodySync()
|
||||
// Low resource scalar writes: publish synchronously to stay in the same frame
|
||||
onAlignedXChanged: _syncModalBody()
|
||||
onAlignedYChanged: _syncModalBody()
|
||||
onAlignedWidthChanged: _syncModalBody()
|
||||
onAlignedHeightChanged: _syncModalBody()
|
||||
|
||||
Connections {
|
||||
target: contentWindow
|
||||
@@ -613,9 +593,9 @@ Item {
|
||||
readonly property real scaleValue: computedScaleCollapsed + (1.0 - computedScaleCollapsed) * morph.openProgress
|
||||
|
||||
onAnimXChanged: if (root.frameOwnsConnectedChrome)
|
||||
root._queueAnimSync()
|
||||
root._syncModalAnim()
|
||||
onAnimYChanged: if (root.frameOwnsConnectedChrome)
|
||||
root._queueAnimSync()
|
||||
root._syncModalAnim()
|
||||
|
||||
Item {
|
||||
id: contentContainer
|
||||
|
||||
@@ -244,11 +244,11 @@ Item {
|
||||
WindowBlur {
|
||||
targetWindow: contentWindow
|
||||
readonly property real s: Math.min(1, modalContainer.scaleValue)
|
||||
readonly property real op: Math.max(0, Math.min(1, (morph.openProgress - 0.06) * 2))
|
||||
blurX: modalContainer.x + modalContainer.width * (1 - s * op) * 0.5 + Theme.snap(modalContainer.animX, root.dpr)
|
||||
blurY: modalContainer.y + modalContainer.height * (1 - s * op) * 0.5 + Theme.snap(modalContainer.animY, root.dpr)
|
||||
blurWidth: root.shouldBeVisible ? modalContainer.width * s * op : 0
|
||||
blurHeight: root.shouldBeVisible ? modalContainer.height * s * op : 0
|
||||
// Blur tracks the surface's scaled rect, matching the connected backend.
|
||||
blurX: modalContainer.x + modalContainer.width * (1 - s) * 0.5 + Theme.snap(modalContainer.animX, root.dpr)
|
||||
blurY: modalContainer.y + modalContainer.height * (1 - s) * 0.5 + Theme.snap(modalContainer.animY, root.dpr)
|
||||
blurWidth: root.shouldBeVisible ? modalContainer.width * s : 0
|
||||
blurHeight: root.shouldBeVisible ? modalContainer.height * s : 0
|
||||
blurRadius: root.cornerRadius
|
||||
}
|
||||
|
||||
|
||||
@@ -364,11 +364,11 @@ Item {
|
||||
WindowBlur {
|
||||
targetWindow: launcherWindow
|
||||
readonly property real s: Math.min(1, modalContainer.publishedScale)
|
||||
readonly property real op: Math.max(0, Math.min(1, (modalContainer.publishedOpacity - 0.06) * 2))
|
||||
blurX: modalContainer.x + modalContainer.width * (1 - s * op) * 0.5
|
||||
blurY: modalContainer.y + modalContainer.height * (1 - s * op) * 0.5
|
||||
blurWidth: contentVisible ? modalContainer.width * s * op : 0
|
||||
blurHeight: contentVisible ? modalContainer.height * s * op : 0
|
||||
// Blur tracks the surface's scaled rect
|
||||
blurX: modalContainer.x + modalContainer.width * (1 - s) * 0.5
|
||||
blurY: modalContainer.y + modalContainer.height * (1 - s) * 0.5
|
||||
blurWidth: contentVisible ? modalContainer.width * s : 0
|
||||
blurHeight: contentVisible ? modalContainer.height * s : 0
|
||||
blurRadius: root.cornerRadius
|
||||
}
|
||||
|
||||
|
||||
@@ -154,10 +154,12 @@ Singleton {
|
||||
continue;
|
||||
if (!x || !y)
|
||||
return false;
|
||||
// Only niri's enriched snapshots support value comparison.
|
||||
if (x.niriWindowId === undefined || y.niriWindowId === undefined)
|
||||
// Only niri/mango enriched snapshots support value comparison
|
||||
const xKey = x.niriWindowId !== undefined ? x.niriWindowId : x.mangoWindowId;
|
||||
const yKey = y.niriWindowId !== undefined ? y.niriWindowId : y.mangoWindowId;
|
||||
if (xKey === undefined || yKey === undefined)
|
||||
return false;
|
||||
if (x.niriWindowId !== y.niriWindowId || x.niriWorkspaceId !== y.niriWorkspaceId || x.appId !== y.appId || x.title !== y.title || !!x.activated !== !!y.activated || !!x.fullscreen !== !!y.fullscreen || !!x.maximized !== !!y.maximized || !!x.minimized !== !!y.minimized)
|
||||
if (xKey !== yKey || x.niriWorkspaceId !== y.niriWorkspaceId || x.appId !== y.appId || x.title !== y.title || !!x.activated !== !!y.activated || !!x.fullscreen !== !!y.fullscreen || !!x.maximized !== !!y.maximized || !!x.minimized !== !!y.minimized)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -39,6 +39,8 @@ Item {
|
||||
property bool fullHeightSurface: false
|
||||
property bool _primeContent: false
|
||||
property bool _contentWarm: false
|
||||
// Keyboard focus grabbed one tick after emerge starts, to avoid stalling first frames.
|
||||
property bool _keyboardReady: false
|
||||
property bool _resizeActive: false
|
||||
property real _chromeAnimTravelX: 1
|
||||
property real _chromeAnimTravelY: 1
|
||||
@@ -241,7 +243,8 @@ Item {
|
||||
}
|
||||
|
||||
function _connectedChromeState(visibleOverride) {
|
||||
const visible = visibleOverride !== undefined ? !!visibleOverride : contentWindow.visible;
|
||||
// Track intent rather than the transient wl_surface state during remap.
|
||||
const visible = visibleOverride !== undefined ? !!visibleOverride : (contentWindow.visible || root.shouldBeVisible);
|
||||
const presented = contentWindow.visible || root.shouldBeVisible;
|
||||
const phase = root.isClosing ? "closing" : (!presented ? "hidden" : (!contentWindow.visible && root.shouldBeVisible ? "opening" : "open"));
|
||||
const bodyX = Theme.snap(root.pubBodyX, root.dpr);
|
||||
@@ -353,48 +356,26 @@ Item {
|
||||
_publishedBodyValid = false;
|
||||
}
|
||||
|
||||
property bool _animSyncQueued: false
|
||||
property bool _bodySyncQueued: false
|
||||
|
||||
function _queueFullSync() {
|
||||
_fullSyncQueued = true;
|
||||
if (!_syncTimer.running)
|
||||
_syncTimer.restart();
|
||||
}
|
||||
function _queueAnimSync() {
|
||||
_animSyncQueued = true;
|
||||
if (!_syncTimer.running)
|
||||
_syncTimer.restart();
|
||||
}
|
||||
function _queueBodySync() {
|
||||
_bodySyncQueued = true;
|
||||
if (!_syncTimer.running)
|
||||
_syncTimer.restart();
|
||||
}
|
||||
function _flushSync() {
|
||||
const fullDirty = _fullSyncQueued;
|
||||
const animDirty = _animSyncQueued;
|
||||
const bodyDirty = _bodySyncQueued;
|
||||
if (!_fullSyncQueued)
|
||||
return;
|
||||
_fullSyncQueued = false;
|
||||
_animSyncQueued = false;
|
||||
_bodySyncQueued = false;
|
||||
if (fullDirty)
|
||||
_syncPopoutChromeState();
|
||||
if (animDirty) {
|
||||
_syncPopoutAnim("x");
|
||||
_syncPopoutAnim("y");
|
||||
}
|
||||
if (bodyDirty)
|
||||
_syncPopoutBody();
|
||||
_syncPopoutChromeState();
|
||||
}
|
||||
|
||||
onAlignedXChanged: _queueFullSync()
|
||||
onAlignedYChanged: _queueFullSync()
|
||||
onAlignedWidthChanged: _queueFullSync()
|
||||
onContentAnimXChanged: _queueAnimSync()
|
||||
onContentAnimYChanged: _queueAnimSync()
|
||||
onRenderedAlignedYChanged: _queueBodySync()
|
||||
onRenderedAlignedHeightChanged: _queueBodySync()
|
||||
// Cheap deduped scalar writes: publish synchronously to stay in the same frame.
|
||||
onContentAnimXChanged: _syncPopoutAnim("x")
|
||||
onContentAnimYChanged: _syncPopoutAnim("y")
|
||||
onRenderedAlignedYChanged: _syncPopoutBody()
|
||||
onRenderedAlignedHeightChanged: _syncPopoutBody()
|
||||
onScreenChanged: {
|
||||
_resetPublishedBody();
|
||||
_queueFullSync();
|
||||
@@ -517,6 +498,10 @@ Item {
|
||||
|
||||
animationsEnabled = true;
|
||||
shouldBeVisible = true;
|
||||
Qt.callLater(() => {
|
||||
if (root.shouldBeVisible)
|
||||
root._keyboardReady = true;
|
||||
});
|
||||
if (shouldBeVisible && screen) {
|
||||
opened();
|
||||
}
|
||||
@@ -530,6 +515,7 @@ Item {
|
||||
_resetPublishedBody();
|
||||
isClosing = true;
|
||||
shouldBeVisible = false;
|
||||
_keyboardReady = false;
|
||||
_primeContent = false;
|
||||
PopoutManager.popoutChanged();
|
||||
closeTimer.restart();
|
||||
@@ -743,9 +729,9 @@ Item {
|
||||
readonly property real pubBodyW: morphSeedW + (alignedWidth - morphSeedW) * morphProgress
|
||||
readonly property real pubBodyH: morphSeedH + (renderedAlignedHeight - morphSeedH) * morphProgress
|
||||
|
||||
// One animation drives all four coordinates, so queue one coalesced state update
|
||||
// per progress tick instead of reacting independently to each derived property.
|
||||
onMorphProgressChanged: _queueBodySync()
|
||||
// One animation drives all four coordinates, so publish once per progress
|
||||
// tick instead of reacting independently to each derived property.
|
||||
onMorphProgressChanged: _syncPopoutBody()
|
||||
|
||||
function _beginMorphTravel() {
|
||||
morphTravelEnabled = false;
|
||||
@@ -967,7 +953,7 @@ Item {
|
||||
WlrLayershell.namespace: root.layerNamespace
|
||||
WlrLayershell.layer: root.effectivePopoutLayer
|
||||
WlrLayershell.exclusiveZone: -1
|
||||
WlrLayershell.keyboardFocus: KeyboardFocus.keyboardFocus(shouldBeVisible, customKeyboardFocus)
|
||||
WlrLayershell.keyboardFocus: KeyboardFocus.keyboardFocus(shouldBeVisible && root._keyboardReady, customKeyboardFocus)
|
||||
|
||||
readonly property bool _fullHeight: root.fullHeightSurface
|
||||
anchors {
|
||||
|
||||
@@ -620,13 +620,13 @@ Item {
|
||||
id: popoutBlur
|
||||
targetWindow: contentWindow
|
||||
readonly property real s: Math.min(1, contentContainer.scaleValue)
|
||||
readonly property real op: Math.max(0, Math.min(1, (morph.openProgress - 0.08) * 1.6))
|
||||
readonly property bool revealClipActive: root.fluidStandaloneActive
|
||||
|
||||
blurX: revealClipActive ? contentContainer.x : contentContainer.x + contentContainer.width * (1 - s * op) * 0.5 + Theme.snap(contentContainer.animX, root.dpr)
|
||||
blurY: revealClipActive ? contentContainer.y : contentContainer.y + contentContainer.height * (1 - s * op) * 0.5 + Theme.snap(contentContainer.animY, root.dpr)
|
||||
blurWidth: root.shouldBeVisible ? (revealClipActive ? contentContainer.width : contentContainer.width * s * op) : 0
|
||||
blurHeight: root.shouldBeVisible ? (revealClipActive ? contentContainer.height : contentContainer.height * s * op) : 0
|
||||
// Blur tracks the surface's scaled rect, matching the connected backend
|
||||
blurX: revealClipActive ? contentContainer.x : contentContainer.x + contentContainer.width * (1 - s) * 0.5 + Theme.snap(contentContainer.animX, root.dpr)
|
||||
blurY: revealClipActive ? contentContainer.y : contentContainer.y + contentContainer.height * (1 - s) * 0.5 + Theme.snap(contentContainer.animY, root.dpr)
|
||||
blurWidth: root.shouldBeVisible ? (revealClipActive ? contentContainer.width : contentContainer.width * s) : 0
|
||||
blurHeight: root.shouldBeVisible ? (revealClipActive ? contentContainer.height : contentContainer.height * s) : 0
|
||||
blurRadius: Theme.cornerRadius
|
||||
clipEnabled: revealClipActive
|
||||
clipX: contentContainer.x + contentContainer.revealX
|
||||
|
||||
@@ -99,8 +99,9 @@ Item {
|
||||
root._clear();
|
||||
}
|
||||
function onResourcesLost() {
|
||||
lifecycleKickAction.cancel();
|
||||
root._clear();
|
||||
// Re-arm so blur self-heals since instances are no longer recreated per open
|
||||
root._scheduleLifecycleKick();
|
||||
}
|
||||
function onWindowConnected() {
|
||||
root._scheduleLifecycleKick();
|
||||
|
||||
Reference in New Issue
Block a user