mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-04-14 09:42:10 -04:00
(frame): Update connected mode animation & motion logic
This commit is contained in:
@@ -19,7 +19,7 @@ Singleton {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Popout state (updated by DankPopout when connectedFrameModeActive)
|
// Popout state (updated by DankPopout when connectedFrameModeActive)
|
||||||
property string popoutOwnerToken: ""
|
property string popoutOwnerId: ""
|
||||||
property bool popoutVisible: false
|
property bool popoutVisible: false
|
||||||
property string popoutBarSide: "top"
|
property string popoutBarSide: "top"
|
||||||
property real popoutBodyX: 0
|
property real popoutBodyX: 0
|
||||||
@@ -36,20 +36,20 @@ 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: ({})
|
||||||
|
|
||||||
function hasPopoutOwner(token) {
|
function hasPopoutOwner(claimId) {
|
||||||
return !!token && popoutOwnerToken === token;
|
return !!claimId && popoutOwnerId === claimId;
|
||||||
}
|
}
|
||||||
|
|
||||||
function claimPopout(token, state) {
|
function claimPopout(claimId, state) {
|
||||||
if (!token)
|
if (!claimId)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
popoutOwnerToken = token;
|
popoutOwnerId = claimId;
|
||||||
return updatePopout(token, state);
|
return updatePopout(claimId, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatePopout(token, state) {
|
function updatePopout(claimId, state) {
|
||||||
if (!hasPopoutOwner(token) || !state)
|
if (!hasPopoutOwner(claimId) || !state)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (state.visible !== undefined)
|
if (state.visible !== undefined)
|
||||||
@@ -74,11 +74,11 @@ Singleton {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function releasePopout(token) {
|
function releasePopout(claimId) {
|
||||||
if (!hasPopoutOwner(token))
|
if (!hasPopoutOwner(claimId))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
popoutOwnerToken = "";
|
popoutOwnerId = "";
|
||||||
popoutVisible = false;
|
popoutVisible = false;
|
||||||
popoutBarSide = "top";
|
popoutBarSide = "top";
|
||||||
popoutBodyX = 0;
|
popoutBodyX = 0;
|
||||||
@@ -150,4 +150,55 @@ Singleton {
|
|||||||
dockSlides = next;
|
dockSlides = next;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─── Notification state (per screen, updated by NotificationSurface) ──────
|
||||||
|
|
||||||
|
readonly property var emptyNotificationState: ({
|
||||||
|
"visible": false,
|
||||||
|
"barSide": "top",
|
||||||
|
"bodyX": 0,
|
||||||
|
"bodyY": 0,
|
||||||
|
"bodyW": 0,
|
||||||
|
"bodyH": 0
|
||||||
|
})
|
||||||
|
|
||||||
|
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),
|
||||||
|
"barSide": state && state.barSide ? state.barSide : "top",
|
||||||
|
"bodyX": Number(state && state.bodyX !== undefined ? state.bodyX : 0),
|
||||||
|
"bodyY": Number(state && state.bodyY !== undefined ? state.bodyY : 0),
|
||||||
|
"bodyW": Number(state && state.bodyW !== undefined ? state.bodyW : 0),
|
||||||
|
"bodyH": Number(state && state.bodyH !== undefined ? state.bodyH : 0)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function setNotificationState(screenName, state) {
|
||||||
|
if (!screenName || !state)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const next = _cloneNotificationStates();
|
||||||
|
next[screenName] = _normalizeNotificationState(state);
|
||||||
|
notificationStates = next;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearNotificationState(screenName) {
|
||||||
|
if (!screenName || !notificationStates[screenName])
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const next = _cloneNotificationStates();
|
||||||
|
delete next[screenName];
|
||||||
|
notificationStates = next;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,11 +64,19 @@ DankModal {
|
|||||||
activeImageLoads = 0;
|
activeImageLoads = 0;
|
||||||
shouldHaveFocus = true;
|
shouldHaveFocus = true;
|
||||||
ClipboardService.reset();
|
ClipboardService.reset();
|
||||||
if (clipboardAvailable)
|
|
||||||
ClipboardService.refresh();
|
|
||||||
keyboardController.reset();
|
keyboardController.reset();
|
||||||
|
|
||||||
Qt.callLater(function () {
|
Qt.callLater(function () {
|
||||||
|
if (clipboardAvailable) {
|
||||||
|
if (Theme.isConnectedEffect) {
|
||||||
|
Qt.callLater(() => {
|
||||||
|
if (clipboardHistoryModal.shouldBeVisible)
|
||||||
|
ClipboardService.refresh();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ClipboardService.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (contentLoader.item?.searchField) {
|
if (contentLoader.item?.searchField) {
|
||||||
contentLoader.item.searchField.text = "";
|
contentLoader.item.searchField.text = "";
|
||||||
contentLoader.item.searchField.forceActiveFocus();
|
contentLoader.item.searchField.forceActiveFocus();
|
||||||
|
|||||||
@@ -53,8 +53,6 @@ DankPopout {
|
|||||||
open();
|
open();
|
||||||
activeImageLoads = 0;
|
activeImageLoads = 0;
|
||||||
ClipboardService.reset();
|
ClipboardService.reset();
|
||||||
if (clipboardAvailable)
|
|
||||||
ClipboardService.refresh();
|
|
||||||
keyboardController.reset();
|
keyboardController.reset();
|
||||||
|
|
||||||
Qt.callLater(function () {
|
Qt.callLater(function () {
|
||||||
@@ -121,8 +119,16 @@ DankPopout {
|
|||||||
onShouldBeVisibleChanged: {
|
onShouldBeVisibleChanged: {
|
||||||
if (!shouldBeVisible)
|
if (!shouldBeVisible)
|
||||||
return;
|
return;
|
||||||
if (clipboardAvailable)
|
if (clipboardAvailable) {
|
||||||
ClipboardService.refresh();
|
if (Theme.isConnectedEffect) {
|
||||||
|
Qt.callLater(() => {
|
||||||
|
if (root.shouldBeVisible)
|
||||||
|
ClipboardService.refresh();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ClipboardService.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
keyboardController.reset();
|
keyboardController.reset();
|
||||||
Qt.callLater(function () {
|
Qt.callLater(function () {
|
||||||
if (contentLoader.item?.searchField) {
|
if (contentLoader.item?.searchField) {
|
||||||
|
|||||||
@@ -26,11 +26,12 @@ Item {
|
|||||||
property bool closeOnEscapeKey: true
|
property bool closeOnEscapeKey: true
|
||||||
property bool closeOnBackgroundClick: true
|
property bool closeOnBackgroundClick: true
|
||||||
property string animationType: "scale"
|
property string animationType: "scale"
|
||||||
property int animationDuration: Theme.modalAnimationDuration
|
readonly property bool connectedMotionParity: Theme.isConnectedEffect
|
||||||
|
property int animationDuration: connectedMotionParity ? Theme.popoutAnimationDuration : Theme.modalAnimationDuration
|
||||||
property real animationScaleCollapsed: Theme.effectScaleCollapsed
|
property real animationScaleCollapsed: Theme.effectScaleCollapsed
|
||||||
property real animationOffset: Theme.effectAnimOffset
|
property real animationOffset: Theme.effectAnimOffset
|
||||||
property list<real> animationEnterCurve: Theme.variantModalEnterCurve
|
property list<real> animationEnterCurve: connectedMotionParity ? Theme.variantPopoutEnterCurve : Theme.variantModalEnterCurve
|
||||||
property list<real> animationExitCurve: Theme.variantModalExitCurve
|
property list<real> animationExitCurve: connectedMotionParity ? Theme.variantPopoutExitCurve : Theme.variantModalExitCurve
|
||||||
property color backgroundColor: Theme.surfaceContainer
|
property color backgroundColor: Theme.surfaceContainer
|
||||||
property color borderColor: Theme.outlineMedium
|
property color borderColor: Theme.outlineMedium
|
||||||
property real borderWidth: 0
|
property real borderWidth: 0
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ Item {
|
|||||||
property bool spotlightOpen: false
|
property bool spotlightOpen: false
|
||||||
property bool keyboardActive: false
|
property bool keyboardActive: false
|
||||||
property bool contentVisible: false
|
property bool contentVisible: false
|
||||||
readonly property bool launcherMotionVisible: Theme.isDirectionalEffect ? spotlightOpen : _motionActive
|
readonly property bool launcherMotionVisible: Theme.isConnectedEffect ? _motionActive : (Theme.isDirectionalEffect ? spotlightOpen : _motionActive)
|
||||||
property var spotlightContent: launcherContentLoader.item
|
property var spotlightContent: launcherContentLoader.item
|
||||||
property bool openedFromOverview: false
|
property bool openedFromOverview: false
|
||||||
property bool isClosing: false
|
property bool isClosing: false
|
||||||
@@ -67,6 +67,9 @@ Item {
|
|||||||
readonly property real modalY: (screenHeight - modalHeight) / 2
|
readonly property real modalY: (screenHeight - modalHeight) / 2
|
||||||
|
|
||||||
readonly property bool connectedSurfaceOverride: Theme.isConnectedEffect
|
readonly property bool connectedSurfaceOverride: Theme.isConnectedEffect
|
||||||
|
readonly property int launcherAnimationDuration: Theme.isConnectedEffect ? Theme.popoutAnimationDuration : Theme.modalAnimationDuration
|
||||||
|
readonly property list<real> launcherEnterCurve: Theme.isConnectedEffect ? Theme.variantPopoutEnterCurve : Theme.variantModalEnterCurve
|
||||||
|
readonly property list<real> launcherExitCurve: Theme.isConnectedEffect ? Theme.variantPopoutExitCurve : Theme.variantModalExitCurve
|
||||||
readonly property color backgroundColor: connectedSurfaceOverride ? Theme.connectedSurfaceColor : Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
|
readonly property color backgroundColor: connectedSurfaceOverride ? Theme.connectedSurfaceColor : Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
|
||||||
readonly property real cornerRadius: connectedSurfaceOverride ? Theme.connectedSurfaceRadius : Theme.cornerRadius
|
readonly property real cornerRadius: connectedSurfaceOverride ? Theme.connectedSurfaceRadius : Theme.cornerRadius
|
||||||
readonly property color borderColor: {
|
readonly property color borderColor: {
|
||||||
@@ -271,7 +274,7 @@ Item {
|
|||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: closeCleanupTimer
|
id: closeCleanupTimer
|
||||||
interval: Theme.variantCloseInterval(Theme.modalAnimationDuration)
|
interval: Theme.variantCloseInterval(root.launcherAnimationDuration)
|
||||||
repeat: false
|
repeat: false
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
isClosing = false;
|
isClosing = false;
|
||||||
@@ -394,8 +397,8 @@ Item {
|
|||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
enabled: root.animationsEnabled && (!Theme.isDirectionalEffect || Theme.isConnectedEffect)
|
enabled: root.animationsEnabled && (!Theme.isDirectionalEffect || Theme.isConnectedEffect)
|
||||||
DankAnim {
|
DankAnim {
|
||||||
duration: Math.round(Theme.variantDuration(Theme.modalAnimationDuration, launcherMotionVisible) * Theme.variantOpacityDurationScale)
|
duration: Math.round(Theme.variantDuration(root.launcherAnimationDuration, launcherMotionVisible) * Theme.variantOpacityDurationScale)
|
||||||
easing.bezierCurve: launcherMotionVisible ? Theme.variantModalEnterCurve : Theme.variantModalExitCurve
|
easing.bezierCurve: launcherMotionVisible ? root.launcherEnterCurve : root.launcherExitCurve
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -512,47 +515,32 @@ Item {
|
|||||||
return -Math.max((root.shadowPad || 0) + Theme.effectAnimOffset, 40);
|
return -Math.max((root.shadowPad || 0) + Theme.effectAnimOffset, 40);
|
||||||
}
|
}
|
||||||
|
|
||||||
// animX/animY are Behavior-animated — DankPopout pattern
|
// Declarative bindings — snap applied at render layer (contentWrapper x/y)
|
||||||
property real animX: 0
|
property real animX: root._motionActive ? 0 : root._frozenMotionX
|
||||||
property real animY: 0
|
property real animY: root._motionActive ? 0 : root._frozenMotionY
|
||||||
property real scaleValue: Theme.isDirectionalEffect && typeof SettingsData !== "undefined" && SettingsData.directionalAnimationMode === 2 ? Theme.effectScaleCollapsed : (Theme.isDirectionalEffect ? 1 : Theme.effectScaleCollapsed)
|
property real scaleValue: root._motionActive ? 1.0 : (Theme.isDirectionalEffect && typeof SettingsData !== "undefined" && SettingsData.directionalAnimationMode === 2 ? Theme.effectScaleCollapsed : (Theme.isDirectionalEffect ? 1 : Theme.effectScaleCollapsed))
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
animX = Theme.snap(root._motionActive ? 0 : collapsedMotionX, root.dpr);
|
|
||||||
animY = Theme.snap(root._motionActive ? 0 : collapsedMotionY, root.dpr);
|
|
||||||
scaleValue = root._motionActive ? 1.0 : (Theme.isDirectionalEffect && typeof SettingsData !== "undefined" && SettingsData.directionalAnimationMode === 2 ? Theme.effectScaleCollapsed : (Theme.isDirectionalEffect ? 1 : Theme.effectScaleCollapsed));
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: root
|
|
||||||
function on_MotionActiveChanged() {
|
|
||||||
contentContainer.animX = Theme.snap(root._motionActive ? 0 : root._frozenMotionX, root.dpr);
|
|
||||||
contentContainer.animY = Theme.snap(root._motionActive ? 0 : root._frozenMotionY, root.dpr);
|
|
||||||
contentContainer.scaleValue = root._motionActive ? 1.0 : (Theme.isDirectionalEffect && typeof SettingsData !== "undefined" && SettingsData.directionalAnimationMode === 2 ? Theme.effectScaleCollapsed : (Theme.isDirectionalEffect ? 1 : Theme.effectScaleCollapsed));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on animX {
|
Behavior on animX {
|
||||||
enabled: root.animationsEnabled
|
enabled: root.animationsEnabled
|
||||||
DankAnim {
|
DankAnim {
|
||||||
duration: Theme.variantDuration(Theme.modalAnimationDuration, root._motionActive)
|
duration: Theme.variantDuration(root.launcherAnimationDuration, root._motionActive)
|
||||||
easing.bezierCurve: root._motionActive ? Theme.variantModalEnterCurve : Theme.variantModalExitCurve
|
easing.bezierCurve: root._motionActive ? root.launcherEnterCurve : root.launcherExitCurve
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on animY {
|
Behavior on animY {
|
||||||
enabled: root.animationsEnabled
|
enabled: root.animationsEnabled
|
||||||
DankAnim {
|
DankAnim {
|
||||||
duration: Theme.variantDuration(Theme.modalAnimationDuration, root._motionActive)
|
duration: Theme.variantDuration(root.launcherAnimationDuration, root._motionActive)
|
||||||
easing.bezierCurve: root._motionActive ? Theme.variantModalEnterCurve : Theme.variantModalExitCurve
|
easing.bezierCurve: root._motionActive ? root.launcherEnterCurve : root.launcherExitCurve
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on scaleValue {
|
Behavior on scaleValue {
|
||||||
enabled: root.animationsEnabled && (!Theme.isDirectionalEffect || (typeof SettingsData !== "undefined" && SettingsData.directionalAnimationMode === 2))
|
enabled: root.animationsEnabled && (!Theme.isDirectionalEffect || (typeof SettingsData !== "undefined" && SettingsData.directionalAnimationMode === 2))
|
||||||
DankAnim {
|
DankAnim {
|
||||||
duration: Theme.variantDuration(Theme.modalAnimationDuration, root._motionActive)
|
duration: Theme.variantDuration(root.launcherAnimationDuration, root._motionActive)
|
||||||
easing.bezierCurve: root._motionActive ? Theme.variantModalEnterCurve : Theme.variantModalExitCurve
|
easing.bezierCurve: root._motionActive ? root.launcherEnterCurve : root.launcherExitCurve
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -608,8 +596,8 @@ Item {
|
|||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
enabled: root.animationsEnabled && (!Theme.isDirectionalEffect || Theme.isConnectedEffect)
|
enabled: root.animationsEnabled && (!Theme.isDirectionalEffect || Theme.isConnectedEffect)
|
||||||
DankAnim {
|
DankAnim {
|
||||||
duration: Math.round(Theme.variantDuration(Theme.modalAnimationDuration, launcherMotionVisible) * Theme.variantOpacityDurationScale)
|
duration: Math.round(Theme.variantDuration(root.launcherAnimationDuration, launcherMotionVisible) * Theme.variantOpacityDurationScale)
|
||||||
easing.bezierCurve: launcherMotionVisible ? Theme.variantModalEnterCurve : Theme.variantModalExitCurve
|
easing.bezierCurve: launcherMotionVisible ? root.launcherEnterCurve : root.launcherExitCurve
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -112,8 +112,8 @@ PanelWindow {
|
|||||||
|
|
||||||
readonly property bool _active: ConnectedModeState.popoutVisible && ConnectedModeState.popoutScreen === win._screenName
|
readonly property bool _active: ConnectedModeState.popoutVisible && ConnectedModeState.popoutScreen === win._screenName
|
||||||
|
|
||||||
readonly property real _dyClamp: (ConnectedModeState.popoutBarSide === "top" || ConnectedModeState.popoutBarSide === "bottom") ? Math.max(-ConnectedModeState.popoutBodyH, Math.min(ConnectedModeState.popoutAnimY, ConnectedModeState.popoutBodyH)) : 0
|
readonly property real _dyClamp: (ConnectedModeState.popoutBarSide === "top" || ConnectedModeState.popoutBarSide === "bottom") ? Math.max(-ConnectedModeState.popoutBodyH, Math.min(ConnectedModeState.popoutAnimY * 1.02, ConnectedModeState.popoutBodyH)) : 0
|
||||||
readonly property real _dxClamp: (ConnectedModeState.popoutBarSide === "left" || ConnectedModeState.popoutBarSide === "right") ? Math.max(-ConnectedModeState.popoutBodyW, Math.min(ConnectedModeState.popoutAnimX, ConnectedModeState.popoutBodyW)) : 0
|
readonly property real _dxClamp: (ConnectedModeState.popoutBarSide === "left" || ConnectedModeState.popoutBarSide === "right") ? Math.max(-ConnectedModeState.popoutBodyW, Math.min(ConnectedModeState.popoutAnimX * 1.02, ConnectedModeState.popoutBodyW)) : 0
|
||||||
|
|
||||||
x: _active ? ConnectedModeState.popoutBodyX + (ConnectedModeState.popoutBarSide === "right" ? _dxClamp : 0) : 0
|
x: _active ? ConnectedModeState.popoutBodyX + (ConnectedModeState.popoutBarSide === "right" ? _dxClamp : 0) : 0
|
||||||
y: _active ? ConnectedModeState.popoutBodyY + (ConnectedModeState.popoutBarSide === "bottom" ? _dyClamp : 0) : 0
|
y: _active ? ConnectedModeState.popoutBodyY + (ConnectedModeState.popoutBarSide === "bottom" ? _dyClamp : 0) : 0
|
||||||
@@ -218,60 +218,6 @@ PanelWindow {
|
|||||||
height: _active ? win._dockConnectorRadius() * 2 : 0
|
height: _active ? win._dockConnectorRadius() * 2 : 0
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
|
||||||
id: _popoutLeftConnectorBlurAnchor
|
|
||||||
opacity: 0
|
|
||||||
|
|
||||||
readonly property bool _active: win._popoutArcVisible()
|
|
||||||
readonly property real _w: win._popoutConnectorWidth(0)
|
|
||||||
readonly property real _h: win._popoutConnectorHeight(0)
|
|
||||||
|
|
||||||
x: _active ? Theme.snap(win._popoutConnectorX(ConnectedModeState.popoutBodyX, ConnectedModeState.popoutBodyW, "left", 0), win._dpr) : 0
|
|
||||||
y: _active ? Theme.snap(win._popoutConnectorY(ConnectedModeState.popoutBodyY, ConnectedModeState.popoutBodyH, "left", 0), win._dpr) : 0
|
|
||||||
width: _active ? _w : 0
|
|
||||||
height: _active ? _h : 0
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: _popoutRightConnectorBlurAnchor
|
|
||||||
opacity: 0
|
|
||||||
|
|
||||||
readonly property bool _active: win._popoutArcVisible()
|
|
||||||
readonly property real _w: win._popoutConnectorWidth(0)
|
|
||||||
readonly property real _h: win._popoutConnectorHeight(0)
|
|
||||||
|
|
||||||
x: _active ? Theme.snap(win._popoutConnectorX(ConnectedModeState.popoutBodyX, ConnectedModeState.popoutBodyW, "right", 0), win._dpr) : 0
|
|
||||||
y: _active ? Theme.snap(win._popoutConnectorY(ConnectedModeState.popoutBodyY, ConnectedModeState.popoutBodyH, "right", 0), win._dpr) : 0
|
|
||||||
width: _active ? _w : 0
|
|
||||||
height: _active ? _h : 0
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: _popoutLeftConnectorCutout
|
|
||||||
opacity: 0
|
|
||||||
|
|
||||||
readonly property bool _active: _popoutLeftConnectorBlurAnchor.width > 0 && _popoutLeftConnectorBlurAnchor.height > 0
|
|
||||||
readonly property string _arcCorner: win._connectorArcCorner(ConnectedModeState.popoutBarSide, "left")
|
|
||||||
|
|
||||||
x: _active ? win._connectorCutoutX(_popoutLeftConnectorBlurAnchor.x, _popoutLeftConnectorBlurAnchor.width, _arcCorner) : 0
|
|
||||||
y: _active ? win._connectorCutoutY(_popoutLeftConnectorBlurAnchor.y, _popoutLeftConnectorBlurAnchor.height, _arcCorner) : 0
|
|
||||||
width: _active ? win._effectivePopoutCcr * 2 : 0
|
|
||||||
height: _active ? win._effectivePopoutCcr * 2 : 0
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: _popoutRightConnectorCutout
|
|
||||||
opacity: 0
|
|
||||||
|
|
||||||
readonly property bool _active: _popoutRightConnectorBlurAnchor.width > 0 && _popoutRightConnectorBlurAnchor.height > 0
|
|
||||||
readonly property string _arcCorner: win._connectorArcCorner(ConnectedModeState.popoutBarSide, "right")
|
|
||||||
|
|
||||||
x: _active ? win._connectorCutoutX(_popoutRightConnectorBlurAnchor.x, _popoutRightConnectorBlurAnchor.width, _arcCorner) : 0
|
|
||||||
y: _active ? win._connectorCutoutY(_popoutRightConnectorBlurAnchor.y, _popoutRightConnectorBlurAnchor.height, _arcCorner) : 0
|
|
||||||
width: _active ? win._effectivePopoutCcr * 2 : 0
|
|
||||||
height: _active ? win._effectivePopoutCcr * 2 : 0
|
|
||||||
}
|
|
||||||
|
|
||||||
Region {
|
Region {
|
||||||
id: _staticBlurRegion
|
id: _staticBlurRegion
|
||||||
x: 0
|
x: 0
|
||||||
@@ -289,31 +235,11 @@ PanelWindow {
|
|||||||
// ── Connected popout blur regions ──
|
// ── Connected popout blur regions ──
|
||||||
Region {
|
Region {
|
||||||
item: _popoutBodyBlurAnchor
|
item: _popoutBodyBlurAnchor
|
||||||
readonly property string _bs: ConnectedModeState.popoutBarSide
|
radius: win._surfaceRadius
|
||||||
topLeftRadius: (_bs === "top" || _bs === "left") ? win._effectivePopoutCcr : win._surfaceRadius
|
|
||||||
topRightRadius: (_bs === "top" || _bs === "right") ? win._effectivePopoutCcr : win._surfaceRadius
|
|
||||||
bottomLeftRadius: (_bs === "bottom" || _bs === "left") ? win._effectivePopoutCcr : win._surfaceRadius
|
|
||||||
bottomRightRadius: (_bs === "bottom" || _bs === "right") ? win._effectivePopoutCcr : win._surfaceRadius
|
|
||||||
}
|
}
|
||||||
Region {
|
Region {
|
||||||
item: _popoutBodyBlurCap
|
item: _popoutBodyBlurCap
|
||||||
}
|
}
|
||||||
Region {
|
|
||||||
item: _popoutLeftConnectorBlurAnchor
|
|
||||||
Region {
|
|
||||||
item: _popoutLeftConnectorCutout
|
|
||||||
intersection: Intersection.Subtract
|
|
||||||
radius: win._effectivePopoutCcr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Region {
|
|
||||||
item: _popoutRightConnectorBlurAnchor
|
|
||||||
Region {
|
|
||||||
item: _popoutRightConnectorCutout
|
|
||||||
intersection: Intersection.Subtract
|
|
||||||
radius: win._effectivePopoutCcr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ── Connected dock blur regions ──
|
// ── Connected dock blur regions ──
|
||||||
Region {
|
Region {
|
||||||
@@ -343,37 +269,7 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── Connector position helpers (mirror DankPopout / Dock logic) ──────────
|
// ─── Connector position helpers (dock) ─────────────────────────────────
|
||||||
|
|
||||||
function _popoutConnectorWidth(spacing) {
|
|
||||||
const barSide = ConnectedModeState.popoutBarSide;
|
|
||||||
return (barSide === "top" || barSide === "bottom") ? win._effectivePopoutCcr : (spacing + win._effectivePopoutCcr);
|
|
||||||
}
|
|
||||||
|
|
||||||
function _popoutConnectorHeight(spacing) {
|
|
||||||
const barSide = ConnectedModeState.popoutBarSide;
|
|
||||||
return (barSide === "top" || barSide === "bottom") ? (spacing + win._effectivePopoutCcr) : win._effectivePopoutCcr;
|
|
||||||
}
|
|
||||||
|
|
||||||
function _popoutConnectorX(baseX, bodyWidth, placement, spacing) {
|
|
||||||
const barSide = ConnectedModeState.popoutBarSide;
|
|
||||||
const seamX = (barSide === "top" || barSide === "bottom") ? (placement === "left" ? baseX : baseX + bodyWidth) : (barSide === "left" ? baseX : baseX + bodyWidth);
|
|
||||||
const w = _popoutConnectorWidth(spacing);
|
|
||||||
if (barSide === "top" || barSide === "bottom")
|
|
||||||
return placement === "left" ? seamX - w : seamX;
|
|
||||||
return barSide === "left" ? seamX : seamX - w;
|
|
||||||
}
|
|
||||||
|
|
||||||
function _popoutConnectorY(baseY, bodyHeight, placement, spacing) {
|
|
||||||
const barSide = ConnectedModeState.popoutBarSide;
|
|
||||||
const seamY = barSide === "top" ? baseY : barSide === "bottom" ? baseY + bodyHeight : (placement === "left" ? baseY : baseY + bodyHeight);
|
|
||||||
const h = _popoutConnectorHeight(spacing);
|
|
||||||
if (barSide === "top")
|
|
||||||
return seamY;
|
|
||||||
if (barSide === "bottom")
|
|
||||||
return seamY - h;
|
|
||||||
return placement === "left" ? seamY - h : seamY;
|
|
||||||
}
|
|
||||||
|
|
||||||
function _dockBodyBlurRadius() {
|
function _dockBodyBlurRadius() {
|
||||||
return _dockBodyBlurAnchor._active ? Math.max(0, Math.min(win._surfaceRadius, _dockBodyBlurAnchor.width / 2, _dockBodyBlurAnchor.height / 2)) : win._surfaceRadius;
|
return _dockBodyBlurAnchor._active ? Math.max(0, Math.min(win._surfaceRadius, _dockBodyBlurAnchor.width / 2, _dockBodyBlurAnchor.height / 2)) : win._surfaceRadius;
|
||||||
@@ -660,56 +556,27 @@ PanelWindow {
|
|||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: _popoutClip
|
id: _popoutClip
|
||||||
x: win._popoutClipX()
|
readonly property bool _barHoriz: ConnectedModeState.popoutBarSide === "top" || ConnectedModeState.popoutBarSide === "bottom"
|
||||||
y: win._popoutClipY()
|
// Expand clip by ccr on bar axis to include arc columns
|
||||||
width: win._popoutClipWidth()
|
x: win._popoutClipX() - (_barHoriz ? win._effectivePopoutCcr : 0)
|
||||||
height: win._popoutClipHeight()
|
y: win._popoutClipY() - (_barHoriz ? 0 : win._effectivePopoutCcr)
|
||||||
|
width: win._popoutClipWidth() + (_barHoriz ? win._effectivePopoutCcr * 2 : 0)
|
||||||
|
height: win._popoutClipHeight() + (_barHoriz ? 0 : win._effectivePopoutCcr * 2)
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
Rectangle {
|
ConnectedShape {
|
||||||
id: _popoutFill
|
id: _popoutShape
|
||||||
x: win._popoutBodyXInClip()
|
visible: _popoutBodyBlurAnchor._active && _popoutBodyBlurAnchor.width > 0 && _popoutBodyBlurAnchor.height > 0
|
||||||
y: win._popoutBodyYInClip()
|
barSide: ConnectedModeState.popoutBarSide
|
||||||
width: win._popoutBodyFullWidth()
|
bodyWidth: win._popoutClipWidth()
|
||||||
height: win._popoutBodyFullHeight()
|
bodyHeight: win._popoutClipHeight()
|
||||||
color: win._opaqueSurfaceColor
|
connectorRadius: win._effectivePopoutCcr
|
||||||
z: 1
|
surfaceRadius: win._surfaceRadius
|
||||||
topLeftRadius: (ConnectedModeState.popoutBarSide === "top" || ConnectedModeState.popoutBarSide === "left") ? 0 : win._surfaceRadius
|
fillColor: win._opaqueSurfaceColor
|
||||||
topRightRadius: (ConnectedModeState.popoutBarSide === "top" || ConnectedModeState.popoutBarSide === "right") ? 0 : win._surfaceRadius
|
x: 0
|
||||||
bottomLeftRadius: (ConnectedModeState.popoutBarSide === "bottom" || ConnectedModeState.popoutBarSide === "left") ? 0 : win._surfaceRadius
|
y: 0
|
||||||
bottomRightRadius: (ConnectedModeState.popoutBarSide === "bottom" || ConnectedModeState.popoutBarSide === "right") ? 0 : win._surfaceRadius
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectedCorner {
|
|
||||||
id: _connPopoutLeft
|
|
||||||
visible: win._popoutArcVisible()
|
|
||||||
barSide: ConnectedModeState.popoutBarSide
|
|
||||||
placement: "left"
|
|
||||||
spacing: 0
|
|
||||||
connectorRadius: win._effectivePopoutCcr
|
|
||||||
color: win._opaqueSurfaceColor
|
|
||||||
edgeStrokeWidth: win._seamOverlap
|
|
||||||
edgeStrokeColor: win._opaqueSurfaceColor
|
|
||||||
dpr: win._dpr
|
|
||||||
x: Theme.snap(win._popoutConnectorX(ConnectedModeState.popoutBodyX, ConnectedModeState.popoutBodyW, "left", 0) - _popoutChrome.x, win._dpr)
|
|
||||||
y: Theme.snap(win._popoutConnectorY(ConnectedModeState.popoutBodyY, ConnectedModeState.popoutBodyH, "left", 0) - _popoutChrome.y, win._dpr)
|
|
||||||
}
|
|
||||||
|
|
||||||
ConnectedCorner {
|
|
||||||
id: _connPopoutRight
|
|
||||||
visible: win._popoutArcVisible()
|
|
||||||
barSide: ConnectedModeState.popoutBarSide
|
|
||||||
placement: "right"
|
|
||||||
spacing: 0
|
|
||||||
connectorRadius: win._effectivePopoutCcr
|
|
||||||
color: win._opaqueSurfaceColor
|
|
||||||
edgeStrokeWidth: win._seamOverlap
|
|
||||||
edgeStrokeColor: win._opaqueSurfaceColor
|
|
||||||
dpr: win._dpr
|
|
||||||
x: Theme.snap(win._popoutConnectorX(ConnectedModeState.popoutBodyX, ConnectedModeState.popoutBodyW, "right", 0) - _popoutChrome.x, win._dpr)
|
|
||||||
y: Theme.snap(win._popoutConnectorY(ConnectedModeState.popoutBodyY, ConnectedModeState.popoutBodyH, "right", 0) - _popoutChrome.y, win._dpr)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|||||||
@@ -34,11 +34,12 @@ Rectangle {
|
|||||||
readonly property real actionButtonHeight: compactMode ? 20 : 24
|
readonly property real actionButtonHeight: compactMode ? 20 : 24
|
||||||
readonly property real collapsedContentHeight: Math.max(iconSize, Theme.fontSizeSmall * 1.2 + Theme.fontSizeMedium * 1.2 + Theme.fontSizeSmall * 1.2 * (compactMode ? 1 : 2))
|
readonly property real collapsedContentHeight: Math.max(iconSize, Theme.fontSizeSmall * 1.2 + Theme.fontSizeMedium * 1.2 + Theme.fontSizeSmall * 1.2 * (compactMode ? 1 : 2))
|
||||||
readonly property real baseCardHeight: cardPadding * 2 + collapsedContentHeight + actionButtonHeight + contentSpacing
|
readonly property real baseCardHeight: cardPadding * 2 + collapsedContentHeight + actionButtonHeight + contentSpacing
|
||||||
|
readonly property bool connectedFrameMode: SettingsData.connectedFrameModeActive
|
||||||
|
|
||||||
width: parent ? parent.width : 400
|
width: parent ? parent.width : 400
|
||||||
height: expanded ? (expandedContent.height + cardPadding * 2) : (baseCardHeight + collapsedContent.extraHeight)
|
height: expanded ? (expandedContent.height + cardPadding * 2) : (baseCardHeight + collapsedContent.extraHeight)
|
||||||
readonly property real targetHeight: expanded ? (expandedContent.height + cardPadding * 2) : (baseCardHeight + collapsedContent.extraHeight)
|
readonly property real targetHeight: expanded ? (expandedContent.height + cardPadding * 2) : (baseCardHeight + collapsedContent.extraHeight)
|
||||||
radius: Theme.cornerRadius
|
radius: connectedFrameMode ? Theme.connectedSurfaceRadius : Theme.cornerRadius
|
||||||
scale: (cardHoverHandler.hovered ? 1.004 : 1.0) * listLevelAdjacentScaleInfluence
|
scale: (cardHoverHandler.hovered ? 1.004 : 1.0) * listLevelAdjacentScaleInfluence
|
||||||
readonly property bool shadowsAllowed: Theme.elevationEnabled && Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1"
|
readonly property bool shadowsAllowed: Theme.elevationEnabled && Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1"
|
||||||
readonly property var shadowElevation: Theme.elevationLevel1
|
readonly property var shadowElevation: Theme.elevationLevel1
|
||||||
@@ -100,6 +101,8 @@ Rectangle {
|
|||||||
if (keyboardNavigationActive && expanded && selectedNotificationIndex >= 0) {
|
if (keyboardNavigationActive && expanded && selectedNotificationIndex >= 0) {
|
||||||
return Theme.primaryHoverLight;
|
return Theme.primaryHoverLight;
|
||||||
}
|
}
|
||||||
|
if (connectedFrameMode)
|
||||||
|
return Theme.popupLayerColor(Theme.surfaceContainerHigh);
|
||||||
return Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency);
|
return Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency);
|
||||||
}
|
}
|
||||||
border.color: {
|
border.color: {
|
||||||
@@ -959,9 +962,9 @@ Rectangle {
|
|||||||
Behavior on height {
|
Behavior on height {
|
||||||
enabled: root.__initialized && root.userInitiatedExpansion && root.animateExpansion
|
enabled: root.__initialized && root.userInitiatedExpansion && root.animateExpansion
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: root.expanded ? Theme.notificationExpandDuration : Theme.notificationCollapseDuration
|
duration: root.connectedFrameMode ? Theme.variantDuration(Theme.popoutAnimationDuration, root.expanded) : (root.expanded ? Theme.notificationExpandDuration : Theme.notificationCollapseDuration)
|
||||||
easing.type: Easing.BezierSpline
|
easing.type: Easing.BezierSpline
|
||||||
easing.bezierCurve: Theme.expressiveCurves.emphasized
|
easing.bezierCurve: root.connectedFrameMode ? (root.expanded ? Theme.variantPopoutEnterCurve : Theme.variantPopoutExitCurve) : Theme.expressiveCurves.emphasized
|
||||||
onRunningChanged: {
|
onRunningChanged: {
|
||||||
if (running) {
|
if (running) {
|
||||||
root.isAnimating = true;
|
root.isAnimating = true;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ PanelWindow {
|
|||||||
blurY: content.y + content.cardInset + swipeTx.y + tx.y
|
blurY: content.y + content.cardInset + swipeTx.y + tx.y
|
||||||
blurWidth: !win._finalized ? Math.max(0, content.width - content.cardInset * 2) : 0
|
blurWidth: !win._finalized ? Math.max(0, content.width - content.cardInset * 2) : 0
|
||||||
blurHeight: !win._finalized ? Math.max(0, content.height - content.cardInset * 2) : 0
|
blurHeight: !win._finalized ? Math.max(0, content.height - content.cardInset * 2) : 0
|
||||||
blurRadius: Theme.cornerRadius
|
blurRadius: SettingsData.connectedFrameModeActive ? Theme.connectedSurfaceRadius : Theme.cornerRadius
|
||||||
}
|
}
|
||||||
|
|
||||||
WlrLayershell.namespace: "dms:notification-popup"
|
WlrLayershell.namespace: "dms:notification-popup"
|
||||||
|
|||||||
@@ -8,11 +8,12 @@ QtObject {
|
|||||||
property var modelData
|
property var modelData
|
||||||
property int topMargin: 0
|
property int topMargin: 0
|
||||||
readonly property bool compactMode: SettingsData.notificationCompactMode
|
readonly property bool compactMode: SettingsData.notificationCompactMode
|
||||||
|
readonly property bool connectedFrameMode: SettingsData.connectedFrameModeActive
|
||||||
readonly property real cardPadding: compactMode ? Theme.notificationCardPaddingCompact : Theme.notificationCardPadding
|
readonly property real cardPadding: compactMode ? Theme.notificationCardPaddingCompact : Theme.notificationCardPadding
|
||||||
readonly property real popupIconSize: compactMode ? Theme.notificationIconSizeCompact : Theme.notificationIconSizeNormal
|
readonly property real popupIconSize: compactMode ? Theme.notificationIconSizeCompact : Theme.notificationIconSizeNormal
|
||||||
readonly property real actionButtonHeight: compactMode ? 20 : 24
|
readonly property real actionButtonHeight: compactMode ? 20 : 24
|
||||||
readonly property real contentSpacing: compactMode ? Theme.spacingXS : Theme.spacingS
|
readonly property real contentSpacing: compactMode ? Theme.spacingXS : Theme.spacingS
|
||||||
readonly property real popupSpacing: compactMode ? 0 : Theme.spacingXS
|
readonly property real popupSpacing: connectedFrameMode ? 0 : (compactMode ? 0 : Theme.spacingXS)
|
||||||
readonly property real collapsedContentHeight: Math.max(popupIconSize, Theme.fontSizeSmall * 1.2 + Theme.fontSizeMedium * 1.2 + Theme.fontSizeSmall * 1.2 * (compactMode ? 1 : 2))
|
readonly property real collapsedContentHeight: Math.max(popupIconSize, Theme.fontSizeSmall * 1.2 + Theme.fontSizeMedium * 1.2 + Theme.fontSizeSmall * 1.2 * (compactMode ? 1 : 2))
|
||||||
readonly property int baseNotificationHeight: cardPadding * 2 + collapsedContentHeight + actionButtonHeight + contentSpacing + popupSpacing
|
readonly property int baseNotificationHeight: cardPadding * 2 + collapsedContentHeight + actionButtonHeight + contentSpacing + popupSpacing
|
||||||
property var popupWindows: []
|
property var popupWindows: []
|
||||||
|
|||||||
@@ -3,6 +3,10 @@ import QtQuick.Shapes
|
|||||||
import qs.Common
|
import qs.Common
|
||||||
|
|
||||||
// Concave arc connector filling the gap between a bar corner and an adjacent surface.
|
// Concave arc connector filling the gap between a bar corner and an adjacent surface.
|
||||||
|
//
|
||||||
|
// NOTE: FrameWindow now uses ConnectedShape.qml for frame-owned connected chrome
|
||||||
|
// (unified single-path rendering). This component is still used by DankPopout's
|
||||||
|
// own shadow source for non-frame-owned chrome (popouts on non-frame screens).
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|||||||
286
quickshell/Widgets/ConnectedShape.qml
Normal file
286
quickshell/Widgets/ConnectedShape.qml
Normal file
@@ -0,0 +1,286 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Shapes
|
||||||
|
import qs.Common
|
||||||
|
|
||||||
|
// Unified connected silhouette: body + concave arcs as one ShapePath.
|
||||||
|
// PathArc pattern — 4 arcs + 4 lines, no sibling alignment.
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property string barSide: "top"
|
||||||
|
|
||||||
|
property real bodyWidth: 0
|
||||||
|
property real bodyHeight: 0
|
||||||
|
|
||||||
|
property real connectorRadius: 12
|
||||||
|
|
||||||
|
property real surfaceRadius: 12
|
||||||
|
|
||||||
|
property color fillColor: "transparent"
|
||||||
|
|
||||||
|
// ── Derived layout ──
|
||||||
|
readonly property bool _horiz: barSide === "top" || barSide === "bottom"
|
||||||
|
readonly property real _cr: Math.max(0, connectorRadius)
|
||||||
|
readonly property real _sr: Math.max(0, Math.min(surfaceRadius, (_horiz ? bodyWidth : bodyHeight) / 2, (_horiz ? bodyHeight : bodyWidth) / 2))
|
||||||
|
|
||||||
|
// Root-level aliases — PathArc/PathLine elements can't use `parent`.
|
||||||
|
readonly property real _bw: bodyWidth
|
||||||
|
readonly property real _bh: bodyHeight
|
||||||
|
readonly property real _totalW: _horiz ? _bw + _cr * 2 : _bw
|
||||||
|
readonly property real _totalH: _horiz ? _bh : _bh + _cr * 2
|
||||||
|
|
||||||
|
width: _totalW
|
||||||
|
height: _totalH
|
||||||
|
|
||||||
|
readonly property real bodyX: _horiz ? _cr : 0
|
||||||
|
readonly property real bodyY: _horiz ? 0 : _cr
|
||||||
|
|
||||||
|
Shape {
|
||||||
|
anchors.fill: parent
|
||||||
|
asynchronous: false
|
||||||
|
preferredRendererType: Shape.CurveRenderer
|
||||||
|
|
||||||
|
ShapePath {
|
||||||
|
fillColor: root.fillColor
|
||||||
|
strokeWidth: -1
|
||||||
|
fillRule: ShapePath.WindingFill
|
||||||
|
|
||||||
|
// CW path: bar edge → concave arc → body → convex arc → far edge → convex arc → body → concave arc
|
||||||
|
|
||||||
|
startX: root.barSide === "right" ? root._totalW : 0
|
||||||
|
startY: {
|
||||||
|
switch (root.barSide) {
|
||||||
|
case "bottom":
|
||||||
|
return root._totalH;
|
||||||
|
case "left":
|
||||||
|
return root._totalH;
|
||||||
|
case "right":
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bar edge
|
||||||
|
PathLine {
|
||||||
|
x: {
|
||||||
|
switch (root.barSide) {
|
||||||
|
case "left":
|
||||||
|
return 0;
|
||||||
|
case "right":
|
||||||
|
return root._totalW;
|
||||||
|
default:
|
||||||
|
return root._totalW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
y: {
|
||||||
|
switch (root.barSide) {
|
||||||
|
case "bottom":
|
||||||
|
return root._totalH;
|
||||||
|
case "left":
|
||||||
|
return 0;
|
||||||
|
case "right":
|
||||||
|
return root._totalH;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Concave arc 1
|
||||||
|
PathArc {
|
||||||
|
relativeX: {
|
||||||
|
switch (root.barSide) {
|
||||||
|
case "left":
|
||||||
|
return root._cr;
|
||||||
|
case "right":
|
||||||
|
return -root._cr;
|
||||||
|
default:
|
||||||
|
return -root._cr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
relativeY: {
|
||||||
|
switch (root.barSide) {
|
||||||
|
case "bottom":
|
||||||
|
return -root._cr;
|
||||||
|
case "left":
|
||||||
|
return root._cr;
|
||||||
|
case "right":
|
||||||
|
return -root._cr;
|
||||||
|
default:
|
||||||
|
return root._cr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
radiusX: root._cr
|
||||||
|
radiusY: root._cr
|
||||||
|
direction: PathArc.Counterclockwise
|
||||||
|
}
|
||||||
|
|
||||||
|
// Body edge to first convex corner
|
||||||
|
PathLine {
|
||||||
|
x: {
|
||||||
|
switch (root.barSide) {
|
||||||
|
case "left":
|
||||||
|
return root._bw - root._sr;
|
||||||
|
case "right":
|
||||||
|
return root._sr;
|
||||||
|
default:
|
||||||
|
return root._totalW - root._cr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
y: {
|
||||||
|
switch (root.barSide) {
|
||||||
|
case "bottom":
|
||||||
|
return root._sr;
|
||||||
|
case "left":
|
||||||
|
return root._cr;
|
||||||
|
case "right":
|
||||||
|
return root._cr + root._bh;
|
||||||
|
default:
|
||||||
|
return root._totalH - root._sr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convex arc 1
|
||||||
|
PathArc {
|
||||||
|
relativeX: {
|
||||||
|
switch (root.barSide) {
|
||||||
|
case "left":
|
||||||
|
return root._sr;
|
||||||
|
case "right":
|
||||||
|
return -root._sr;
|
||||||
|
default:
|
||||||
|
return -root._sr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
relativeY: {
|
||||||
|
switch (root.barSide) {
|
||||||
|
case "bottom":
|
||||||
|
return -root._sr;
|
||||||
|
case "left":
|
||||||
|
return root._sr;
|
||||||
|
case "right":
|
||||||
|
return -root._sr;
|
||||||
|
default:
|
||||||
|
return root._sr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
radiusX: root._sr
|
||||||
|
radiusY: root._sr
|
||||||
|
direction: PathArc.Clockwise
|
||||||
|
}
|
||||||
|
|
||||||
|
// Far edge
|
||||||
|
PathLine {
|
||||||
|
x: {
|
||||||
|
switch (root.barSide) {
|
||||||
|
case "left":
|
||||||
|
return root._bw;
|
||||||
|
case "right":
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
return root._cr + root._sr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
y: {
|
||||||
|
switch (root.barSide) {
|
||||||
|
case "bottom":
|
||||||
|
return 0;
|
||||||
|
case "left":
|
||||||
|
return root._cr + root._bh - root._sr;
|
||||||
|
case "right":
|
||||||
|
return root._cr + root._sr;
|
||||||
|
default:
|
||||||
|
return root._totalH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convex arc 2
|
||||||
|
PathArc {
|
||||||
|
relativeX: {
|
||||||
|
switch (root.barSide) {
|
||||||
|
case "left":
|
||||||
|
return -root._sr;
|
||||||
|
case "right":
|
||||||
|
return root._sr;
|
||||||
|
default:
|
||||||
|
return -root._sr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
relativeY: {
|
||||||
|
switch (root.barSide) {
|
||||||
|
case "bottom":
|
||||||
|
return root._sr;
|
||||||
|
case "left":
|
||||||
|
return root._sr;
|
||||||
|
case "right":
|
||||||
|
return -root._sr;
|
||||||
|
default:
|
||||||
|
return -root._sr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
radiusX: root._sr
|
||||||
|
radiusY: root._sr
|
||||||
|
direction: PathArc.Clockwise
|
||||||
|
}
|
||||||
|
|
||||||
|
// Body edge to second concave arc
|
||||||
|
PathLine {
|
||||||
|
x: {
|
||||||
|
switch (root.barSide) {
|
||||||
|
case "left":
|
||||||
|
return root._cr;
|
||||||
|
case "right":
|
||||||
|
return root._bw - root._cr;
|
||||||
|
default:
|
||||||
|
return root._cr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
y: {
|
||||||
|
switch (root.barSide) {
|
||||||
|
case "bottom":
|
||||||
|
return root._totalH - root._cr;
|
||||||
|
case "left":
|
||||||
|
return root._cr + root._bh;
|
||||||
|
case "right":
|
||||||
|
return root._cr;
|
||||||
|
default:
|
||||||
|
return root._cr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Concave arc 2
|
||||||
|
PathArc {
|
||||||
|
relativeX: {
|
||||||
|
switch (root.barSide) {
|
||||||
|
case "left":
|
||||||
|
return -root._cr;
|
||||||
|
case "right":
|
||||||
|
return root._cr;
|
||||||
|
default:
|
||||||
|
return -root._cr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
relativeY: {
|
||||||
|
switch (root.barSide) {
|
||||||
|
case "bottom":
|
||||||
|
return root._cr;
|
||||||
|
case "left":
|
||||||
|
return root._cr;
|
||||||
|
case "right":
|
||||||
|
return -root._cr;
|
||||||
|
default:
|
||||||
|
return -root._cr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
radiusX: root._cr
|
||||||
|
radiusY: root._cr
|
||||||
|
direction: PathArc.Counterclockwise
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,7 +34,7 @@ Item {
|
|||||||
property bool _resizeActive: false
|
property bool _resizeActive: false
|
||||||
property real _surfaceMarginLeft: 0
|
property real _surfaceMarginLeft: 0
|
||||||
property real _surfaceW: 0
|
property real _surfaceW: 0
|
||||||
property string _connectedChromeToken: ""
|
property string _chromeClaimId: ""
|
||||||
property int _connectedChromeSerial: 0
|
property int _connectedChromeSerial: 0
|
||||||
|
|
||||||
property real storedBarThickness: Theme.barHeight - 4
|
property real storedBarThickness: Theme.barHeight - 4
|
||||||
@@ -153,7 +153,7 @@ Item {
|
|||||||
setBarContext(pos, bottomGap);
|
setBarContext(pos, bottomGap);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _nextConnectedChromeToken() {
|
function _nextChromeClaimId() {
|
||||||
_connectedChromeSerial += 1;
|
_connectedChromeSerial += 1;
|
||||||
return layerNamespace + ":" + _connectedChromeSerial + ":" + (new Date()).getTime();
|
return layerNamespace + ":" + _connectedChromeSerial + ":" + (new Date()).getTime();
|
||||||
}
|
}
|
||||||
@@ -174,21 +174,21 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _publishConnectedChromeState(forceClaim, visibleOverride) {
|
function _publishConnectedChromeState(forceClaim, visibleOverride) {
|
||||||
if (!SettingsData.connectedFrameModeActive || !root.screen || !_connectedChromeToken)
|
if (!root.frameOwnsConnectedChrome || !root.screen || !_chromeClaimId)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const state = _connectedChromeState(visibleOverride);
|
const state = _connectedChromeState(visibleOverride);
|
||||||
if (forceClaim || !ConnectedModeState.hasPopoutOwner(_connectedChromeToken)) {
|
if (forceClaim || !ConnectedModeState.hasPopoutOwner(_chromeClaimId)) {
|
||||||
ConnectedModeState.claimPopout(_connectedChromeToken, state);
|
ConnectedModeState.claimPopout(_chromeClaimId, state);
|
||||||
} else {
|
} else {
|
||||||
ConnectedModeState.updatePopout(_connectedChromeToken, state);
|
ConnectedModeState.updatePopout(_chromeClaimId, state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _releaseConnectedChromeState() {
|
function _releaseConnectedChromeState() {
|
||||||
if (_connectedChromeToken)
|
if (_chromeClaimId)
|
||||||
ConnectedModeState.releasePopout(_connectedChromeToken);
|
ConnectedModeState.releasePopout(_chromeClaimId);
|
||||||
_connectedChromeToken = "";
|
_chromeClaimId = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── Exposed animation state for ConnectedModeState ────────────────────
|
// ─── Exposed animation state for ConnectedModeState ────────────────────
|
||||||
@@ -197,7 +197,7 @@ Item {
|
|||||||
|
|
||||||
// ─── ConnectedModeState sync ────────────────────────────────────────────
|
// ─── ConnectedModeState sync ────────────────────────────────────────────
|
||||||
function _syncPopoutChromeState() {
|
function _syncPopoutChromeState() {
|
||||||
if (!SettingsData.connectedFrameModeActive) {
|
if (!root.frameOwnsConnectedChrome) {
|
||||||
_releaseConnectedChromeState();
|
_releaseConnectedChromeState();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -207,9 +207,9 @@ Item {
|
|||||||
}
|
}
|
||||||
if (!contentWindow.visible && !shouldBeVisible)
|
if (!contentWindow.visible && !shouldBeVisible)
|
||||||
return;
|
return;
|
||||||
if (!_connectedChromeToken)
|
if (!_chromeClaimId)
|
||||||
_connectedChromeToken = _nextConnectedChromeToken();
|
_chromeClaimId = _nextChromeClaimId();
|
||||||
_publishConnectedChromeState(contentWindow.visible && !ConnectedModeState.hasPopoutOwner(_connectedChromeToken));
|
_publishConnectedChromeState(contentWindow.visible && !ConnectedModeState.hasPopoutOwner(_chromeClaimId));
|
||||||
}
|
}
|
||||||
|
|
||||||
onAlignedXChanged: _syncPopoutChromeState()
|
onAlignedXChanged: _syncPopoutChromeState()
|
||||||
@@ -233,10 +233,10 @@ Item {
|
|||||||
Connections {
|
Connections {
|
||||||
target: SettingsData
|
target: SettingsData
|
||||||
function onConnectedFrameModeActiveChanged() {
|
function onConnectedFrameModeActiveChanged() {
|
||||||
if (SettingsData.connectedFrameModeActive) {
|
if (root.frameOwnsConnectedChrome) {
|
||||||
if (contentWindow.visible || root.shouldBeVisible) {
|
if (contentWindow.visible || root.shouldBeVisible) {
|
||||||
if (!root._connectedChromeToken)
|
if (!root._chromeClaimId)
|
||||||
root._connectedChromeToken = root._nextConnectedChromeToken();
|
root._chromeClaimId = root._nextChromeClaimId();
|
||||||
root._publishConnectedChromeState(true);
|
root._publishConnectedChromeState(true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -246,6 +246,9 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
readonly property bool useBackgroundWindow: !CompositorService.isHyprland || CompositorService.useHyprlandFocusGrab
|
readonly property bool useBackgroundWindow: !CompositorService.isHyprland || CompositorService.useHyprlandFocusGrab
|
||||||
|
readonly property bool frameOwnsConnectedChrome: SettingsData.connectedFrameModeActive
|
||||||
|
&& !!root.screen
|
||||||
|
&& SettingsData.isScreenInPreferences(root.screen, SettingsData.frameScreenPreferences)
|
||||||
|
|
||||||
function updateSurfacePosition() {
|
function updateSurfacePosition() {
|
||||||
if (useBackgroundWindow && shouldBeVisible) {
|
if (useBackgroundWindow && shouldBeVisible) {
|
||||||
@@ -282,11 +285,11 @@ Item {
|
|||||||
contentContainer.scaleValue = root.animationScaleCollapsed;
|
contentContainer.scaleValue = root.animationScaleCollapsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SettingsData.connectedFrameModeActive) {
|
if (root.frameOwnsConnectedChrome) {
|
||||||
_connectedChromeToken = _nextConnectedChromeToken();
|
_chromeClaimId = _nextChromeClaimId();
|
||||||
_publishConnectedChromeState(true, true);
|
_publishConnectedChromeState(true, true);
|
||||||
} else {
|
} else {
|
||||||
_connectedChromeToken = "";
|
_chromeClaimId = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useBackgroundWindow) {
|
if (useBackgroundWindow) {
|
||||||
@@ -641,7 +644,7 @@ Item {
|
|||||||
WindowBlur {
|
WindowBlur {
|
||||||
id: popoutBlur
|
id: popoutBlur
|
||||||
targetWindow: contentWindow
|
targetWindow: contentWindow
|
||||||
blurEnabled: root.effectiveSurfaceBlurEnabled && !SettingsData.connectedFrameModeActive
|
blurEnabled: root.effectiveSurfaceBlurEnabled && !root.frameOwnsConnectedChrome
|
||||||
|
|
||||||
readonly property real s: Math.min(1, contentContainer.scaleValue)
|
readonly property real s: Math.min(1, contentContainer.scaleValue)
|
||||||
readonly property bool trackBlurFromBarEdge: Theme.isConnectedEffect || (typeof SettingsData !== "undefined" && Theme.isDirectionalEffect && SettingsData.directionalAnimationMode !== 2)
|
readonly property bool trackBlurFromBarEdge: Theme.isConnectedEffect || (typeof SettingsData !== "undefined" && Theme.isDirectionalEffect && SettingsData.directionalAnimationMode !== 2)
|
||||||
@@ -984,7 +987,7 @@ Item {
|
|||||||
|
|
||||||
Item {
|
Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: Theme.isConnectedEffect && !SettingsData.connectedFrameModeActive
|
visible: Theme.isConnectedEffect && !root.frameOwnsConnectedChrome
|
||||||
clip: false
|
clip: false
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
|||||||
Reference in New Issue
Block a user