mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-06-07 19:59:14 -04:00
refactor(frame): improve connected mode surface recovery
- share modal and launcher ownership handling - recover missing background and blur layers
This commit is contained in:
@@ -0,0 +1,125 @@
|
|||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
required property var modalHandle
|
||||||
|
required property string claimPrefix
|
||||||
|
property string screenName: ""
|
||||||
|
property bool enabled: false
|
||||||
|
property bool active: false
|
||||||
|
property bool presented: false
|
||||||
|
property bool dockBlocked: false
|
||||||
|
property string dockSide: ""
|
||||||
|
|
||||||
|
property string claimId: ""
|
||||||
|
property string claimedScreenName: ""
|
||||||
|
|
||||||
|
signal recoveryRequested
|
||||||
|
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
function _nextClaimId() {
|
||||||
|
return claimPrefix + ":" + (new Date()).getTime() + ":" + Math.floor(Math.random() * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _isCurrentModal(name) {
|
||||||
|
return !!name && ModalManager.isCurrentModal(modalHandle, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _shouldRecover() {
|
||||||
|
return active && enabled && _isCurrentModal(screenName);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _requestRecovery() {
|
||||||
|
if (_shouldRecover())
|
||||||
|
recoveryRequested();
|
||||||
|
}
|
||||||
|
|
||||||
|
function publish(state) {
|
||||||
|
if (!enabled || !screenName || !state) {
|
||||||
|
release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (claimedScreenName && claimedScreenName !== screenName)
|
||||||
|
release();
|
||||||
|
|
||||||
|
const isCurrent = _isCurrentModal(screenName);
|
||||||
|
let isClaim = !claimId;
|
||||||
|
if (isClaim && !isCurrent)
|
||||||
|
return false;
|
||||||
|
if (isClaim)
|
||||||
|
claimId = _nextClaimId();
|
||||||
|
|
||||||
|
let published = isClaim ? ConnectedModeState.claimModalState(screenName, state, claimId) : ConnectedModeState.ensureModalState(screenName, state, claimId);
|
||||||
|
if (!published && !isClaim && isCurrent) {
|
||||||
|
ConnectedModeState.releaseDockRetract(claimId);
|
||||||
|
claimId = _nextClaimId();
|
||||||
|
published = ConnectedModeState.claimModalState(screenName, state, claimId);
|
||||||
|
}
|
||||||
|
if (!published)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
claimedScreenName = screenName;
|
||||||
|
if (dockBlocked && presented)
|
||||||
|
ConnectedModeState.requestDockRetract(claimId, screenName, dockSide);
|
||||||
|
else
|
||||||
|
ConnectedModeState.releaseDockRetract(claimId);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateAnim(animX, animY) {
|
||||||
|
if (!enabled || !claimId || !claimedScreenName)
|
||||||
|
return false;
|
||||||
|
if (!ConnectedModeState.hasModalOwner(claimedScreenName, claimId)) {
|
||||||
|
_requestRecovery();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ConnectedModeState.setModalAnim(claimedScreenName, animX, animY, claimId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateBody(bodyX, bodyY, bodyW, bodyH) {
|
||||||
|
if (!enabled || !claimId || !claimedScreenName)
|
||||||
|
return false;
|
||||||
|
if (!ConnectedModeState.hasModalOwner(claimedScreenName, claimId)) {
|
||||||
|
_requestRecovery();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ConnectedModeState.setModalBody(claimedScreenName, bodyX, bodyY, bodyW, bodyH, claimId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function release() {
|
||||||
|
if (!claimId)
|
||||||
|
return;
|
||||||
|
ConnectedModeState.releaseDockRetract(claimId);
|
||||||
|
const releasedClaimId = claimId;
|
||||||
|
const releasedScreenName = claimedScreenName;
|
||||||
|
claimId = "";
|
||||||
|
claimedScreenName = "";
|
||||||
|
if (releasedScreenName)
|
||||||
|
ConnectedModeState.clearModalState(releasedScreenName, releasedClaimId);
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onDestruction: release()
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: ModalManager
|
||||||
|
function onModalChanged() {
|
||||||
|
root._requestRecovery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: ConnectedModeState
|
||||||
|
function onModalOwnersChanged() {
|
||||||
|
if (!ConnectedModeState.hasModalOwner(root.screenName, root.claimId))
|
||||||
|
root._requestRecovery();
|
||||||
|
}
|
||||||
|
function onModalStatesChanged() {
|
||||||
|
if (!ConnectedModeState.modalStates[root.screenName])
|
||||||
|
root._requestRecovery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -38,6 +38,10 @@ Singleton {
|
|||||||
// Dock slide offsets — hot-path updates separated from full geometry state
|
// Dock slide offsets — hot-path updates separated from full geometry state
|
||||||
property var dockSlides: ({})
|
property var dockSlides: ({})
|
||||||
|
|
||||||
|
// Surfaces are keyed by screen.name. FrameWindow watches to refresh connected chrome
|
||||||
|
// after claim/release boundaries without tracking each animation frame
|
||||||
|
property var surfaceRevisions: ({})
|
||||||
|
|
||||||
function _cloneDict(src) {
|
function _cloneDict(src) {
|
||||||
const next = {};
|
const next = {};
|
||||||
for (const k in src)
|
for (const k in src)
|
||||||
@@ -45,16 +49,31 @@ Singleton {
|
|||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _bumpSurfaceRevision(screenName) {
|
||||||
|
if (!screenName)
|
||||||
|
return;
|
||||||
|
const next = _cloneDict(surfaceRevisions);
|
||||||
|
next[screenName] = Number(next[screenName] || 0) + 1;
|
||||||
|
surfaceRevisions = next;
|
||||||
|
}
|
||||||
|
|
||||||
function hasPopoutOwner(claimId) {
|
function hasPopoutOwner(claimId) {
|
||||||
return !!claimId && popoutOwnerId === claimId;
|
return !!claimId && popoutOwnerId === claimId;
|
||||||
}
|
}
|
||||||
|
|
||||||
function claimPopout(claimId, state) {
|
function claimPopout(claimId, state) {
|
||||||
if (!claimId)
|
if (!claimId || !state)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
const previousScreen = popoutScreen;
|
||||||
popoutOwnerId = claimId;
|
popoutOwnerId = claimId;
|
||||||
return updatePopout(claimId, state);
|
const ok = updatePopout(claimId, state);
|
||||||
|
if (ok) {
|
||||||
|
if (previousScreen && previousScreen !== popoutScreen)
|
||||||
|
_bumpSurfaceRevision(previousScreen);
|
||||||
|
_bumpSurfaceRevision(popoutScreen);
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatePopout(claimId, state) {
|
function updatePopout(claimId, state) {
|
||||||
@@ -91,6 +110,7 @@ Singleton {
|
|||||||
if (!hasPopoutOwner(claimId))
|
if (!hasPopoutOwner(claimId))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
const releasedScreen = popoutScreen;
|
||||||
popoutOwnerId = "";
|
popoutOwnerId = "";
|
||||||
popoutVisible = false;
|
popoutVisible = false;
|
||||||
popoutBarSide = "top";
|
popoutBarSide = "top";
|
||||||
@@ -103,6 +123,7 @@ Singleton {
|
|||||||
popoutScreen = "";
|
popoutScreen = "";
|
||||||
popoutOmitStartConnector = false;
|
popoutOmitStartConnector = false;
|
||||||
popoutOmitEndConnector = false;
|
popoutOmitEndConnector = false;
|
||||||
|
_bumpSurfaceRevision(releasedScreen);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,10 +195,13 @@ Singleton {
|
|||||||
const normalized = _normalizeDockState(state);
|
const normalized = _normalizeDockState(state);
|
||||||
if (_sameDockState(dockStates[screenName], normalized))
|
if (_sameDockState(dockStates[screenName], normalized))
|
||||||
return true;
|
return true;
|
||||||
|
const previous = dockStates[screenName] || emptyDockState;
|
||||||
|
|
||||||
const next = _cloneDict(dockStates);
|
const next = _cloneDict(dockStates);
|
||||||
next[screenName] = normalized;
|
next[screenName] = normalized;
|
||||||
dockStates = next;
|
dockStates = next;
|
||||||
|
if (!!previous.reveal !== !!normalized.reveal)
|
||||||
|
_bumpSurfaceRevision(screenName);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,6 +219,7 @@ Singleton {
|
|||||||
delete nextSlides[screenName];
|
delete nextSlides[screenName];
|
||||||
dockSlides = nextSlides;
|
dockSlides = nextSlides;
|
||||||
}
|
}
|
||||||
|
_bumpSurfaceRevision(screenName);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,10 +285,13 @@ Singleton {
|
|||||||
const normalized = _normalizeNotificationState(state);
|
const normalized = _normalizeNotificationState(state);
|
||||||
if (_sameNotificationState(notificationStates[screenName], normalized))
|
if (_sameNotificationState(notificationStates[screenName], normalized))
|
||||||
return true;
|
return true;
|
||||||
|
const previous = notificationStates[screenName] || emptyNotificationState;
|
||||||
|
|
||||||
const next = _cloneDict(notificationStates);
|
const next = _cloneDict(notificationStates);
|
||||||
next[screenName] = normalized;
|
next[screenName] = normalized;
|
||||||
notificationStates = next;
|
notificationStates = next;
|
||||||
|
if (!!previous.visible !== !!normalized.visible)
|
||||||
|
_bumpSurfaceRevision(screenName);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,6 +302,7 @@ Singleton {
|
|||||||
const next = _cloneDict(notificationStates);
|
const next = _cloneDict(notificationStates);
|
||||||
delete next[screenName];
|
delete next[screenName];
|
||||||
notificationStates = next;
|
notificationStates = next;
|
||||||
|
_bumpSurfaceRevision(screenName);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,18 +359,17 @@ Singleton {
|
|||||||
modalOwners = nextOwners;
|
modalOwners = nextOwners;
|
||||||
}
|
}
|
||||||
const normalized = _normalizeModalState(state);
|
const normalized = _normalizeModalState(state);
|
||||||
if (_sameModalState(modalStates[screenName], normalized))
|
|
||||||
return true;
|
|
||||||
const next = _cloneDict(modalStates);
|
const next = _cloneDict(modalStates);
|
||||||
next[screenName] = normalized;
|
next[screenName] = normalized;
|
||||||
modalStates = next;
|
modalStates = next;
|
||||||
|
_bumpSurfaceRevision(screenName);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateModalState(screenName, state, ownerId) {
|
function updateModalState(screenName, state, ownerId) {
|
||||||
if (!screenName || !state)
|
if (!screenName || !state)
|
||||||
return false;
|
return false;
|
||||||
if (ownerId && modalOwners[screenName] && modalOwners[screenName] !== ownerId)
|
if (ownerId && modalOwners[screenName] !== ownerId)
|
||||||
return false;
|
return false;
|
||||||
const normalized = _normalizeModalState(state);
|
const normalized = _normalizeModalState(state);
|
||||||
if (_sameModalState(modalStates[screenName], normalized))
|
if (_sameModalState(modalStates[screenName], normalized))
|
||||||
@@ -352,30 +380,50 @@ Singleton {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasModalOwner(screenName, ownerId) {
|
||||||
|
return !!screenName && !!ownerId && modalOwners[screenName] === ownerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ensureModalState(screenName, state, ownerId) {
|
||||||
|
if (!screenName || !state || !ownerId)
|
||||||
|
return false;
|
||||||
|
const currentOwner = modalOwners[screenName] || "";
|
||||||
|
if (currentOwner && currentOwner !== ownerId)
|
||||||
|
return false;
|
||||||
|
if (!currentOwner)
|
||||||
|
return claimModalState(screenName, state, ownerId);
|
||||||
|
return updateModalState(screenName, state, ownerId);
|
||||||
|
}
|
||||||
|
|
||||||
function setModalState(screenName, state) {
|
function setModalState(screenName, state) {
|
||||||
return updateModalState(screenName, state, null);
|
return updateModalState(screenName, state, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearModalState(screenName, ownerId) {
|
function clearModalState(screenName, ownerId) {
|
||||||
if (!screenName || !modalStates[screenName])
|
if (!screenName)
|
||||||
return false;
|
return false;
|
||||||
if (ownerId && modalOwners[screenName] && modalOwners[screenName] !== ownerId)
|
if (ownerId && modalOwners[screenName] !== ownerId)
|
||||||
|
return false;
|
||||||
|
if (!modalStates[screenName] && !modalOwners[screenName])
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (modalStates[screenName]) {
|
||||||
const next = _cloneDict(modalStates);
|
const next = _cloneDict(modalStates);
|
||||||
delete next[screenName];
|
delete next[screenName];
|
||||||
modalStates = next;
|
modalStates = next;
|
||||||
|
}
|
||||||
|
|
||||||
if (modalOwners[screenName]) {
|
if (modalOwners[screenName]) {
|
||||||
const nextOwners = _cloneDict(modalOwners);
|
const nextOwners = _cloneDict(modalOwners);
|
||||||
delete nextOwners[screenName];
|
delete nextOwners[screenName];
|
||||||
modalOwners = nextOwners;
|
modalOwners = nextOwners;
|
||||||
}
|
}
|
||||||
|
_bumpSurfaceRevision(screenName);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setModalAnim(screenName, animX, animY, ownerId) {
|
function setModalAnim(screenName, animX, animY, ownerId) {
|
||||||
if (ownerId && modalOwners[screenName] && modalOwners[screenName] !== ownerId)
|
if (ownerId && modalOwners[screenName] !== ownerId)
|
||||||
return false;
|
return false;
|
||||||
const cur = screenName ? modalStates[screenName] : null;
|
const cur = screenName ? modalStates[screenName] : null;
|
||||||
if (!cur)
|
if (!cur)
|
||||||
@@ -394,7 +442,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setModalBody(screenName, bodyX, bodyY, bodyW, bodyH, ownerId) {
|
function setModalBody(screenName, bodyX, bodyY, bodyW, bodyH, ownerId) {
|
||||||
if (ownerId && modalOwners[screenName] && modalOwners[screenName] !== ownerId)
|
if (ownerId && modalOwners[screenName] !== ownerId)
|
||||||
return false;
|
return false;
|
||||||
const cur = screenName ? modalStates[screenName] : null;
|
const cur = screenName ? modalStates[screenName] : null;
|
||||||
if (!cur)
|
if (!cur)
|
||||||
@@ -492,6 +540,9 @@ Singleton {
|
|||||||
const nextModalOwners = pruneKeyed(modalOwners);
|
const nextModalOwners = pruneKeyed(modalOwners);
|
||||||
if (nextModalOwners !== null)
|
if (nextModalOwners !== null)
|
||||||
modalOwners = nextModalOwners;
|
modalOwners = nextModalOwners;
|
||||||
|
const nextSurfaceRevisions = pruneKeyed(surfaceRevisions);
|
||||||
|
if (nextSurfaceRevisions !== null)
|
||||||
|
surfaceRevisions = nextSurfaceRevisions;
|
||||||
|
|
||||||
let retractChanged = false;
|
let retractChanged = false;
|
||||||
const nextRetract = {};
|
const nextRetract = {};
|
||||||
@@ -512,7 +563,12 @@ Singleton {
|
|||||||
Connections {
|
Connections {
|
||||||
target: Quickshell
|
target: Quickshell
|
||||||
function onScreensChanged() {
|
function onScreensChanged() {
|
||||||
root._pruneToLiveScreens();
|
screenPruneAction.schedule();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DeferredAction {
|
||||||
|
id: screenPruneAction
|
||||||
|
onTriggered: root._pruneToLiveScreens()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ Singleton {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isCurrentModal(modal, screenName) {
|
||||||
|
const name = screenName || modal?.effectiveScreen?.name || "unknown";
|
||||||
|
return currentModalsByScreen[name] === modal;
|
||||||
|
}
|
||||||
|
|
||||||
function closeModal(modal) {
|
function closeModal(modal) {
|
||||||
const screenName = modal.effectiveScreen?.name ?? "unknown";
|
const screenName = modal.effectiveScreen?.name ?? "unknown";
|
||||||
if (currentModalsByScreen[screenName] === modal) {
|
if (currentModalsByScreen[screenName] === modal) {
|
||||||
|
|||||||
@@ -98,6 +98,11 @@ Singleton {
|
|||||||
return currentPopoutsByScreen[screen.name] || null;
|
return currentPopoutsByScreen[screen.name] || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isCurrentPopout(popout, screenName) {
|
||||||
|
const name = screenName || popout?.screen?.name || "";
|
||||||
|
return !!name && currentPopoutsByScreen[name] === popout;
|
||||||
|
}
|
||||||
|
|
||||||
function requestPopout(popout, tabIndex, triggerSource) {
|
function requestPopout(popout, tabIndex, triggerSource) {
|
||||||
if (!popout || !popout.screen)
|
if (!popout || !popout.screen)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -105,21 +105,26 @@ Item {
|
|||||||
|
|
||||||
property bool animationsEnabled: true
|
property bool animationsEnabled: true
|
||||||
|
|
||||||
property string _chromeClaimId: ""
|
|
||||||
property bool _fullSyncPending: false
|
property bool _fullSyncPending: false
|
||||||
|
|
||||||
function _nextChromeClaimId() {
|
|
||||||
return layerNamespace + ":modal:" + (new Date()).getTime() + ":" + Math.floor(Math.random() * 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _currentScreenName() {
|
function _currentScreenName() {
|
||||||
return effectiveScreen ? effectiveScreen.name : "";
|
return effectiveScreen ? effectiveScreen.name : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
function _publishModalChromeState(isClaim) {
|
ConnectedModalChrome {
|
||||||
const screenName = _currentScreenName();
|
id: modalChrome
|
||||||
if (!screenName)
|
modalHandle: root.modalHandle
|
||||||
return;
|
claimPrefix: root.layerNamespace + ":modal"
|
||||||
|
screenName: root._currentScreenName()
|
||||||
|
enabled: root.frameOwnsConnectedChrome
|
||||||
|
active: root.shouldBeVisible
|
||||||
|
presented: root.shouldBeVisible || contentWindow.visible
|
||||||
|
dockBlocked: root._dockBlocksEmergence
|
||||||
|
dockSide: root.resolvedConnectedBarSide
|
||||||
|
onRecoveryRequested: root._queueFullSync()
|
||||||
|
}
|
||||||
|
|
||||||
|
function _publishModalChromeState() {
|
||||||
const state = {
|
const state = {
|
||||||
"visible": shouldBeVisible || contentWindow.visible,
|
"visible": shouldBeVisible || contentWindow.visible,
|
||||||
"barSide": resolvedConnectedBarSide,
|
"barSide": resolvedConnectedBarSide,
|
||||||
@@ -132,25 +137,11 @@ Item {
|
|||||||
"omitStartConnector": false,
|
"omitStartConnector": false,
|
||||||
"omitEndConnector": false
|
"omitEndConnector": false
|
||||||
};
|
};
|
||||||
if (isClaim)
|
return modalChrome.publish(state);
|
||||||
ConnectedModeState.claimModalState(screenName, state, _chromeClaimId);
|
|
||||||
else
|
|
||||||
ConnectedModeState.updateModalState(screenName, state, _chromeClaimId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function _syncModalChromeState() {
|
function _syncModalChromeState() {
|
||||||
if (!frameOwnsConnectedChrome) {
|
_publishModalChromeState();
|
||||||
_releaseModalChrome();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const isClaim = !_chromeClaimId;
|
|
||||||
if (!_chromeClaimId)
|
|
||||||
_chromeClaimId = _nextChromeClaimId();
|
|
||||||
_publishModalChromeState(isClaim);
|
|
||||||
if (_dockBlocksEmergence && (shouldBeVisible || contentWindow.visible))
|
|
||||||
ConnectedModeState.requestDockRetract(_chromeClaimId, _currentScreenName(), resolvedConnectedBarSide);
|
|
||||||
else
|
|
||||||
ConnectedModeState.releaseDockRetract(_chromeClaimId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
property bool _animSyncQueued: false
|
property bool _animSyncQueued: false
|
||||||
@@ -187,32 +178,21 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _syncModalAnim() {
|
function _syncModalAnim() {
|
||||||
if (!frameOwnsConnectedChrome || !_chromeClaimId)
|
if (!frameOwnsConnectedChrome)
|
||||||
return;
|
return;
|
||||||
const screenName = _currentScreenName();
|
if (!modalContainer)
|
||||||
if (!screenName || !modalContainer)
|
|
||||||
return;
|
return;
|
||||||
ConnectedModeState.setModalAnim(screenName, modalContainer.animX, modalContainer.animY, _chromeClaimId);
|
modalChrome.updateAnim(modalContainer.animX, modalContainer.animY);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _syncModalBody() {
|
function _syncModalBody() {
|
||||||
if (!frameOwnsConnectedChrome || !_chromeClaimId)
|
if (!frameOwnsConnectedChrome)
|
||||||
return;
|
return;
|
||||||
const screenName = _currentScreenName();
|
modalChrome.updateBody(alignedX, alignedY, alignedWidth, alignedHeight);
|
||||||
if (!screenName)
|
|
||||||
return;
|
|
||||||
ConnectedModeState.setModalBody(screenName, alignedX, alignedY, alignedWidth, alignedHeight, _chromeClaimId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function _releaseModalChrome() {
|
function _releaseModalChrome() {
|
||||||
if (!_chromeClaimId)
|
modalChrome.release();
|
||||||
return;
|
|
||||||
ConnectedModeState.releaseDockRetract(_chromeClaimId);
|
|
||||||
const claimId = _chromeClaimId;
|
|
||||||
_chromeClaimId = "";
|
|
||||||
const screenName = _currentScreenName();
|
|
||||||
if (screenName)
|
|
||||||
ConnectedModeState.clearModalState(screenName, claimId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onFrameOwnsConnectedChromeChanged: _syncModalChromeState()
|
onFrameOwnsConnectedChromeChanged: _syncModalChromeState()
|
||||||
@@ -223,8 +203,6 @@ Item {
|
|||||||
onAlignedWidthChanged: _queueBodySync()
|
onAlignedWidthChanged: _queueBodySync()
|
||||||
onAlignedHeightChanged: _queueBodySync()
|
onAlignedHeightChanged: _queueBodySync()
|
||||||
|
|
||||||
Component.onDestruction: _releaseModalChrome()
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: contentWindow
|
target: contentWindow
|
||||||
function onVisibleChanged() {
|
function onVisibleChanged() {
|
||||||
@@ -248,12 +226,12 @@ Item {
|
|||||||
clickCatcher.screen = focusedScreen;
|
clickCatcher.screen = focusedScreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ModalManager.openModal(modalHandle);
|
||||||
if (Theme.isDirectionalEffect || root.useBackground) {
|
if (Theme.isDirectionalEffect || root.useBackground) {
|
||||||
if (!useSingleWindow)
|
if (!useSingleWindow)
|
||||||
clickCatcher.visible = true;
|
clickCatcher.visible = true;
|
||||||
contentWindow.visible = true;
|
contentWindow.visible = true;
|
||||||
}
|
}
|
||||||
ModalManager.openModal(modalHandle);
|
|
||||||
|
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
animationsEnabled = true;
|
animationsEnabled = true;
|
||||||
@@ -317,8 +295,12 @@ Item {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (screenStillExists)
|
if (screenStillExists) {
|
||||||
|
if (root.shouldBeVisible)
|
||||||
|
root._queueFullSync();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
root._releaseModalChrome();
|
||||||
const newScreen = CompositorService.getFocusedScreen();
|
const newScreen = CompositorService.getFocusedScreen();
|
||||||
if (newScreen) {
|
if (newScreen) {
|
||||||
contentWindow.screen = newScreen;
|
contentWindow.screen = newScreen;
|
||||||
|
|||||||
@@ -232,21 +232,26 @@ Item {
|
|||||||
onTriggered: root._flushSync()
|
onTriggered: root._flushSync()
|
||||||
}
|
}
|
||||||
|
|
||||||
property string _chromeClaimId: ""
|
|
||||||
property bool _fullSyncPending: false
|
property bool _fullSyncPending: false
|
||||||
|
|
||||||
function _nextChromeClaimId() {
|
|
||||||
return "dms:launcher-v2:" + (new Date()).getTime() + ":" + Math.floor(Math.random() * 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _currentScreenName() {
|
function _currentScreenName() {
|
||||||
return effectiveScreen ? effectiveScreen.name : "";
|
return effectiveScreen ? effectiveScreen.name : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
function _publishModalChromeState(isClaim) {
|
ConnectedModalChrome {
|
||||||
const screenName = _currentScreenName();
|
id: modalChrome
|
||||||
if (!screenName)
|
modalHandle: root.modalHandle
|
||||||
return;
|
claimPrefix: "dms:launcher-v2"
|
||||||
|
screenName: root._currentScreenName()
|
||||||
|
enabled: root.frameOwnsConnectedChrome
|
||||||
|
active: root.spotlightOpen
|
||||||
|
presented: root.spotlightOpen || contentWindow.visible
|
||||||
|
dockBlocked: root._dockBlocksEmergence
|
||||||
|
dockSide: root.resolvedConnectedBarSide
|
||||||
|
onRecoveryRequested: root._queueFullSync()
|
||||||
|
}
|
||||||
|
|
||||||
|
function _publishModalChromeState() {
|
||||||
const state = {
|
const state = {
|
||||||
"visible": spotlightOpen || contentWindow.visible,
|
"visible": spotlightOpen || contentWindow.visible,
|
||||||
"barSide": resolvedConnectedBarSide,
|
"barSide": resolvedConnectedBarSide,
|
||||||
@@ -259,25 +264,11 @@ Item {
|
|||||||
"omitStartConnector": false,
|
"omitStartConnector": false,
|
||||||
"omitEndConnector": false
|
"omitEndConnector": false
|
||||||
};
|
};
|
||||||
if (isClaim)
|
return modalChrome.publish(state);
|
||||||
ConnectedModeState.claimModalState(screenName, state, _chromeClaimId);
|
|
||||||
else
|
|
||||||
ConnectedModeState.updateModalState(screenName, state, _chromeClaimId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function _syncModalChromeState() {
|
function _syncModalChromeState() {
|
||||||
if (!frameOwnsConnectedChrome) {
|
_publishModalChromeState();
|
||||||
_releaseModalChrome();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const isClaim = !_chromeClaimId;
|
|
||||||
if (!_chromeClaimId)
|
|
||||||
_chromeClaimId = _nextChromeClaimId();
|
|
||||||
_publishModalChromeState(isClaim);
|
|
||||||
if (_dockBlocksEmergence && (spotlightOpen || contentWindow.visible))
|
|
||||||
ConnectedModeState.requestDockRetract(_chromeClaimId, _currentScreenName(), resolvedConnectedBarSide);
|
|
||||||
else
|
|
||||||
ConnectedModeState.releaseDockRetract(_chromeClaimId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
property bool _animSyncQueued: false
|
property bool _animSyncQueued: false
|
||||||
@@ -314,32 +305,21 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _syncModalAnim() {
|
function _syncModalAnim() {
|
||||||
if (!frameOwnsConnectedChrome || !_chromeClaimId)
|
if (!frameOwnsConnectedChrome)
|
||||||
return;
|
return;
|
||||||
const screenName = _currentScreenName();
|
if (!contentContainer)
|
||||||
if (!screenName || !contentContainer)
|
|
||||||
return;
|
return;
|
||||||
ConnectedModeState.setModalAnim(screenName, contentContainer.animX, contentContainer.animY, _chromeClaimId);
|
modalChrome.updateAnim(contentContainer.animX, contentContainer.animY);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _syncModalBody() {
|
function _syncModalBody() {
|
||||||
if (!frameOwnsConnectedChrome || !_chromeClaimId)
|
if (!frameOwnsConnectedChrome)
|
||||||
return;
|
return;
|
||||||
const screenName = _currentScreenName();
|
modalChrome.updateBody(_connectedChromeX, _connectedChromeY, _connectedChromeWidth, _connectedChromeHeight);
|
||||||
if (!screenName)
|
|
||||||
return;
|
|
||||||
ConnectedModeState.setModalBody(screenName, _connectedChromeX, _connectedChromeY, _connectedChromeWidth, _connectedChromeHeight, _chromeClaimId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function _releaseModalChrome() {
|
function _releaseModalChrome() {
|
||||||
if (!_chromeClaimId)
|
modalChrome.release();
|
||||||
return;
|
|
||||||
ConnectedModeState.releaseDockRetract(_chromeClaimId);
|
|
||||||
const claimId = _chromeClaimId;
|
|
||||||
_chromeClaimId = "";
|
|
||||||
const screenName = _currentScreenName();
|
|
||||||
if (screenName)
|
|
||||||
ConnectedModeState.clearModalState(screenName, claimId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onFrameOwnsConnectedChromeChanged: _syncModalChromeState()
|
onFrameOwnsConnectedChromeChanged: _syncModalChromeState()
|
||||||
@@ -351,8 +331,6 @@ Item {
|
|||||||
onAlignedWidthChanged: _queueBodySync()
|
onAlignedWidthChanged: _queueBodySync()
|
||||||
onAlignedHeightChanged: _queueBodySync()
|
onAlignedHeightChanged: _queueBodySync()
|
||||||
|
|
||||||
Component.onDestruction: _releaseModalChrome()
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: contentWindow
|
target: contentWindow
|
||||||
function onVisibleChanged() {
|
function onVisibleChanged() {
|
||||||
@@ -579,13 +557,17 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!needsReset)
|
if (!needsReset) {
|
||||||
|
if (root.spotlightOpen)
|
||||||
|
root._queueFullSync();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const newScreen = CompositorService.getFocusedScreen() ?? Quickshell.screens[0];
|
const newScreen = CompositorService.getFocusedScreen() ?? Quickshell.screens[0];
|
||||||
if (!newScreen)
|
if (!newScreen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
root._releaseModalChrome();
|
||||||
root._windowEnabled = false;
|
root._windowEnabled = false;
|
||||||
backgroundWindow.screen = newScreen;
|
backgroundWindow.screen = newScreen;
|
||||||
contentWindow.screen = newScreen;
|
contentWindow.screen = newScreen;
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ PanelWindow {
|
|||||||
readonly property int _windowRegionWidth: win._regionInt(win.width)
|
readonly property int _windowRegionWidth: win._regionInt(win.width)
|
||||||
readonly property int _windowRegionHeight: win._regionInt(win.height)
|
readonly property int _windowRegionHeight: win._regionInt(win.height)
|
||||||
readonly property string _screenName: win.targetScreen ? win.targetScreen.name : ""
|
readonly property string _screenName: win.targetScreen ? win.targetScreen.name : ""
|
||||||
|
readonly property int _surfaceRevision: Number(ConnectedModeState.surfaceRevisions[win._screenName] || 0)
|
||||||
readonly property var _dockState: ConnectedModeState.dockStates[win._screenName] || ConnectedModeState.emptyDockState
|
readonly property var _dockState: ConnectedModeState.dockStates[win._screenName] || ConnectedModeState.emptyDockState
|
||||||
readonly property var _dockSlide: ConnectedModeState.dockSlides[win._screenName] || ({
|
readonly property var _dockSlide: ConnectedModeState.dockSlides[win._screenName] || ({
|
||||||
"x": 0,
|
"x": 0,
|
||||||
@@ -150,6 +151,8 @@ PanelWindow {
|
|||||||
readonly property real _surfaceRadius: Theme.connectedSurfaceRadius
|
readonly property real _surfaceRadius: Theme.connectedSurfaceRadius
|
||||||
readonly property real _seamOverlap: Theme.hairline(win._dpr)
|
readonly property real _seamOverlap: Theme.hairline(win._dpr)
|
||||||
readonly property bool _disableLayer: Quickshell.env("DMS_DISABLE_LAYER") === "true" || Quickshell.env("DMS_DISABLE_LAYER") === "1"
|
readonly property bool _disableLayer: Quickshell.env("DMS_DISABLE_LAYER") === "true" || Quickshell.env("DMS_DISABLE_LAYER") === "1"
|
||||||
|
property bool _surfaceRefreshNeedsLayerRecreate: false
|
||||||
|
property bool _surfaceLayerRecoveryActive: false
|
||||||
|
|
||||||
function _regionInt(value) {
|
function _regionInt(value) {
|
||||||
return Math.max(0, Math.round(Theme.px(value, win._dpr)));
|
return Math.max(0, Math.round(Theme.px(value, win._dpr)));
|
||||||
@@ -1187,12 +1190,14 @@ PanelWindow {
|
|||||||
return (arcCorner === "topLeft" || arcCorner === "topRight") ? connectorY - r : connectorY + connectorHeight - r;
|
return (arcCorner === "topLeft" || arcCorner === "topRight") ? connectorY - r : connectorY + connectorHeight - r;
|
||||||
}
|
}
|
||||||
|
|
||||||
function _buildBlur() {
|
function _buildBlur(forceRepublish) {
|
||||||
try {
|
try {
|
||||||
if (!BlurService.enabled || !SettingsData.frameBlurEnabled || !win._frameActive || !win.visible) {
|
if (!BlurService.enabled || !SettingsData.frameBlurEnabled || !win._frameActive || !win.visible) {
|
||||||
win.BackgroundEffect.blurRegion = null;
|
win.BackgroundEffect.blurRegion = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (forceRepublish)
|
||||||
|
win.BackgroundEffect.blurRegion = null;
|
||||||
win.BackgroundEffect.blurRegion = _staticBlurRegion;
|
win.BackgroundEffect.blurRegion = _staticBlurRegion;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
win.log.warn("Failed to set blur region:", e);
|
win.log.warn("Failed to set blur region:", e);
|
||||||
@@ -1216,7 +1221,54 @@ PanelWindow {
|
|||||||
blurRebuildAction.schedule();
|
blurRebuildAction.schedule();
|
||||||
}
|
}
|
||||||
function _runBlurRebuild() {
|
function _runBlurRebuild() {
|
||||||
_buildBlur();
|
_buildBlur(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _republishFrameBlur() {
|
||||||
|
_buildBlur(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function _requestContentUpdate() {
|
||||||
|
try {
|
||||||
|
if (win.contentItem && typeof win.contentItem.update === "function")
|
||||||
|
win.contentItem.update();
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function _scheduleSurfaceRefresh(recreateLayer) {
|
||||||
|
if (recreateLayer)
|
||||||
|
_surfaceRefreshNeedsLayerRecreate = true;
|
||||||
|
surfaceRefreshAction.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
function _runSurfaceRefresh() {
|
||||||
|
if (!win.visible)
|
||||||
|
return;
|
||||||
|
if (_surfaceRefreshNeedsLayerRecreate) {
|
||||||
|
_surfaceRefreshNeedsLayerRecreate = false;
|
||||||
|
if (win._connectedActive && !win._disableLayer && (Theme.elevationEnabled || win._surfaceOpacity < 1)) {
|
||||||
|
_surfaceLayerRecoveryActive = true;
|
||||||
|
surfaceLayerRestoreAction.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_requestContentUpdate();
|
||||||
|
_republishFrameBlur();
|
||||||
|
}
|
||||||
|
|
||||||
|
function _finishSurfaceLayerRecovery() {
|
||||||
|
_surfaceLayerRecoveryActive = false;
|
||||||
|
_requestContentUpdate();
|
||||||
|
_republishFrameBlur();
|
||||||
|
}
|
||||||
|
|
||||||
|
DeferredAction {
|
||||||
|
id: surfaceRefreshAction
|
||||||
|
onTriggered: win._runSurfaceRefresh()
|
||||||
|
}
|
||||||
|
|
||||||
|
DeferredAction {
|
||||||
|
id: surfaceLayerRestoreAction
|
||||||
|
onTriggered: win._finishSurfaceLayerRecovery()
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
@@ -1263,14 +1315,41 @@ PanelWindow {
|
|||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
win._scheduleBlurRebuild();
|
win._scheduleBlurRebuild();
|
||||||
|
win._scheduleSurfaceRefresh(false);
|
||||||
} else {
|
} else {
|
||||||
|
surfaceRefreshAction.cancel();
|
||||||
|
surfaceLayerRestoreAction.cancel();
|
||||||
|
_surfaceLayerRecoveryActive = false;
|
||||||
|
_surfaceRefreshNeedsLayerRecreate = false;
|
||||||
_teardownBlur();
|
_teardownBlur();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: win._scheduleBlurRebuild()
|
on_SurfaceRevisionChanged: win._scheduleSurfaceRefresh(false)
|
||||||
|
|
||||||
|
onResourcesLost: {
|
||||||
|
blurRebuildAction.cancel();
|
||||||
|
surfaceRefreshAction.cancel();
|
||||||
|
surfaceLayerRestoreAction.cancel();
|
||||||
|
_surfaceRefreshNeedsLayerRecreate = true;
|
||||||
|
if (win._connectedActive && !win._disableLayer && (Theme.elevationEnabled || win._surfaceOpacity < 1))
|
||||||
|
_surfaceLayerRecoveryActive = true;
|
||||||
|
win._teardownBlur();
|
||||||
|
}
|
||||||
|
|
||||||
|
onWindowConnected: {
|
||||||
|
win._scheduleSurfaceRefresh(true);
|
||||||
|
win._scheduleBlurRebuild();
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
win._scheduleBlurRebuild();
|
||||||
|
win._scheduleSurfaceRefresh(false);
|
||||||
|
}
|
||||||
Component.onDestruction: {
|
Component.onDestruction: {
|
||||||
blurRebuildAction.cancel();
|
blurRebuildAction.cancel();
|
||||||
|
surfaceRefreshAction.cancel();
|
||||||
|
surfaceLayerRestoreAction.cancel();
|
||||||
win._teardownBlur();
|
win._teardownBlur();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1290,7 +1369,7 @@ PanelWindow {
|
|||||||
visible: win._connectedActive
|
visible: win._connectedActive
|
||||||
opacity: win._surfaceOpacity
|
opacity: win._surfaceOpacity
|
||||||
// Skip FBO when disabled, invisible, or when neither elevation nor alpha blend is active
|
// Skip FBO when disabled, invisible, or when neither elevation nor alpha blend is active
|
||||||
layer.enabled: win._connectedActive && !win._disableLayer && (Theme.elevationEnabled || win._surfaceOpacity < 1)
|
layer.enabled: win._connectedActive && !win._surfaceLayerRecoveryActive && !win._disableLayer && (Theme.elevationEnabled || win._surfaceOpacity < 1)
|
||||||
layer.smooth: false
|
layer.smooth: false
|
||||||
|
|
||||||
layer.effect: MultiEffect {
|
layer.effect: MultiEffect {
|
||||||
|
|||||||
@@ -220,14 +220,20 @@ Item {
|
|||||||
|
|
||||||
function _publishConnectedChromeState(forceClaim, visibleOverride) {
|
function _publishConnectedChromeState(forceClaim, visibleOverride) {
|
||||||
if (!root.frameOwnsConnectedChrome || !root.screen || !_chromeClaimId)
|
if (!root.frameOwnsConnectedChrome || !root.screen || !_chromeClaimId)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
|
const screenName = root.screen.name;
|
||||||
|
const isCurrent = PopoutManager.isCurrentPopout(popoutHandle, screenName);
|
||||||
|
if (!ConnectedModeState.hasPopoutOwner(_chromeClaimId)) {
|
||||||
|
if (!isCurrent)
|
||||||
|
return false;
|
||||||
|
forceClaim = true;
|
||||||
|
} else if (forceClaim && !isCurrent) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const state = _connectedChromeState(visibleOverride);
|
const state = _connectedChromeState(visibleOverride);
|
||||||
if (forceClaim || !ConnectedModeState.hasPopoutOwner(_chromeClaimId)) {
|
return forceClaim ? ConnectedModeState.claimPopout(_chromeClaimId, state) : ConnectedModeState.updatePopout(_chromeClaimId, state);
|
||||||
ConnectedModeState.claimPopout(_chromeClaimId, state);
|
|
||||||
} else {
|
|
||||||
ConnectedModeState.updatePopout(_chromeClaimId, state);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function _releaseConnectedChromeState() {
|
function _releaseConnectedChromeState() {
|
||||||
@@ -252,9 +258,12 @@ Item {
|
|||||||
}
|
}
|
||||||
if (!contentWindow.visible && !shouldBeVisible)
|
if (!contentWindow.visible && !shouldBeVisible)
|
||||||
return;
|
return;
|
||||||
if (!_chromeClaimId)
|
if (!_chromeClaimId) {
|
||||||
|
if (!PopoutManager.isCurrentPopout(popoutHandle, root.screen.name))
|
||||||
|
return;
|
||||||
_chromeClaimId = _nextChromeClaimId();
|
_chromeClaimId = _nextChromeClaimId();
|
||||||
_publishConnectedChromeState(contentWindow.visible && !ConnectedModeState.hasPopoutOwner(_chromeClaimId));
|
}
|
||||||
|
_publishConnectedChromeState(!ConnectedModeState.hasPopoutOwner(_chromeClaimId));
|
||||||
}
|
}
|
||||||
|
|
||||||
function _syncPopoutAnim(axis) {
|
function _syncPopoutAnim(axis) {
|
||||||
@@ -267,6 +276,11 @@ Item {
|
|||||||
const syncY = axis === "y" && (barSide === "top" || barSide === "bottom");
|
const syncY = axis === "y" && (barSide === "top" || barSide === "bottom");
|
||||||
if (!syncX && !syncY)
|
if (!syncX && !syncY)
|
||||||
return;
|
return;
|
||||||
|
if (!ConnectedModeState.hasPopoutOwner(_chromeClaimId)) {
|
||||||
|
if (root.screen && PopoutManager.isCurrentPopout(popoutHandle, root.screen.name))
|
||||||
|
_queueFullSync();
|
||||||
|
return;
|
||||||
|
}
|
||||||
ConnectedModeState.setPopoutAnim(_chromeClaimId, syncX ? _connectedChromeAnimX() : undefined, syncY ? _connectedChromeAnimY() : undefined);
|
ConnectedModeState.setPopoutAnim(_chromeClaimId, syncX ? _connectedChromeAnimX() : undefined, syncY ? _connectedChromeAnimY() : undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,6 +289,11 @@ Item {
|
|||||||
return;
|
return;
|
||||||
if (!contentWindow.visible && !shouldBeVisible)
|
if (!contentWindow.visible && !shouldBeVisible)
|
||||||
return;
|
return;
|
||||||
|
if (!ConnectedModeState.hasPopoutOwner(_chromeClaimId)) {
|
||||||
|
if (root.screen && PopoutManager.isCurrentPopout(popoutHandle, root.screen.name))
|
||||||
|
_queueFullSync();
|
||||||
|
return;
|
||||||
|
}
|
||||||
ConnectedModeState.setPopoutBody(_chromeClaimId, root.alignedX, root.renderedAlignedY, root.alignedWidth, root.renderedAlignedHeight);
|
ConnectedModeState.setPopoutBody(_chromeClaimId, root.alignedX, root.renderedAlignedY, root.alignedWidth, root.renderedAlignedHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,18 +345,21 @@ Item {
|
|||||||
Connections {
|
Connections {
|
||||||
target: contentWindow
|
target: contentWindow
|
||||||
function onVisibleChanged() {
|
function onVisibleChanged() {
|
||||||
if (contentWindow.visible)
|
if (contentWindow.visible) {
|
||||||
|
if (!root._chromeClaimId)
|
||||||
|
root._chromeClaimId = root._nextChromeClaimId();
|
||||||
root._publishConnectedChromeState(true);
|
root._publishConnectedChromeState(true);
|
||||||
else
|
} else {
|
||||||
root._releaseConnectedChromeState();
|
root._releaseConnectedChromeState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: SettingsData
|
target: SettingsData
|
||||||
function onConnectedFrameModeActiveChanged() {
|
function onConnectedFrameModeActiveChanged() {
|
||||||
if (root.frameOwnsConnectedChrome) {
|
if (root.frameOwnsConnectedChrome) {
|
||||||
if (contentWindow.visible || root.shouldBeVisible) {
|
if ((contentWindow.visible || root.shouldBeVisible) && root.screen && PopoutManager.isCurrentPopout(root.popoutHandle, root.screen.name)) {
|
||||||
if (!root._chromeClaimId)
|
if (!root._chromeClaimId)
|
||||||
root._chromeClaimId = root._nextChromeClaimId();
|
root._chromeClaimId = root._nextChromeClaimId();
|
||||||
root._publishConnectedChromeState(true);
|
root._publishConnectedChromeState(true);
|
||||||
@@ -351,6 +373,22 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: ConnectedModeState
|
||||||
|
function onPopoutOwnerIdChanged() {
|
||||||
|
if ((contentWindow.visible || root.shouldBeVisible) && root.screen && PopoutManager.isCurrentPopout(root.popoutHandle, root.screen.name) && !ConnectedModeState.hasPopoutOwner(root._chromeClaimId))
|
||||||
|
root._queueFullSync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: PopoutManager
|
||||||
|
function onPopoutChanged() {
|
||||||
|
if ((contentWindow.visible || root.shouldBeVisible) && root.screen && PopoutManager.isCurrentPopout(root.popoutHandle, root.screen.name))
|
||||||
|
root._queueFullSync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
readonly property bool frameOwnsConnectedChrome: CompositorService.usesConnectedFrameChromeForScreen(root.screen)
|
readonly property bool frameOwnsConnectedChrome: CompositorService.usesConnectedFrameChromeForScreen(root.screen)
|
||||||
readonly property bool usesConnectedSurfaceChrome: Theme.isConnectedEffect && !CompositorService.connectedFrameBlockedOnScreen(root.screen)
|
readonly property bool usesConnectedSurfaceChrome: Theme.isConnectedEffect && !CompositorService.connectedFrameBlockedOnScreen(root.screen)
|
||||||
readonly property bool usesLocalConnectedSurfaceChrome: usesConnectedSurfaceChrome && !frameOwnsConnectedChrome
|
readonly property bool usesLocalConnectedSurfaceChrome: usesConnectedSurfaceChrome && !frameOwnsConnectedChrome
|
||||||
@@ -373,6 +411,7 @@ Item {
|
|||||||
contentWindow.visible = false;
|
contentWindow.visible = false;
|
||||||
}
|
}
|
||||||
_lastOpenedScreen = screen;
|
_lastOpenedScreen = screen;
|
||||||
|
PopoutManager.showPopout(popoutHandle);
|
||||||
|
|
||||||
if (contentContainer) {
|
if (contentContainer) {
|
||||||
// Snap morph closed only on a fresh open; on screen-change re-open we stay at 1
|
// Snap morph closed only on a fresh open; on screen-change re-open we stay at 1
|
||||||
@@ -408,7 +447,6 @@ Item {
|
|||||||
animationsEnabled = true;
|
animationsEnabled = true;
|
||||||
shouldBeVisible = true;
|
shouldBeVisible = true;
|
||||||
if (shouldBeVisible && screen) {
|
if (shouldBeVisible && screen) {
|
||||||
PopoutManager.showPopout(popoutHandle);
|
|
||||||
opened();
|
opened();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -440,6 +478,8 @@ Item {
|
|||||||
}
|
}
|
||||||
if (!screenStillExists) {
|
if (!screenStillExists) {
|
||||||
close();
|
close();
|
||||||
|
} else {
|
||||||
|
root._queueFullSync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,11 @@ Item {
|
|||||||
targetWindow.BackgroundEffect.blurRegion = _active ? blurRegion : null;
|
targetWindow.BackgroundEffect.blurRegion = _active ? blurRegion : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function _clear() {
|
||||||
|
if (targetWindow)
|
||||||
|
targetWindow.BackgroundEffect.blurRegion = null;
|
||||||
|
}
|
||||||
|
|
||||||
// Force BackgroundEffect to re-publish the blur region on the current wl_surface.
|
// Force BackgroundEffect to re-publish the blur region on the current wl_surface.
|
||||||
// Clearing first bypasses Quickshell's same-Region dedup in BackgroundEffect::setBlurRegion,
|
// Clearing first bypasses Quickshell's same-Region dedup in BackgroundEffect::setBlurRegion,
|
||||||
// setting pendingBlurRegion=true so the next polish actually ships the region — needed
|
// setting pendingBlurRegion=true so the next polish actually ships the region — needed
|
||||||
@@ -45,20 +50,56 @@ Item {
|
|||||||
targetWindow.BackgroundEffect.blurRegion = _active ? blurRegion : null;
|
targetWindow.BackgroundEffect.blurRegion = _active ? blurRegion : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
on_ActiveChanged: _apply()
|
function _scheduleLifecycleKick() {
|
||||||
onTargetWindowChanged: _apply()
|
lifecycleKickAction.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
function _runLifecycleKick() {
|
||||||
|
if (!targetWindow)
|
||||||
|
return;
|
||||||
|
if (targetWindow.visible)
|
||||||
|
kick();
|
||||||
|
else
|
||||||
|
_apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
on_ActiveChanged: {
|
||||||
|
if (_active)
|
||||||
|
_scheduleLifecycleKick();
|
||||||
|
else
|
||||||
|
_clear();
|
||||||
|
}
|
||||||
|
onTargetWindowChanged: {
|
||||||
|
lifecycleKickAction.cancel();
|
||||||
|
_apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
DeferredAction {
|
||||||
|
id: lifecycleKickAction
|
||||||
|
onTriggered: root._runLifecycleKick()
|
||||||
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: root.targetWindow ?? null
|
target: root.targetWindow ?? null
|
||||||
ignoreUnknownSignals: true
|
ignoreUnknownSignals: true
|
||||||
function onVisibleChanged() {
|
function onVisibleChanged() {
|
||||||
if (root.targetWindow && root.targetWindow.visible)
|
if (root.targetWindow && root.targetWindow.visible)
|
||||||
root._apply();
|
root._scheduleLifecycleKick();
|
||||||
|
else
|
||||||
|
root._clear();
|
||||||
|
}
|
||||||
|
function onResourcesLost() {
|
||||||
|
lifecycleKickAction.cancel();
|
||||||
|
root._clear();
|
||||||
|
}
|
||||||
|
function onWindowConnected() {
|
||||||
|
root._scheduleLifecycleKick();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: _apply()
|
Component.onCompleted: _scheduleLifecycleKick()
|
||||||
Component.onDestruction: {
|
Component.onDestruction: {
|
||||||
|
lifecycleKickAction.cancel();
|
||||||
if (targetWindow)
|
if (targetWindow)
|
||||||
targetWindow.BackgroundEffect.blurRegion = null;
|
targetWindow.BackgroundEffect.blurRegion = null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user