1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-04-16 10:42:06 -04:00

feat(Frame): Close the gaps

This commit is contained in:
purian23
2026-04-14 23:26:58 -04:00
parent 995995034b
commit 59160ce5ac
9 changed files with 846 additions and 171 deletions

View File

@@ -29,6 +29,8 @@ Singleton {
property real popoutAnimX: 0 property real popoutAnimX: 0
property real popoutAnimY: 0 property real popoutAnimY: 0
property string popoutScreen: "" property string popoutScreen: ""
property bool popoutOmitStartConnector: false
property bool popoutOmitEndConnector: false
// Dock state (updated by Dock when connectedFrameModeActive), keyed by screen.name // Dock state (updated by Dock when connectedFrameModeActive), keyed by screen.name
property var dockStates: ({}) property var dockStates: ({})
@@ -70,6 +72,10 @@ Singleton {
popoutAnimY = Number(state.animY); popoutAnimY = Number(state.animY);
if (state.screen !== undefined) if (state.screen !== undefined)
popoutScreen = state.screen || ""; popoutScreen = state.screen || "";
if (state.omitStartConnector !== undefined)
popoutOmitStartConnector = !!state.omitStartConnector;
if (state.omitEndConnector !== undefined)
popoutOmitEndConnector = !!state.omitEndConnector;
return true; return true;
} }
@@ -88,6 +94,8 @@ Singleton {
popoutAnimX = 0; popoutAnimX = 0;
popoutAnimY = 0; popoutAnimY = 0;
popoutScreen = ""; popoutScreen = "";
popoutOmitStartConnector = false;
popoutOmitEndConnector = false;
return true; return true;
} }
@@ -175,7 +183,9 @@ Singleton {
"bodyX": 0, "bodyX": 0,
"bodyY": 0, "bodyY": 0,
"bodyW": 0, "bodyW": 0,
"bodyH": 0 "bodyH": 0,
"omitStartConnector": false,
"omitEndConnector": false
}) })
property var notificationStates: ({}) property var notificationStates: ({})
@@ -194,7 +204,9 @@ Singleton {
"bodyX": Number(state && state.bodyX !== undefined ? state.bodyX : 0), "bodyX": Number(state && state.bodyX !== undefined ? state.bodyX : 0),
"bodyY": Number(state && state.bodyY !== undefined ? state.bodyY : 0), "bodyY": Number(state && state.bodyY !== undefined ? state.bodyY : 0),
"bodyW": Number(state && state.bodyW !== undefined ? state.bodyW : 0), "bodyW": Number(state && state.bodyW !== undefined ? state.bodyW : 0),
"bodyH": Number(state && state.bodyH !== undefined ? state.bodyH : 0) "bodyH": Number(state && state.bodyH !== undefined ? state.bodyH : 0),
"omitStartConnector": !!(state && state.omitStartConnector),
"omitEndConnector": !!(state && state.omitEndConnector)
}; };
} }

View File

@@ -235,6 +235,8 @@ Singleton {
onFrameShowOnOverviewChanged: saveSettings() onFrameShowOnOverviewChanged: saveSettings()
property bool frameBlurEnabled: true property bool frameBlurEnabled: true
onFrameBlurEnabledChanged: saveSettings() onFrameBlurEnabledChanged: saveSettings()
property bool frameCloseGaps: false
onFrameCloseGapsChanged: saveSettings()
property int previousDirectionalMode: 1 property int previousDirectionalMode: 1
onPreviousDirectionalModeChanged: saveSettings() onPreviousDirectionalModeChanged: saveSettings()
property var connectedFrameBarStyleBackups: ({}) property var connectedFrameBarStyleBackups: ({})

View File

@@ -552,7 +552,8 @@ var SPEC = {
frameScreenPreferences: { def: ["all"] }, frameScreenPreferences: { def: ["all"] },
frameBarSize: { def: 40 }, frameBarSize: { def: 40 },
frameShowOnOverview: { def: false }, frameShowOnOverview: { def: false },
frameBlurEnabled: { def: true } frameBlurEnabled: { def: true },
frameCloseGaps: { def: false }
}; };
function getValidKeys() { function getValidKeys() {

View File

@@ -66,12 +66,34 @@ PanelWindow {
const crossSize = isHoriz ? _popoutBodyBlurAnchor.width : _popoutBodyBlurAnchor.height; const crossSize = isHoriz ? _popoutBodyBlurAnchor.width : _popoutBodyBlurAnchor.height;
return Math.max(0, Math.min(win._ccr, extent, crossSize / 2)); return Math.max(0, Math.min(win._ccr, extent, crossSize / 2));
} }
readonly property real _effectivePopoutFarCcr: {
const isHoriz = ConnectedModeState.popoutBarSide === "top" || ConnectedModeState.popoutBarSide === "bottom";
const crossSize = isHoriz ? _popoutBodyBlurAnchor.width : _popoutBodyBlurAnchor.height;
return Math.max(0, Math.min(win._ccr, win._surfaceRadius, crossSize / 2));
}
readonly property real _effectivePopoutStartCcr: ConnectedModeState.popoutOmitStartConnector ? 0 : win._effectivePopoutCcr
readonly property real _effectivePopoutEndCcr: ConnectedModeState.popoutOmitEndConnector ? 0 : win._effectivePopoutCcr
readonly property real _effectivePopoutFarStartCcr: ConnectedModeState.popoutOmitStartConnector ? win._effectivePopoutFarCcr : 0
readonly property real _effectivePopoutFarEndCcr: ConnectedModeState.popoutOmitEndConnector ? win._effectivePopoutFarCcr : 0
readonly property real _effectivePopoutMaxCcr: Math.max(win._effectivePopoutStartCcr, win._effectivePopoutEndCcr)
readonly property real _effectivePopoutFarExtent: Math.max(win._effectivePopoutFarStartCcr, win._effectivePopoutFarEndCcr)
readonly property real _effectiveNotifCcr: { readonly property real _effectiveNotifCcr: {
const isHoriz = win._notifState.barSide === "top" || win._notifState.barSide === "bottom"; const isHoriz = win._notifState.barSide === "top" || win._notifState.barSide === "bottom";
const crossSize = isHoriz ? _notifBodyBlurAnchor.width : _notifBodyBlurAnchor.height; const crossSize = isHoriz ? _notifBodyBlurAnchor.width : _notifBodyBlurAnchor.height;
const extent = isHoriz ? _notifBodyBlurAnchor.height : _notifBodyBlurAnchor.width; const extent = isHoriz ? _notifBodyBlurAnchor.height : _notifBodyBlurAnchor.width;
return Theme.snap(Math.max(0, Math.min(win._ccr, win._surfaceRadius, extent, crossSize / 2)), win._dpr); return Theme.snap(Math.max(0, Math.min(win._ccr, win._surfaceRadius, extent, crossSize / 2)), win._dpr);
} }
readonly property real _effectiveNotifFarCcr: {
const isHoriz = win._notifState.barSide === "top" || win._notifState.barSide === "bottom";
const crossSize = isHoriz ? _notifBodySceneBlurAnchor.width : _notifBodySceneBlurAnchor.height;
return Theme.snap(Math.max(0, Math.min(win._ccr, win._surfaceRadius, crossSize / 2)), win._dpr);
}
readonly property real _effectiveNotifStartCcr: win._notifState.omitStartConnector ? 0 : win._effectiveNotifCcr
readonly property real _effectiveNotifEndCcr: win._notifState.omitEndConnector ? 0 : win._effectiveNotifCcr
readonly property real _effectiveNotifFarStartCcr: win._notifState.omitStartConnector ? win._effectiveNotifFarCcr : 0
readonly property real _effectiveNotifFarEndCcr: win._notifState.omitEndConnector ? win._effectiveNotifFarCcr : 0
readonly property real _effectiveNotifMaxCcr: Math.max(win._effectiveNotifStartCcr, win._effectiveNotifEndCcr)
readonly property real _effectiveNotifFarExtent: Math.max(win._effectiveNotifFarStartCcr, win._effectiveNotifFarEndCcr)
readonly property color _surfaceColor: Theme.connectedSurfaceColor readonly property color _surfaceColor: Theme.connectedSurfaceColor
readonly property real _surfaceOpacity: _surfaceColor.a readonly property real _surfaceOpacity: _surfaceColor.a
readonly property color _opaqueSurfaceColor: Qt.rgba(_surfaceColor.r, _surfaceColor.g, _surfaceColor.b, 1) readonly property color _opaqueSurfaceColor: Qt.rgba(_surfaceColor.r, _surfaceColor.g, _surfaceColor.b, 1)
@@ -121,8 +143,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 * 1.02, ConnectedModeState.popoutBodyH)) : 0 readonly property real _dyClamp: (ConnectedModeState.popoutBarSide === "top" || ConnectedModeState.popoutBarSide === "bottom") ? Math.max(-ConnectedModeState.popoutBodyH, Math.min(ConnectedModeState.popoutAnimY, ConnectedModeState.popoutBodyH)) : 0
readonly property real _dxClamp: (ConnectedModeState.popoutBarSide === "left" || ConnectedModeState.popoutBarSide === "right") ? Math.max(-ConnectedModeState.popoutBodyW, Math.min(ConnectedModeState.popoutAnimX * 1.02, ConnectedModeState.popoutBodyW)) : 0 readonly property real _dxClamp: (ConnectedModeState.popoutBarSide === "left" || ConnectedModeState.popoutBarSide === "right") ? Math.max(-ConnectedModeState.popoutBodyW, Math.min(ConnectedModeState.popoutAnimX, 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
@@ -177,9 +199,10 @@ PanelWindow {
id: _popoutLeftConnectorBlurAnchor id: _popoutLeftConnectorBlurAnchor
opacity: 0 opacity: 0
readonly property bool _active: _popoutBodyBlurAnchor._active && win._effectivePopoutCcr > 0 readonly property real _radius: win._popoutConnectorRadius("left")
readonly property real _w: win._popoutConnectorWidth(0) readonly property bool _active: _popoutBodyBlurAnchor._active && _radius > 0
readonly property real _h: win._popoutConnectorHeight(0) readonly property real _w: win._popoutConnectorWidth(0, "left")
readonly property real _h: win._popoutConnectorHeight(0, "left")
x: _active ? Theme.snap(win._popoutConnectorX(_popoutBodyBlurAnchor.x, _popoutBodyBlurAnchor.width, "left", 0), win._dpr) : 0 x: _active ? Theme.snap(win._popoutConnectorX(_popoutBodyBlurAnchor.x, _popoutBodyBlurAnchor.width, "left", 0), win._dpr) : 0
y: _active ? Theme.snap(win._popoutConnectorY(_popoutBodyBlurAnchor.y, _popoutBodyBlurAnchor.height, "left", 0), win._dpr) : 0 y: _active ? Theme.snap(win._popoutConnectorY(_popoutBodyBlurAnchor.y, _popoutBodyBlurAnchor.height, "left", 0), win._dpr) : 0
@@ -191,9 +214,10 @@ PanelWindow {
id: _popoutRightConnectorBlurAnchor id: _popoutRightConnectorBlurAnchor
opacity: 0 opacity: 0
readonly property bool _active: _popoutBodyBlurAnchor._active && win._effectivePopoutCcr > 0 readonly property real _radius: win._popoutConnectorRadius("right")
readonly property real _w: win._popoutConnectorWidth(0) readonly property bool _active: _popoutBodyBlurAnchor._active && _radius > 0
readonly property real _h: win._popoutConnectorHeight(0) readonly property real _w: win._popoutConnectorWidth(0, "right")
readonly property real _h: win._popoutConnectorHeight(0, "right")
x: _active ? Theme.snap(win._popoutConnectorX(_popoutBodyBlurAnchor.x, _popoutBodyBlurAnchor.width, "right", 0), win._dpr) : 0 x: _active ? Theme.snap(win._popoutConnectorX(_popoutBodyBlurAnchor.x, _popoutBodyBlurAnchor.width, "right", 0), win._dpr) : 0
y: _active ? Theme.snap(win._popoutConnectorY(_popoutBodyBlurAnchor.y, _popoutBodyBlurAnchor.height, "right", 0), win._dpr) : 0 y: _active ? Theme.snap(win._popoutConnectorY(_popoutBodyBlurAnchor.y, _popoutBodyBlurAnchor.height, "right", 0), win._dpr) : 0
@@ -207,11 +231,12 @@ PanelWindow {
readonly property bool _active: _popoutLeftConnectorBlurAnchor.width > 0 && _popoutLeftConnectorBlurAnchor.height > 0 readonly property bool _active: _popoutLeftConnectorBlurAnchor.width > 0 && _popoutLeftConnectorBlurAnchor.height > 0
readonly property string _arcCorner: win._connectorArcCorner(ConnectedModeState.popoutBarSide, "left") readonly property string _arcCorner: win._connectorArcCorner(ConnectedModeState.popoutBarSide, "left")
readonly property real _radius: win._popoutConnectorRadius("left")
x: _active ? win._connectorCutoutX(_popoutLeftConnectorBlurAnchor.x, _popoutLeftConnectorBlurAnchor.width, _arcCorner, win._effectivePopoutCcr) : 0 x: _active ? win._connectorCutoutX(_popoutLeftConnectorBlurAnchor.x, _popoutLeftConnectorBlurAnchor.width, _arcCorner, _radius) : 0
y: _active ? win._connectorCutoutY(_popoutLeftConnectorBlurAnchor.y, _popoutLeftConnectorBlurAnchor.height, _arcCorner, win._effectivePopoutCcr) : 0 y: _active ? win._connectorCutoutY(_popoutLeftConnectorBlurAnchor.y, _popoutLeftConnectorBlurAnchor.height, _arcCorner, _radius) : 0
width: _active ? win._effectivePopoutCcr * 2 : 0 width: _active ? _radius * 2 : 0
height: _active ? win._effectivePopoutCcr * 2 : 0 height: _active ? _radius * 2 : 0
} }
Item { Item {
@@ -220,11 +245,96 @@ PanelWindow {
readonly property bool _active: _popoutRightConnectorBlurAnchor.width > 0 && _popoutRightConnectorBlurAnchor.height > 0 readonly property bool _active: _popoutRightConnectorBlurAnchor.width > 0 && _popoutRightConnectorBlurAnchor.height > 0
readonly property string _arcCorner: win._connectorArcCorner(ConnectedModeState.popoutBarSide, "right") readonly property string _arcCorner: win._connectorArcCorner(ConnectedModeState.popoutBarSide, "right")
readonly property real _radius: win._popoutConnectorRadius("right")
x: _active ? win._connectorCutoutX(_popoutRightConnectorBlurAnchor.x, _popoutRightConnectorBlurAnchor.width, _arcCorner, win._effectivePopoutCcr) : 0 x: _active ? win._connectorCutoutX(_popoutRightConnectorBlurAnchor.x, _popoutRightConnectorBlurAnchor.width, _arcCorner, _radius) : 0
y: _active ? win._connectorCutoutY(_popoutRightConnectorBlurAnchor.y, _popoutRightConnectorBlurAnchor.height, _arcCorner, win._effectivePopoutCcr) : 0 y: _active ? win._connectorCutoutY(_popoutRightConnectorBlurAnchor.y, _popoutRightConnectorBlurAnchor.height, _arcCorner, _radius) : 0
width: _active ? win._effectivePopoutCcr * 2 : 0 width: _active ? _radius * 2 : 0
height: _active ? win._effectivePopoutCcr * 2 : 0 height: _active ? _radius * 2 : 0
}
Item {
id: _popoutFarStartConnectorBlurAnchor
opacity: 0
readonly property real _radius: win._effectivePopoutFarStartCcr
readonly property bool _active: _popoutBodyBlurAnchor._active && _radius > 0
x: _active ? Theme.snap(win._farConnectorX(_popoutBodyBlurAnchor.x, _popoutBodyBlurAnchor.y, _popoutBodyBlurAnchor.width, _popoutBodyBlurAnchor.height, ConnectedModeState.popoutBarSide, "left", _radius), win._dpr) : 0
y: _active ? Theme.snap(win._farConnectorY(_popoutBodyBlurAnchor.x, _popoutBodyBlurAnchor.y, _popoutBodyBlurAnchor.width, _popoutBodyBlurAnchor.height, ConnectedModeState.popoutBarSide, "left", _radius), win._dpr) : 0
width: _active ? _radius : 0
height: _active ? _radius : 0
}
Item {
id: _popoutFarStartBodyBlurCap
opacity: 0
readonly property real _radius: win._effectivePopoutFarStartCcr
readonly property bool _active: _popoutBodyBlurAnchor._active && _radius > 0
x: _active ? Theme.snap(win._farBodyCapX(_popoutBodyBlurAnchor.x, _popoutBodyBlurAnchor.width, ConnectedModeState.popoutBarSide, "left", _radius), win._dpr) : 0
y: _active ? Theme.snap(win._farBodyCapY(_popoutBodyBlurAnchor.y, _popoutBodyBlurAnchor.height, ConnectedModeState.popoutBarSide, "left", _radius), win._dpr) : 0
width: _active ? _radius : 0
height: _active ? _radius : 0
}
Item {
id: _popoutFarEndBodyBlurCap
opacity: 0
readonly property real _radius: win._effectivePopoutFarEndCcr
readonly property bool _active: _popoutBodyBlurAnchor._active && _radius > 0
x: _active ? Theme.snap(win._farBodyCapX(_popoutBodyBlurAnchor.x, _popoutBodyBlurAnchor.width, ConnectedModeState.popoutBarSide, "right", _radius), win._dpr) : 0
y: _active ? Theme.snap(win._farBodyCapY(_popoutBodyBlurAnchor.y, _popoutBodyBlurAnchor.height, ConnectedModeState.popoutBarSide, "right", _radius), win._dpr) : 0
width: _active ? _radius : 0
height: _active ? _radius : 0
}
Item {
id: _popoutFarEndConnectorBlurAnchor
opacity: 0
readonly property real _radius: win._effectivePopoutFarEndCcr
readonly property bool _active: _popoutBodyBlurAnchor._active && _radius > 0
x: _active ? Theme.snap(win._farConnectorX(_popoutBodyBlurAnchor.x, _popoutBodyBlurAnchor.y, _popoutBodyBlurAnchor.width, _popoutBodyBlurAnchor.height, ConnectedModeState.popoutBarSide, "right", _radius), win._dpr) : 0
y: _active ? Theme.snap(win._farConnectorY(_popoutBodyBlurAnchor.x, _popoutBodyBlurAnchor.y, _popoutBodyBlurAnchor.width, _popoutBodyBlurAnchor.height, ConnectedModeState.popoutBarSide, "right", _radius), win._dpr) : 0
width: _active ? _radius : 0
height: _active ? _radius : 0
}
Item {
id: _popoutFarStartConnectorCutout
opacity: 0
readonly property bool _active: _popoutFarStartConnectorBlurAnchor.width > 0 && _popoutFarStartConnectorBlurAnchor.height > 0
readonly property string _barSide: win._farConnectorBarSide(ConnectedModeState.popoutBarSide, "left")
readonly property string _placement: win._farConnectorPlacement(ConnectedModeState.popoutBarSide, "left")
readonly property string _arcCorner: win._connectorArcCorner(_barSide, _placement)
readonly property real _radius: win._effectivePopoutFarStartCcr
x: _active ? win._connectorCutoutX(_popoutFarStartConnectorBlurAnchor.x, _popoutFarStartConnectorBlurAnchor.width, _arcCorner, _radius) : 0
y: _active ? win._connectorCutoutY(_popoutFarStartConnectorBlurAnchor.y, _popoutFarStartConnectorBlurAnchor.height, _arcCorner, _radius) : 0
width: _active ? _radius * 2 : 0
height: _active ? _radius * 2 : 0
}
Item {
id: _popoutFarEndConnectorCutout
opacity: 0
readonly property bool _active: _popoutFarEndConnectorBlurAnchor.width > 0 && _popoutFarEndConnectorBlurAnchor.height > 0
readonly property string _barSide: win._farConnectorBarSide(ConnectedModeState.popoutBarSide, "right")
readonly property string _placement: win._farConnectorPlacement(ConnectedModeState.popoutBarSide, "right")
readonly property string _arcCorner: win._connectorArcCorner(_barSide, _placement)
readonly property real _radius: win._effectivePopoutFarEndCcr
x: _active ? win._connectorCutoutX(_popoutFarEndConnectorBlurAnchor.x, _popoutFarEndConnectorBlurAnchor.width, _arcCorner, _radius) : 0
y: _active ? win._connectorCutoutY(_popoutFarEndConnectorBlurAnchor.y, _popoutFarEndConnectorBlurAnchor.height, _arcCorner, _radius) : 0
width: _active ? _radius * 2 : 0
height: _active ? _radius * 2 : 0
} }
Item { Item {
@@ -293,17 +403,30 @@ PanelWindow {
height: _active ? Theme.snap(win._notifState.bodyH, win._dpr) : 0 height: _active ? Theme.snap(win._notifState.bodyH, win._dpr) : 0
} }
Item {
id: _notifBodySceneBlurAnchor
visible: false
readonly property bool _active: _notifBodyBlurAnchor._active
x: _active ? Theme.snap(win._notifBodySceneX(), win._dpr) : 0
y: _active ? Theme.snap(win._notifBodySceneY(), win._dpr) : 0
width: _active ? Theme.snap(win._notifBodySceneWidth(), win._dpr) : 0
height: _active ? Theme.snap(win._notifBodySceneHeight(), win._dpr) : 0
}
Item { Item {
id: _notifBodyBlurCap id: _notifBodyBlurCap
opacity: 0 opacity: 0
readonly property string _side: win._notifState.barSide readonly property string _side: win._notifState.barSide
readonly property bool _active: _notifBodyBlurAnchor._active && _notifBodyBlurAnchor.width > 0 && _notifBodyBlurAnchor.height > 0 && win._notifConnectorRadius() > 0 readonly property real _capRadius: win._notifMaxConnectorRadius()
readonly property real _capWidth: (_side === "left" || _side === "right") ? Math.min(win._notifConnectorRadius(), _notifBodyBlurAnchor.width) : _notifBodyBlurAnchor.width readonly property bool _active: _notifBodySceneBlurAnchor._active && _notifBodySceneBlurAnchor.width > 0 && _notifBodySceneBlurAnchor.height > 0 && _capRadius > 0
readonly property real _capHeight: (_side === "top" || _side === "bottom") ? Math.min(win._notifConnectorRadius(), _notifBodyBlurAnchor.height) : _notifBodyBlurAnchor.height readonly property real _capWidth: (_side === "left" || _side === "right") ? Math.min(_capRadius, _notifBodySceneBlurAnchor.width) : _notifBodySceneBlurAnchor.width
readonly property real _capHeight: (_side === "top" || _side === "bottom") ? Math.min(_capRadius, _notifBodySceneBlurAnchor.height) : _notifBodySceneBlurAnchor.height
x: !_active ? 0 : (_side === "right" ? _notifBodyBlurAnchor.x + _notifBodyBlurAnchor.width - _capWidth : _notifBodyBlurAnchor.x) x: !_active ? 0 : (_side === "right" ? _notifBodySceneBlurAnchor.x + _notifBodySceneBlurAnchor.width - _capWidth : _notifBodySceneBlurAnchor.x)
y: !_active ? 0 : (_side === "bottom" ? _notifBodyBlurAnchor.y + _notifBodyBlurAnchor.height - _capHeight : _notifBodyBlurAnchor.y) y: !_active ? 0 : (_side === "bottom" ? _notifBodySceneBlurAnchor.y + _notifBodySceneBlurAnchor.height - _capHeight : _notifBodySceneBlurAnchor.y)
width: _active ? _capWidth : 0 width: _active ? _capWidth : 0
height: _active ? _capHeight : 0 height: _active ? _capHeight : 0
} }
@@ -312,12 +435,13 @@ PanelWindow {
id: _notifLeftConnectorBlurAnchor id: _notifLeftConnectorBlurAnchor
opacity: 0 opacity: 0
readonly property bool _active: _notifBodyBlurAnchor._active && win._notifConnectorRadius() > 0 readonly property real _radius: win._notifConnectorRadius("left")
readonly property real _w: win._notifConnectorWidth(0) readonly property bool _active: _notifBodySceneBlurAnchor._active && _radius > 0
readonly property real _h: win._notifConnectorHeight(0) readonly property real _w: win._notifConnectorWidth(0, "left")
readonly property real _h: win._notifConnectorHeight(0, "left")
x: _active ? Theme.snap(win._notifConnectorX(_notifBodyBlurAnchor.x, _notifBodyBlurAnchor.width, "left", 0), win._dpr) : 0 x: _active ? Theme.snap(win._notifConnectorX(_notifBodySceneBlurAnchor.x, _notifBodySceneBlurAnchor.width, "left", 0), win._dpr) : 0
y: _active ? Theme.snap(win._notifConnectorY(_notifBodyBlurAnchor.y, _notifBodyBlurAnchor.height, "left", 0), win._dpr) : 0 y: _active ? Theme.snap(win._notifConnectorY(_notifBodySceneBlurAnchor.y, _notifBodySceneBlurAnchor.height, "left", 0), win._dpr) : 0
width: _active ? _w : 0 width: _active ? _w : 0
height: _active ? _h : 0 height: _active ? _h : 0
} }
@@ -326,12 +450,13 @@ PanelWindow {
id: _notifRightConnectorBlurAnchor id: _notifRightConnectorBlurAnchor
opacity: 0 opacity: 0
readonly property bool _active: _notifBodyBlurAnchor._active && win._notifConnectorRadius() > 0 readonly property real _radius: win._notifConnectorRadius("right")
readonly property real _w: win._notifConnectorWidth(0) readonly property bool _active: _notifBodySceneBlurAnchor._active && _radius > 0
readonly property real _h: win._notifConnectorHeight(0) readonly property real _w: win._notifConnectorWidth(0, "right")
readonly property real _h: win._notifConnectorHeight(0, "right")
x: _active ? Theme.snap(win._notifConnectorX(_notifBodyBlurAnchor.x, _notifBodyBlurAnchor.width, "right", 0), win._dpr) : 0 x: _active ? Theme.snap(win._notifConnectorX(_notifBodySceneBlurAnchor.x, _notifBodySceneBlurAnchor.width, "right", 0), win._dpr) : 0
y: _active ? Theme.snap(win._notifConnectorY(_notifBodyBlurAnchor.y, _notifBodyBlurAnchor.height, "right", 0), win._dpr) : 0 y: _active ? Theme.snap(win._notifConnectorY(_notifBodySceneBlurAnchor.y, _notifBodySceneBlurAnchor.height, "right", 0), win._dpr) : 0
width: _active ? _w : 0 width: _active ? _w : 0
height: _active ? _h : 0 height: _active ? _h : 0
} }
@@ -342,11 +467,12 @@ PanelWindow {
readonly property bool _active: _notifLeftConnectorBlurAnchor.width > 0 && _notifLeftConnectorBlurAnchor.height > 0 readonly property bool _active: _notifLeftConnectorBlurAnchor.width > 0 && _notifLeftConnectorBlurAnchor.height > 0
readonly property string _arcCorner: win._connectorArcCorner(win._notifState.barSide, "left") readonly property string _arcCorner: win._connectorArcCorner(win._notifState.barSide, "left")
readonly property real _radius: win._notifConnectorRadius("left")
x: _active ? win._connectorCutoutX(_notifLeftConnectorBlurAnchor.x, _notifLeftConnectorBlurAnchor.width, _arcCorner, win._notifConnectorRadius()) : 0 x: _active ? win._connectorCutoutX(_notifLeftConnectorBlurAnchor.x, _notifLeftConnectorBlurAnchor.width, _arcCorner, _radius) : 0
y: _active ? win._connectorCutoutY(_notifLeftConnectorBlurAnchor.y, _notifLeftConnectorBlurAnchor.height, _arcCorner, win._notifConnectorRadius()) : 0 y: _active ? win._connectorCutoutY(_notifLeftConnectorBlurAnchor.y, _notifLeftConnectorBlurAnchor.height, _arcCorner, _radius) : 0
width: _active ? win._notifConnectorRadius() * 2 : 0 width: _active ? _radius * 2 : 0
height: _active ? win._notifConnectorRadius() * 2 : 0 height: _active ? _radius * 2 : 0
} }
Item { Item {
@@ -355,11 +481,96 @@ PanelWindow {
readonly property bool _active: _notifRightConnectorBlurAnchor.width > 0 && _notifRightConnectorBlurAnchor.height > 0 readonly property bool _active: _notifRightConnectorBlurAnchor.width > 0 && _notifRightConnectorBlurAnchor.height > 0
readonly property string _arcCorner: win._connectorArcCorner(win._notifState.barSide, "right") readonly property string _arcCorner: win._connectorArcCorner(win._notifState.barSide, "right")
readonly property real _radius: win._notifConnectorRadius("right")
x: _active ? win._connectorCutoutX(_notifRightConnectorBlurAnchor.x, _notifRightConnectorBlurAnchor.width, _arcCorner, win._notifConnectorRadius()) : 0 x: _active ? win._connectorCutoutX(_notifRightConnectorBlurAnchor.x, _notifRightConnectorBlurAnchor.width, _arcCorner, _radius) : 0
y: _active ? win._connectorCutoutY(_notifRightConnectorBlurAnchor.y, _notifRightConnectorBlurAnchor.height, _arcCorner, win._notifConnectorRadius()) : 0 y: _active ? win._connectorCutoutY(_notifRightConnectorBlurAnchor.y, _notifRightConnectorBlurAnchor.height, _arcCorner, _radius) : 0
width: _active ? win._notifConnectorRadius() * 2 : 0 width: _active ? _radius * 2 : 0
height: _active ? win._notifConnectorRadius() * 2 : 0 height: _active ? _radius * 2 : 0
}
Item {
id: _notifFarStartConnectorBlurAnchor
opacity: 0
readonly property real _radius: win._effectiveNotifFarStartCcr
readonly property bool _active: _notifBodySceneBlurAnchor._active && _radius > 0
x: _active ? Theme.snap(win._farConnectorX(_notifBodySceneBlurAnchor.x, _notifBodySceneBlurAnchor.y, _notifBodySceneBlurAnchor.width, _notifBodySceneBlurAnchor.height, win._notifState.barSide, "left", _radius), win._dpr) : 0
y: _active ? Theme.snap(win._farConnectorY(_notifBodySceneBlurAnchor.x, _notifBodySceneBlurAnchor.y, _notifBodySceneBlurAnchor.width, _notifBodySceneBlurAnchor.height, win._notifState.barSide, "left", _radius), win._dpr) : 0
width: _active ? _radius : 0
height: _active ? _radius : 0
}
Item {
id: _notifFarStartBodyBlurCap
opacity: 0
readonly property real _radius: win._effectiveNotifFarStartCcr
readonly property bool _active: _notifBodySceneBlurAnchor._active && _radius > 0
x: _active ? Theme.snap(win._farBodyCapX(_notifBodySceneBlurAnchor.x, _notifBodySceneBlurAnchor.width, win._notifState.barSide, "left", _radius), win._dpr) : 0
y: _active ? Theme.snap(win._farBodyCapY(_notifBodySceneBlurAnchor.y, _notifBodySceneBlurAnchor.height, win._notifState.barSide, "left", _radius), win._dpr) : 0
width: _active ? _radius : 0
height: _active ? _radius : 0
}
Item {
id: _notifFarEndBodyBlurCap
opacity: 0
readonly property real _radius: win._effectiveNotifFarEndCcr
readonly property bool _active: _notifBodySceneBlurAnchor._active && _radius > 0
x: _active ? Theme.snap(win._farBodyCapX(_notifBodySceneBlurAnchor.x, _notifBodySceneBlurAnchor.width, win._notifState.barSide, "right", _radius), win._dpr) : 0
y: _active ? Theme.snap(win._farBodyCapY(_notifBodySceneBlurAnchor.y, _notifBodySceneBlurAnchor.height, win._notifState.barSide, "right", _radius), win._dpr) : 0
width: _active ? _radius : 0
height: _active ? _radius : 0
}
Item {
id: _notifFarEndConnectorBlurAnchor
opacity: 0
readonly property real _radius: win._effectiveNotifFarEndCcr
readonly property bool _active: _notifBodySceneBlurAnchor._active && _radius > 0
x: _active ? Theme.snap(win._farConnectorX(_notifBodySceneBlurAnchor.x, _notifBodySceneBlurAnchor.y, _notifBodySceneBlurAnchor.width, _notifBodySceneBlurAnchor.height, win._notifState.barSide, "right", _radius), win._dpr) : 0
y: _active ? Theme.snap(win._farConnectorY(_notifBodySceneBlurAnchor.x, _notifBodySceneBlurAnchor.y, _notifBodySceneBlurAnchor.width, _notifBodySceneBlurAnchor.height, win._notifState.barSide, "right", _radius), win._dpr) : 0
width: _active ? _radius : 0
height: _active ? _radius : 0
}
Item {
id: _notifFarStartConnectorCutout
opacity: 0
readonly property bool _active: _notifFarStartConnectorBlurAnchor.width > 0 && _notifFarStartConnectorBlurAnchor.height > 0
readonly property string _barSide: win._farConnectorBarSide(win._notifState.barSide, "left")
readonly property string _placement: win._farConnectorPlacement(win._notifState.barSide, "left")
readonly property string _arcCorner: win._connectorArcCorner(_barSide, _placement)
readonly property real _radius: win._effectiveNotifFarStartCcr
x: _active ? win._connectorCutoutX(_notifFarStartConnectorBlurAnchor.x, _notifFarStartConnectorBlurAnchor.width, _arcCorner, _radius) : 0
y: _active ? win._connectorCutoutY(_notifFarStartConnectorBlurAnchor.y, _notifFarStartConnectorBlurAnchor.height, _arcCorner, _radius) : 0
width: _active ? _radius * 2 : 0
height: _active ? _radius * 2 : 0
}
Item {
id: _notifFarEndConnectorCutout
opacity: 0
readonly property bool _active: _notifFarEndConnectorBlurAnchor.width > 0 && _notifFarEndConnectorBlurAnchor.height > 0
readonly property string _barSide: win._farConnectorBarSide(win._notifState.barSide, "right")
readonly property string _placement: win._farConnectorPlacement(win._notifState.barSide, "right")
readonly property string _arcCorner: win._connectorArcCorner(_barSide, _placement)
readonly property real _radius: win._effectiveNotifFarEndCcr
x: _active ? win._connectorCutoutX(_notifFarEndConnectorBlurAnchor.x, _notifFarEndConnectorBlurAnchor.width, _arcCorner, _radius) : 0
y: _active ? win._connectorCutoutY(_notifFarEndConnectorBlurAnchor.y, _notifFarEndConnectorBlurAnchor.height, _arcCorner, _radius) : 0
width: _active ? _radius * 2 : 0
height: _active ? _radius * 2 : 0
} }
Region { Region {
@@ -389,7 +600,7 @@ PanelWindow {
Region { Region {
item: _popoutLeftConnectorCutout item: _popoutLeftConnectorCutout
intersection: Intersection.Subtract intersection: Intersection.Subtract
radius: win._effectivePopoutCcr radius: win._popoutConnectorRadius("left")
} }
} }
Region { Region {
@@ -397,7 +608,29 @@ PanelWindow {
Region { Region {
item: _popoutRightConnectorCutout item: _popoutRightConnectorCutout
intersection: Intersection.Subtract intersection: Intersection.Subtract
radius: win._effectivePopoutCcr radius: win._popoutConnectorRadius("right")
}
}
Region {
item: _popoutFarStartBodyBlurCap
}
Region {
item: _popoutFarEndBodyBlurCap
}
Region {
item: _popoutFarStartConnectorBlurAnchor
Region {
item: _popoutFarStartConnectorCutout
intersection: Intersection.Subtract
radius: win._effectivePopoutFarStartCcr
}
}
Region {
item: _popoutFarEndConnectorBlurAnchor
Region {
item: _popoutFarEndConnectorCutout
intersection: Intersection.Subtract
radius: win._effectivePopoutFarEndCcr
} }
} }
@@ -427,7 +660,7 @@ PanelWindow {
} }
Region { Region {
item: _notifBodyBlurAnchor item: _notifBodySceneBlurAnchor
radius: win._surfaceRadius radius: win._surfaceRadius
} }
Region { Region {
@@ -438,7 +671,7 @@ PanelWindow {
Region { Region {
item: _notifLeftConnectorCutout item: _notifLeftConnectorCutout
intersection: Intersection.Subtract intersection: Intersection.Subtract
radius: win._notifConnectorRadius() radius: win._notifConnectorRadius("left")
} }
} }
Region { Region {
@@ -446,7 +679,29 @@ PanelWindow {
Region { Region {
item: _notifRightConnectorCutout item: _notifRightConnectorCutout
intersection: Intersection.Subtract intersection: Intersection.Subtract
radius: win._notifConnectorRadius() radius: win._notifConnectorRadius("right")
}
}
Region {
item: _notifFarStartBodyBlurCap
}
Region {
item: _notifFarEndBodyBlurCap
}
Region {
item: _notifFarStartConnectorBlurAnchor
Region {
item: _notifFarStartConnectorCutout
intersection: Intersection.Subtract
radius: win._effectiveNotifFarStartCcr
}
}
Region {
item: _notifFarEndConnectorBlurAnchor
Region {
item: _notifFarEndConnectorCutout
intersection: Intersection.Subtract
radius: win._effectiveNotifFarEndCcr
} }
} }
} }
@@ -500,19 +755,68 @@ PanelWindow {
return placement === "left" ? seamY - h : seamY; return placement === "left" ? seamY - h : seamY;
} }
function _notifConnectorRadius() { function _notifSideUnderlap() {
return win._effectiveNotifCcr; const side = win._notifState.barSide;
return (side === "left" || side === "right") ? win._seamOverlap : 0;
} }
function _notifConnectorWidth(spacing) { function _notifStartUnderlap() {
return win._notifState.omitStartConnector ? win._seamOverlap : 0;
}
function _notifEndUnderlap() {
return win._notifState.omitEndConnector ? win._seamOverlap : 0;
}
function _notifBodySceneX() {
const side = win._notifState.barSide;
const isHoriz = side === "top" || side === "bottom";
if (isHoriz)
return _notifBodyBlurAnchor.x - win._notifStartUnderlap();
return _notifBodyBlurAnchor.x - (side === "left" ? win._notifSideUnderlap() : 0);
}
function _notifBodySceneY() {
const side = win._notifState.barSide;
const isHoriz = side === "top" || side === "bottom";
if (isHoriz)
return _notifBodyBlurAnchor.y;
return _notifBodyBlurAnchor.y - win._notifStartUnderlap();
}
function _notifBodySceneWidth() {
const side = win._notifState.barSide;
const isHoriz = side === "top" || side === "bottom";
if (isHoriz)
return _notifBodyBlurAnchor.width + win._notifStartUnderlap() + win._notifEndUnderlap();
return _notifBodyBlurAnchor.width + win._notifSideUnderlap();
}
function _notifBodySceneHeight() {
const side = win._notifState.barSide;
const isHoriz = side === "top" || side === "bottom";
if (isHoriz)
return _notifBodyBlurAnchor.height;
return _notifBodyBlurAnchor.height + win._notifStartUnderlap() + win._notifEndUnderlap();
}
function _notifConnectorRadius(placement) {
return placement === "right" ? win._effectiveNotifEndCcr : win._effectiveNotifStartCcr;
}
function _notifMaxConnectorRadius() {
return win._effectiveNotifMaxCcr;
}
function _notifConnectorWidth(spacing, placement) {
const isVert = win._notifState.barSide === "left" || win._notifState.barSide === "right"; const isVert = win._notifState.barSide === "left" || win._notifState.barSide === "right";
const radius = win._notifConnectorRadius(); const radius = win._notifConnectorRadius(placement);
return isVert ? (spacing + radius) : radius; return isVert ? (spacing + radius) : radius;
} }
function _notifConnectorHeight(spacing) { function _notifConnectorHeight(spacing, placement) {
const isVert = win._notifState.barSide === "left" || win._notifState.barSide === "right"; const isVert = win._notifState.barSide === "left" || win._notifState.barSide === "right";
const radius = win._notifConnectorRadius(); const radius = win._notifConnectorRadius(placement);
return isVert ? radius : (spacing + radius); return isVert ? radius : (spacing + radius);
} }
@@ -520,7 +824,7 @@ PanelWindow {
const notifSide = win._notifState.barSide; const notifSide = win._notifState.barSide;
const isVert = notifSide === "left" || notifSide === "right"; const isVert = notifSide === "left" || notifSide === "right";
const seamX = !isVert ? (placement === "left" ? baseX : baseX + bodyWidth) : (notifSide === "left" ? baseX : baseX + bodyWidth); const seamX = !isVert ? (placement === "left" ? baseX : baseX + bodyWidth) : (notifSide === "left" ? baseX : baseX + bodyWidth);
const w = _notifConnectorWidth(spacing); const w = _notifConnectorWidth(spacing, placement);
if (!isVert) if (!isVert)
return placement === "left" ? seamX - w : seamX; return placement === "left" ? seamX - w : seamX;
return notifSide === "left" ? seamX : seamX - w; return notifSide === "left" ? seamX : seamX - w;
@@ -529,7 +833,7 @@ PanelWindow {
function _notifConnectorY(baseY, bodyHeight, placement, spacing) { function _notifConnectorY(baseY, bodyHeight, placement, spacing) {
const notifSide = win._notifState.barSide; const notifSide = win._notifState.barSide;
const seamY = notifSide === "top" ? baseY : notifSide === "bottom" ? baseY + bodyHeight : (placement === "left" ? baseY : baseY + bodyHeight); const seamY = notifSide === "top" ? baseY : notifSide === "bottom" ? baseY + bodyHeight : (placement === "left" ? baseY : baseY + bodyHeight);
const h = _notifConnectorHeight(spacing); const h = _notifConnectorHeight(spacing, placement);
if (notifSide === "top") if (notifSide === "top")
return seamY; return seamY;
if (notifSide === "bottom") if (notifSide === "bottom")
@@ -537,15 +841,19 @@ PanelWindow {
return placement === "left" ? seamY - h : seamY; return placement === "left" ? seamY - h : seamY;
} }
function _popoutConnectorWidth(spacing) { function _popoutConnectorRadius(placement) {
return placement === "right" ? win._effectivePopoutEndCcr : win._effectivePopoutStartCcr;
}
function _popoutConnectorWidth(spacing, placement) {
const isVert = ConnectedModeState.popoutBarSide === "left" || ConnectedModeState.popoutBarSide === "right"; const isVert = ConnectedModeState.popoutBarSide === "left" || ConnectedModeState.popoutBarSide === "right";
const radius = win._effectivePopoutCcr; const radius = win._popoutConnectorRadius(placement);
return isVert ? (spacing + radius) : radius; return isVert ? (spacing + radius) : radius;
} }
function _popoutConnectorHeight(spacing) { function _popoutConnectorHeight(spacing, placement) {
const isVert = ConnectedModeState.popoutBarSide === "left" || ConnectedModeState.popoutBarSide === "right"; const isVert = ConnectedModeState.popoutBarSide === "left" || ConnectedModeState.popoutBarSide === "right";
const radius = win._effectivePopoutCcr; const radius = win._popoutConnectorRadius(placement);
return isVert ? radius : (spacing + radius); return isVert ? radius : (spacing + radius);
} }
@@ -553,7 +861,7 @@ PanelWindow {
const popoutSide = ConnectedModeState.popoutBarSide; const popoutSide = ConnectedModeState.popoutBarSide;
const isVert = popoutSide === "left" || popoutSide === "right"; const isVert = popoutSide === "left" || popoutSide === "right";
const seamX = !isVert ? (placement === "left" ? baseX : baseX + bodyWidth) : (popoutSide === "left" ? baseX : baseX + bodyWidth); const seamX = !isVert ? (placement === "left" ? baseX : baseX + bodyWidth) : (popoutSide === "left" ? baseX : baseX + bodyWidth);
const w = _popoutConnectorWidth(spacing); const w = _popoutConnectorWidth(spacing, placement);
if (!isVert) if (!isVert)
return placement === "left" ? seamX - w : seamX; return placement === "left" ? seamX - w : seamX;
return popoutSide === "left" ? seamX : seamX - w; return popoutSide === "left" ? seamX : seamX - w;
@@ -562,7 +870,7 @@ PanelWindow {
function _popoutConnectorY(baseY, bodyHeight, placement, spacing) { function _popoutConnectorY(baseY, bodyHeight, placement, spacing) {
const popoutSide = ConnectedModeState.popoutBarSide; const popoutSide = ConnectedModeState.popoutBarSide;
const seamY = popoutSide === "top" ? baseY : popoutSide === "bottom" ? baseY + bodyHeight : (placement === "left" ? baseY : baseY + bodyHeight); const seamY = popoutSide === "top" ? baseY : popoutSide === "bottom" ? baseY + bodyHeight : (placement === "left" ? baseY : baseY + bodyHeight);
const h = _popoutConnectorHeight(spacing); const h = _popoutConnectorHeight(spacing, placement);
if (popoutSide === "top") if (popoutSide === "top")
return seamY; return seamY;
if (popoutSide === "bottom") if (popoutSide === "bottom")
@@ -598,27 +906,27 @@ PanelWindow {
function _popoutBlurCapThickness() { function _popoutBlurCapThickness() {
const extent = win._popoutArcExtent(); const extent = win._popoutArcExtent();
return Math.max(0, Math.min(win._effectivePopoutCcr, extent - win._surfaceRadius)); return Math.max(0, Math.min(win._effectivePopoutMaxCcr, extent - win._surfaceRadius));
} }
function _popoutChromeX() { function _popoutChromeX() {
const barSide = ConnectedModeState.popoutBarSide; const barSide = ConnectedModeState.popoutBarSide;
return ConnectedModeState.popoutBodyX - ((barSide === "top" || barSide === "bottom") ? win._effectivePopoutCcr : 0); return ConnectedModeState.popoutBodyX - ((barSide === "top" || barSide === "bottom") ? win._effectivePopoutStartCcr : 0);
} }
function _popoutChromeY() { function _popoutChromeY() {
const barSide = ConnectedModeState.popoutBarSide; const barSide = ConnectedModeState.popoutBarSide;
return ConnectedModeState.popoutBodyY - ((barSide === "left" || barSide === "right") ? win._effectivePopoutCcr : 0); return ConnectedModeState.popoutBodyY - ((barSide === "left" || barSide === "right") ? win._effectivePopoutStartCcr : 0);
} }
function _popoutChromeWidth() { function _popoutChromeWidth() {
const barSide = ConnectedModeState.popoutBarSide; const barSide = ConnectedModeState.popoutBarSide;
return ConnectedModeState.popoutBodyW + ((barSide === "top" || barSide === "bottom") ? win._effectivePopoutCcr * 2 : 0); return ConnectedModeState.popoutBodyW + ((barSide === "top" || barSide === "bottom") ? win._effectivePopoutStartCcr + win._effectivePopoutEndCcr : 0);
} }
function _popoutChromeHeight() { function _popoutChromeHeight() {
const barSide = ConnectedModeState.popoutBarSide; const barSide = ConnectedModeState.popoutBarSide;
return ConnectedModeState.popoutBodyH + ((barSide === "left" || barSide === "right") ? win._effectivePopoutCcr * 2 : 0); return ConnectedModeState.popoutBodyH + ((barSide === "left" || barSide === "right") ? win._effectivePopoutStartCcr + win._effectivePopoutEndCcr : 0);
} }
function _popoutClipX() { function _popoutClipX() {
@@ -637,6 +945,34 @@ PanelWindow {
return _popoutBodyBlurAnchor.height + win._popoutFillOverlapY() * 2; return _popoutBodyBlurAnchor.height + win._popoutFillOverlapY() * 2;
} }
function _popoutShapeBodyOffsetX() {
const side = ConnectedModeState.popoutBarSide;
if (side === "top" || side === "bottom")
return win._effectivePopoutStartCcr;
return side === "right" ? win._effectivePopoutFarExtent : 0;
}
function _popoutShapeBodyOffsetY() {
const side = ConnectedModeState.popoutBarSide;
if (side === "top" || side === "bottom")
return side === "bottom" ? win._effectivePopoutFarExtent : 0;
return win._effectivePopoutStartCcr;
}
function _popoutShapeWidth() {
const side = ConnectedModeState.popoutBarSide;
if (side === "top" || side === "bottom")
return win._popoutClipWidth() + win._effectivePopoutStartCcr + win._effectivePopoutEndCcr;
return win._popoutClipWidth() + win._effectivePopoutFarExtent;
}
function _popoutShapeHeight() {
const side = ConnectedModeState.popoutBarSide;
if (side === "top" || side === "bottom")
return win._popoutClipHeight() + win._effectivePopoutFarExtent;
return win._popoutClipHeight() + win._effectivePopoutStartCcr + win._effectivePopoutEndCcr;
}
function _popoutBodyXInClip() { function _popoutBodyXInClip() {
return (ConnectedModeState.popoutBarSide === "left" ? _popoutBodyBlurAnchor._dxClamp : 0) - win._popoutFillOverlapX(); return (ConnectedModeState.popoutBarSide === "left" ? _popoutBodyBlurAnchor._dxClamp : 0) - win._popoutFillOverlapX();
} }
@@ -681,6 +1017,54 @@ PanelWindow {
return ((win._dockState.barSide === "left" || win._dockState.barSide === "right") ? win._dockConnectorRadius() : 0) - win._dockFillOverlapY(); return ((win._dockState.barSide === "left" || win._dockState.barSide === "right") ? win._dockConnectorRadius() : 0) - win._dockFillOverlapY();
} }
function _farConnectorBarSide(sourceSide, placement) {
if (sourceSide === "top" || sourceSide === "bottom")
return placement === "left" ? "left" : "right";
return placement === "left" ? "top" : "bottom";
}
function _farConnectorPlacement(sourceSide, placement) {
if (sourceSide === "top")
return "right";
if (sourceSide === "bottom")
return "left";
if (sourceSide === "left")
return "right";
return "left";
}
function _farConnectorX(baseX, baseY, bodyWidth, bodyHeight, sourceSide, placement, radius) {
if (sourceSide === "top" || sourceSide === "bottom")
return placement === "left" ? baseX : baseX + bodyWidth - radius;
if (sourceSide === "left")
return baseX + bodyWidth;
return baseX - radius;
}
function _farConnectorY(baseX, baseY, bodyWidth, bodyHeight, sourceSide, placement, radius) {
if (sourceSide === "top")
return baseY + bodyHeight;
if (sourceSide === "bottom")
return baseY - radius;
return placement === "left" ? baseY : baseY + bodyHeight - radius;
}
function _farBodyCapX(baseX, bodyWidth, sourceSide, placement, radius) {
if (sourceSide === "top" || sourceSide === "bottom")
return placement === "left" ? baseX : baseX + bodyWidth - radius;
if (sourceSide === "left")
return baseX + bodyWidth - radius;
return baseX;
}
function _farBodyCapY(baseY, bodyHeight, sourceSide, placement, radius) {
if (sourceSide === "top")
return baseY + bodyHeight - radius;
if (sourceSide === "bottom")
return baseY;
return placement === "left" ? baseY : baseY + bodyHeight - radius;
}
function _connectorArcCorner(barSide, placement) { function _connectorArcCorner(barSide, placement) {
if (barSide === "top") if (barSide === "top")
return placement === "left" ? "bottomLeft" : "bottomRight"; return placement === "left" ? "bottomLeft" : "bottomRight";
@@ -756,6 +1140,9 @@ PanelWindow {
function onConnectedFrameModeActiveChanged() { function onConnectedFrameModeActiveChanged() {
_blurRebuildTimer.restart(); _blurRebuildTimer.restart();
} }
function onFrameCloseGapsChanged() {
_blurRebuildTimer.restart();
}
} }
Connections { Connections {
@@ -842,12 +1229,10 @@ PanelWindow {
Item { Item {
id: _popoutClip id: _popoutClip
readonly property bool _barHoriz: ConnectedModeState.popoutBarSide === "top" || ConnectedModeState.popoutBarSide === "bottom" x: win._popoutClipX() - win._popoutShapeBodyOffsetX()
// Expand clip by ccr on bar axis to include arc columns y: win._popoutClipY() - win._popoutShapeBodyOffsetY()
x: win._popoutClipX() - (_barHoriz ? win._effectivePopoutCcr : 0) width: win._popoutShapeWidth()
y: win._popoutClipY() - (_barHoriz ? 0 : win._effectivePopoutCcr) height: win._popoutShapeHeight()
width: win._popoutClipWidth() + (_barHoriz ? win._effectivePopoutCcr * 2 : 0)
height: win._popoutClipHeight() + (_barHoriz ? 0 : win._effectivePopoutCcr * 2)
clip: true clip: true
ConnectedShape { ConnectedShape {
@@ -857,6 +1242,10 @@ PanelWindow {
bodyWidth: win._popoutClipWidth() bodyWidth: win._popoutClipWidth()
bodyHeight: win._popoutClipHeight() bodyHeight: win._popoutClipHeight()
connectorRadius: win._effectivePopoutCcr connectorRadius: win._effectivePopoutCcr
startConnectorRadius: win._effectivePopoutStartCcr
endConnectorRadius: win._effectivePopoutEndCcr
farStartConnectorRadius: win._effectivePopoutFarStartCcr
farEndConnectorRadius: win._effectivePopoutFarEndCcr
surfaceRadius: win._surfaceRadius surfaceRadius: win._surfaceRadius
fillColor: win._opaqueSurfaceColor fillColor: win._opaqueSurfaceColor
x: 0 x: 0
@@ -920,27 +1309,34 @@ PanelWindow {
Item { Item {
id: _notifChrome id: _notifChrome
visible: _notifBodyBlurAnchor._active visible: _notifBodySceneBlurAnchor._active
readonly property string _notifSide: win._notifState.barSide readonly property string _notifSide: win._notifState.barSide
readonly property bool _isHoriz: _notifSide === "top" || _notifSide === "bottom" readonly property bool _isHoriz: _notifSide === "top" || _notifSide === "bottom"
readonly property real _notifCcr: win._effectiveNotifCcr readonly property real _startCcr: win._effectiveNotifStartCcr
readonly property real _sideUnderlap: _isHoriz ? 0 : win._seamOverlap readonly property real _endCcr: win._effectiveNotifEndCcr
readonly property real _bodyW: Theme.snap(_notifBodyBlurAnchor.width + _sideUnderlap, win._dpr) readonly property real _farExtent: win._effectiveNotifFarExtent
readonly property real _bodyH: Theme.snap(_notifBodyBlurAnchor.height, win._dpr) readonly property real _bodyOffsetX: _isHoriz ? _startCcr : (_notifSide === "right" ? _farExtent : 0)
readonly property real _bodyOffsetY: _isHoriz ? (_notifSide === "bottom" ? _farExtent : 0) : _startCcr
readonly property real _bodyW: Theme.snap(_notifBodySceneBlurAnchor.width, win._dpr)
readonly property real _bodyH: Theme.snap(_notifBodySceneBlurAnchor.height, win._dpr)
z: _isHoriz ? 0 : -1 z: _isHoriz ? 0 : -1
x: Theme.snap(_notifBodyBlurAnchor.x - (_isHoriz ? _notifCcr : (_notifSide === "left" ? _sideUnderlap : 0)), win._dpr) x: Theme.snap(_notifBodySceneBlurAnchor.x - _bodyOffsetX, win._dpr)
y: Theme.snap(_notifBodyBlurAnchor.y - (_isHoriz ? 0 : _notifCcr), win._dpr) y: Theme.snap(_notifBodySceneBlurAnchor.y - _bodyOffsetY, win._dpr)
width: _isHoriz ? Theme.snap(_bodyW + _notifCcr * 2, win._dpr) : _bodyW width: _isHoriz ? Theme.snap(_bodyW + _startCcr + _endCcr, win._dpr) : Theme.snap(_bodyW + _farExtent, win._dpr)
height: Theme.snap(_bodyH + (_isHoriz ? 0 : _notifCcr * 2), win._dpr) height: _isHoriz ? Theme.snap(_bodyH + _farExtent, win._dpr) : Theme.snap(_bodyH + _startCcr + _endCcr, win._dpr)
ConnectedShape { ConnectedShape {
visible: _notifBodyBlurAnchor._active && _notifBodyBlurAnchor.width > 0 && _notifBodyBlurAnchor.height > 0 visible: _notifBodySceneBlurAnchor._active && _notifBodySceneBlurAnchor.width > 0 && _notifBodySceneBlurAnchor.height > 0
barSide: _notifChrome._notifSide barSide: _notifChrome._notifSide
bodyWidth: _notifChrome._bodyW bodyWidth: _notifChrome._bodyW
bodyHeight: _notifChrome._bodyH bodyHeight: _notifChrome._bodyH
connectorRadius: _notifChrome._notifCcr connectorRadius: win._effectiveNotifCcr
startConnectorRadius: _notifChrome._startCcr
endConnectorRadius: _notifChrome._endCcr
farStartConnectorRadius: win._effectiveNotifFarStartCcr
farEndConnectorRadius: win._effectiveNotifFarEndCcr
surfaceRadius: win._surfaceRadius surfaceRadius: win._surfaceRadius
fillColor: win._opaqueSurfaceColor fillColor: win._opaqueSurfaceColor
x: 0 x: 0

View File

@@ -307,7 +307,9 @@ PanelWindow {
return 0; return 0;
if (connectedFrameMode) { if (connectedFrameMode) {
const cornerClear = isCenterPosition ? 0 : (Theme.px(SettingsData.frameRounding, dpr) + Theme.px(Theme.connectedCornerRadius, dpr)); const cornerClear = (isCenterPosition || SettingsData.frameCloseGaps)
? 0
: (Theme.px(SettingsData.frameRounding, dpr) + Theme.px(Theme.connectedCornerRadius, dpr));
return _frameEdgeInset("top") + cornerClear + screenY; return _frameEdgeInset("top") + cornerClear + screenY;
} }
const barInfo = getBarInfo(); const barInfo = getBarInfo();
@@ -322,7 +324,9 @@ PanelWindow {
return 0; return 0;
if (connectedFrameMode) { if (connectedFrameMode) {
const cornerClear = isCenterPosition ? 0 : (Theme.px(SettingsData.frameRounding, dpr) + Theme.px(Theme.connectedCornerRadius, dpr)); const cornerClear = (isCenterPosition || SettingsData.frameCloseGaps)
? 0
: (Theme.px(SettingsData.frameRounding, dpr) + Theme.px(Theme.connectedCornerRadius, dpr));
return _frameEdgeInset("bottom") + cornerClear + screenY; return _frameEdgeInset("bottom") + cornerClear + screenY;
} }
const barInfo = getBarInfo(); const barInfo = getBarInfo();

View File

@@ -11,6 +11,7 @@ QtObject {
readonly property bool notificationConnectedMode: SettingsData.frameEnabled readonly property bool notificationConnectedMode: SettingsData.frameEnabled
&& Theme.isConnectedEffect && Theme.isConnectedEffect
&& SettingsData.isScreenInPreferences(manager.modelData, SettingsData.frameScreenPreferences) && SettingsData.isScreenInPreferences(manager.modelData, SettingsData.frameScreenPreferences)
readonly property bool closeGapNotifications: notificationConnectedMode && SettingsData.frameCloseGaps
readonly property string notifBarSide: { readonly property string notifBarSide: {
const pos = SettingsData.notificationPopupPosition; const pos = SettingsData.notificationPopupPosition;
if (pos === -1) return "top"; if (pos === -1) return "top";
@@ -339,6 +340,23 @@ QtObject {
return pos === -1 || pos === SettingsData.Position.Top || pos === SettingsData.Position.Left; return pos === -1 || pos === SettingsData.Position.Top || pos === SettingsData.Position.Left;
} }
function _frameEdgeInset(side) {
if (!manager.modelData)
return 0;
const edges = SettingsData.getActiveBarEdgesForScreen(manager.modelData);
const raw = edges.includes(side) ? SettingsData.frameBarSize : SettingsData.frameThickness;
const dpr = CompositorService.getScreenScale(manager.modelData);
return Math.max(0, Math.round(Theme.px(raw, dpr)));
}
function _closeGapChromeAnchorEdge(anchorsTop) {
if (!closeGapNotifications || !manager.modelData)
return null;
if (anchorsTop)
return _frameEdgeInset("top") + topMargin;
return manager.modelData.height - _frameEdgeInset("bottom") - topMargin;
}
function _trailingChromeWindow(candidates) { function _trailingChromeWindow(candidates) {
const anchorsTop = _stackAnchorsTop(); const anchorsTop = _stackAnchorsTop();
let trailing = null; let trailing = null;
@@ -429,6 +447,14 @@ QtObject {
if (!stackEdge.anchorsTop && stackEdge.edge > maxYEnd) if (!stackEdge.anchorsTop && stackEdge.edge > maxYEnd)
maxYEnd = stackEdge.edge; maxYEnd = stackEdge.edge;
} }
const anchorsTop = stackEdge !== null ? stackEdge.anchorsTop : _stackAnchorsTop();
const closeGapAnchorEdge = _closeGapChromeAnchorEdge(anchorsTop);
if (closeGapAnchorEdge !== null) {
if (anchorsTop)
minY = closeGapAnchorEdge;
else
maxYEnd = closeGapAnchorEdge;
}
if (minX === Infinity || minY === Infinity || maxXEnd <= minX || maxYEnd <= minY) { if (minX === Infinity || minY === Infinity || maxXEnd <= minX || maxYEnd <= minY) {
ConnectedModeState.clearNotificationState(screenName); ConnectedModeState.clearNotificationState(screenName);
return; return;
@@ -439,10 +465,24 @@ QtObject {
bodyX: minX, bodyX: minX,
bodyY: minY, bodyY: minY,
bodyW: maxXEnd - minX, bodyW: maxXEnd - minX,
bodyH: maxYEnd - minY bodyH: maxYEnd - minY,
omitStartConnector: _notificationOmitStartConnector(),
omitEndConnector: _notificationOmitEndConnector()
}); });
} }
function _notificationOmitStartConnector() {
return closeGapNotifications
&& (SettingsData.notificationPopupPosition === SettingsData.Position.Top
|| SettingsData.notificationPopupPosition === SettingsData.Position.Left);
}
function _notificationOmitEndConnector() {
return closeGapNotifications
&& (SettingsData.notificationPopupPosition === SettingsData.Position.Right
|| SettingsData.notificationPopupPosition === SettingsData.Position.Bottom);
}
function _onPopupChromeGeometryChanged(p) { function _onPopupChromeGeometryChanged(p) {
if (!p || popupWindows.indexOf(p) === -1) if (!p || popupWindows.indexOf(p) === -1)
return; return;
@@ -504,6 +544,7 @@ QtObject {
} }
onNotificationConnectedModeChanged: _scheduleNotificationChromeSync() onNotificationConnectedModeChanged: _scheduleNotificationChromeSync()
onCloseGapNotificationsChanged: _scheduleNotificationChromeSync()
onNotifBarSideChanged: _scheduleNotificationChromeSync() onNotifBarSideChanged: _scheduleNotificationChromeSync()
onModelDataChanged: _scheduleNotificationChromeSync() onModelDataChanged: _scheduleNotificationChromeSync()
onTopMarginChanged: _repositionAll() onTopMarginChanged: _repositionAll()

View File

@@ -262,7 +262,7 @@ Item {
SettingsCard { SettingsCard {
width: parent.width width: parent.width
iconName: "toolbar" iconName: "toolbar"
title: I18n.tr("Bar Integration") title: I18n.tr("Integrations")
settingKey: "frameBarIntegration" settingKey: "frameBarIntegration"
collapsible: true collapsible: true
expanded: true expanded: true
@@ -283,7 +283,7 @@ Item {
settingKey: "directionalAnimationMode" settingKey: "directionalAnimationMode"
tags: ["frame", "connected", "popout", "corner", "animation"] tags: ["frame", "connected", "popout", "corner", "animation"]
text: I18n.tr("Connected Mode") text: I18n.tr("Connected Mode")
description: I18n.tr("Popouts emerge flush from the bar edge as one continuous piece (based on Slide)") description: I18n.tr("Popouts emerge flush from the bar edge as one continuous piece")
checked: SettingsData.connectedFrameModeActive checked: SettingsData.connectedFrameModeActive
onToggled: checked => { onToggled: checked => {
if (checked) { if (checked) {
@@ -302,6 +302,18 @@ Item {
function onMotionEffectChanged() {} function onMotionEffectChanged() {}
} }
} }
SettingsToggleRow {
visible: SettingsData.frameEnabled
settingKey: "frameCloseGaps"
tags: ["frame", "connected", "gap", "edge", "flush", "popout", "notification"]
text: I18n.tr("Close the Gaps")
description: I18n.tr("Connected popouts and notification corners sit flush against the frame edge")
checked: SettingsData.frameCloseGaps
enabled: SettingsData.connectedFrameModeActive
opacity: enabled ? 1.0 : 0.5
onToggled: checked => SettingsData.set("frameCloseGaps", checked)
}
} }
// ── Display Assignment ──────────────────────────────────────────── // ── Display Assignment ────────────────────────────────────────────

View File

@@ -2,8 +2,8 @@ import QtQuick
import QtQuick.Shapes import QtQuick.Shapes
import qs.Common import qs.Common
// Unified connected silhouette: body + concave arcs as one ShapePath. // Unified connected silhouette: body + near/far concave arcs as one ShapePath.
// PathArc pattern — 4 arcs + 4 lines, no sibling alignment. // Keeping the connected chrome in one path avoids sibling alignment seams.
Item { Item {
id: root id: root
@@ -14,6 +14,10 @@ Item {
property real bodyHeight: 0 property real bodyHeight: 0
property real connectorRadius: 12 property real connectorRadius: 12
property real startConnectorRadius: connectorRadius
property real endConnectorRadius: connectorRadius
property real farStartConnectorRadius: 0
property real farEndConnectorRadius: 0
property real surfaceRadius: 12 property real surfaceRadius: 12
@@ -21,20 +25,36 @@ Item {
// ── Derived layout ── // ── Derived layout ──
readonly property bool _horiz: barSide === "top" || barSide === "bottom" readonly property bool _horiz: barSide === "top" || barSide === "bottom"
readonly property real _cr: Math.max(0, connectorRadius) readonly property real _sc: Math.max(0, startConnectorRadius)
readonly property real _ec: Math.max(0, endConnectorRadius)
readonly property real _fsc: Math.max(0, farStartConnectorRadius)
readonly property real _fec: Math.max(0, farEndConnectorRadius)
readonly property real _firstCr: barSide === "left" ? _sc : _ec
readonly property real _secondCr: barSide === "left" ? _ec : _sc
readonly property real _firstFarCr: barSide === "left" ? _fsc : _fec
readonly property real _secondFarCr: barSide === "left" ? _fec : _fsc
readonly property real _farExtent: Math.max(_fsc, _fec)
readonly property real _sr: Math.max(0, Math.min(surfaceRadius, (_horiz ? bodyWidth : bodyHeight) / 2, (_horiz ? bodyHeight : bodyWidth) / 2)) readonly property real _sr: Math.max(0, Math.min(surfaceRadius, (_horiz ? bodyWidth : bodyHeight) / 2, (_horiz ? bodyHeight : bodyWidth) / 2))
readonly property real _firstSr: _firstFarCr > 0 ? 0 : _sr
readonly property real _secondSr: _secondFarCr > 0 ? 0 : _sr
readonly property real _firstFarInset: _firstFarCr > 0 ? _firstFarCr : _firstSr
readonly property real _secondFarInset: _secondFarCr > 0 ? _secondFarCr : _secondSr
// Root-level aliases — PathArc/PathLine elements can't use `parent`. // Root-level aliases — PathArc/PathLine elements can't use `parent`.
readonly property real _bw: bodyWidth readonly property real _bw: bodyWidth
readonly property real _bh: bodyHeight readonly property real _bh: bodyHeight
readonly property real _totalW: _horiz ? _bw + _cr * 2 : _bw readonly property real _bodyLeft: _horiz ? _sc : (barSide === "right" ? _farExtent : 0)
readonly property real _totalH: _horiz ? _bh : _bh + _cr * 2 readonly property real _bodyRight: _bodyLeft + _bw
readonly property real _bodyTop: _horiz ? (barSide === "bottom" ? _farExtent : 0) : _sc
readonly property real _bodyBottom: _bodyTop + _bh
readonly property real _totalW: _horiz ? _bw + _sc + _ec : _bw + _farExtent
readonly property real _totalH: _horiz ? _bh + _farExtent : _bh + _sc + _ec
width: _totalW width: _totalW
height: _totalH height: _totalH
readonly property real bodyX: _horiz ? _cr : 0 readonly property real bodyX: root._bodyLeft
readonly property real bodyY: _horiz ? 0 : _cr readonly property real bodyY: root._bodyTop
Shape { Shape {
anchors.fill: parent anchors.fill: parent
@@ -94,27 +114,27 @@ Item {
relativeX: { relativeX: {
switch (root.barSide) { switch (root.barSide) {
case "left": case "left":
return root._cr; return root._firstCr;
case "right": case "right":
return -root._cr; return -root._firstCr;
default: default:
return -root._cr; return -root._firstCr;
} }
} }
relativeY: { relativeY: {
switch (root.barSide) { switch (root.barSide) {
case "bottom": case "bottom":
return -root._cr; return -root._firstCr;
case "left": case "left":
return root._cr; return root._firstCr;
case "right": case "right":
return -root._cr; return -root._firstCr;
default: default:
return root._cr; return root._firstCr;
} }
} }
radiusX: root._cr radiusX: root._firstCr
radiusY: root._cr radiusY: root._firstCr
direction: root.barSide === "bottom" ? PathArc.Clockwise : PathArc.Counterclockwise direction: root.barSide === "bottom" ? PathArc.Clockwise : PathArc.Counterclockwise
} }
@@ -123,23 +143,23 @@ Item {
x: { x: {
switch (root.barSide) { switch (root.barSide) {
case "left": case "left":
return root._bw - root._sr; return root._bodyRight - root._firstSr;
case "right": case "right":
return root._sr; return root._bodyLeft + root._firstSr;
default: default:
return root._totalW - root._cr; return root._bodyRight;
} }
} }
y: { y: {
switch (root.barSide) { switch (root.barSide) {
case "bottom": case "bottom":
return root._sr; return root._bodyTop + root._firstSr;
case "left": case "left":
return root._cr; return root._bodyTop;
case "right": case "right":
return root._cr + root._bh; return root._bodyBottom;
default: default:
return root._totalH - root._sr; return root._bodyBottom - root._firstSr;
} }
} }
} }
@@ -149,52 +169,160 @@ Item {
relativeX: { relativeX: {
switch (root.barSide) { switch (root.barSide) {
case "left": case "left":
return root._sr; return root._firstSr;
case "right": case "right":
return -root._sr; return -root._firstSr;
default: default:
return -root._sr; return -root._firstSr;
} }
} }
relativeY: { relativeY: {
switch (root.barSide) { switch (root.barSide) {
case "bottom": case "bottom":
return -root._sr; return -root._firstSr;
case "left": case "left":
return root._sr; return root._firstSr;
case "right": case "right":
return -root._sr; return -root._firstSr;
default: default:
return root._sr; return root._firstSr;
} }
} }
radiusX: root._sr radiusX: root._firstSr
radiusY: root._sr radiusY: root._firstSr
direction: root.barSide === "bottom" ? PathArc.Counterclockwise : PathArc.Clockwise direction: root.barSide === "bottom" ? PathArc.Counterclockwise : PathArc.Clockwise
} }
// Opposite-side connector 1
PathLine {
x: {
switch (root.barSide) {
case "left":
return root._firstFarCr > 0 ? root._bodyRight + root._firstFarCr : root._bodyRight;
case "right":
return root._firstFarCr > 0 ? root._bodyLeft - root._firstFarCr : root._bodyLeft;
default:
return root._firstFarCr > 0 ? root._bodyRight : root._bodyRight - root._firstSr;
}
}
y: {
switch (root.barSide) {
case "bottom":
return root._firstFarCr > 0 ? root._bodyTop - root._firstFarCr : root._bodyTop;
case "left":
return root._firstFarCr > 0 ? root._bodyTop : root._bodyTop + root._firstSr;
case "right":
return root._firstFarCr > 0 ? root._bodyBottom : root._bodyBottom - root._firstSr;
default:
return root._firstFarCr > 0 ? root._bodyBottom + root._firstFarCr : root._bodyBottom;
}
}
}
PathArc {
relativeX: {
switch (root.barSide) {
case "left":
return -root._firstFarCr;
case "right":
return root._firstFarCr;
default:
return -root._firstFarCr;
}
}
relativeY: {
switch (root.barSide) {
case "bottom":
return root._firstFarCr;
case "left":
return root._firstFarCr;
case "right":
return -root._firstFarCr;
default:
return -root._firstFarCr;
}
}
radiusX: root._firstFarCr
radiusY: root._firstFarCr
direction: root.barSide === "bottom" ? PathArc.Clockwise : PathArc.Counterclockwise
}
// Far edge // Far edge
PathLine { PathLine {
x: { x: {
switch (root.barSide) { switch (root.barSide) {
case "left": case "left":
return root._bw; return root._bodyRight;
case "right": case "right":
return 0; return root._bodyLeft;
default: default:
return root._cr + root._sr; return root._bodyLeft + root._secondFarInset;
} }
} }
y: { y: {
switch (root.barSide) { switch (root.barSide) {
case "bottom": case "bottom":
return 0; return root._bodyTop;
case "left": case "left":
return root._cr + root._bh - root._sr; return root._bodyBottom - root._secondFarInset;
case "right": case "right":
return root._cr + root._sr; return root._bodyTop + root._secondFarInset;
default: default:
return root._totalH; return root._bodyBottom;
}
}
}
// Opposite-side connector 2
PathArc {
relativeX: {
switch (root.barSide) {
case "left":
return root._secondFarCr;
case "right":
return -root._secondFarCr;
default:
return -root._secondFarCr;
}
}
relativeY: {
switch (root.barSide) {
case "bottom":
return -root._secondFarCr;
case "left":
return root._secondFarCr;
case "right":
return -root._secondFarCr;
default:
return root._secondFarCr;
}
}
radiusX: root._secondFarCr
radiusY: root._secondFarCr
direction: root.barSide === "bottom" ? PathArc.Clockwise : PathArc.Counterclockwise
}
PathLine {
x: {
switch (root.barSide) {
case "left":
return root._secondFarCr > 0 ? root._bodyRight : root._bodyRight;
case "right":
return root._secondFarCr > 0 ? root._bodyLeft : root._bodyLeft;
default:
return root._secondFarCr > 0 ? root._bodyLeft : root._bodyLeft + root._secondSr;
}
}
y: {
switch (root.barSide) {
case "bottom":
return root._secondFarCr > 0 ? root._bodyTop : root._bodyTop;
case "left":
return root._secondFarCr > 0 ? root._bodyBottom : root._bodyBottom - root._secondSr;
case "right":
return root._secondFarCr > 0 ? root._bodyTop : root._bodyTop + root._secondSr;
default:
return root._secondFarCr > 0 ? root._bodyBottom : root._bodyBottom;
} }
} }
} }
@@ -204,27 +332,27 @@ Item {
relativeX: { relativeX: {
switch (root.barSide) { switch (root.barSide) {
case "left": case "left":
return -root._sr; return -root._secondSr;
case "right": case "right":
return root._sr; return root._secondSr;
default: default:
return -root._sr; return -root._secondSr;
} }
} }
relativeY: { relativeY: {
switch (root.barSide) { switch (root.barSide) {
case "bottom": case "bottom":
return root._sr; return root._secondSr;
case "left": case "left":
return root._sr; return root._secondSr;
case "right": case "right":
return -root._sr; return -root._secondSr;
default: default:
return -root._sr; return -root._secondSr;
} }
} }
radiusX: root._sr radiusX: root._secondSr
radiusY: root._sr radiusY: root._secondSr
direction: root.barSide === "bottom" ? PathArc.Counterclockwise : PathArc.Clockwise direction: root.barSide === "bottom" ? PathArc.Counterclockwise : PathArc.Clockwise
} }
@@ -233,23 +361,23 @@ Item {
x: { x: {
switch (root.barSide) { switch (root.barSide) {
case "left": case "left":
return root._cr; return root._bodyLeft + root._ec;
case "right": case "right":
return root._bw - root._cr; return root._bodyRight - root._sc;
default: default:
return root._cr; return root._bodyLeft;
} }
} }
y: { y: {
switch (root.barSide) { switch (root.barSide) {
case "bottom": case "bottom":
return root._totalH - root._cr; return root._bodyBottom - root._sc;
case "left": case "left":
return root._cr + root._bh; return root._bodyBottom;
case "right": case "right":
return root._cr; return root._bodyTop;
default: default:
return root._cr; return root._bodyTop + root._sc;
} }
} }
} }
@@ -259,27 +387,27 @@ Item {
relativeX: { relativeX: {
switch (root.barSide) { switch (root.barSide) {
case "left": case "left":
return -root._cr; return -root._secondCr;
case "right": case "right":
return root._cr; return root._secondCr;
default: default:
return -root._cr; return -root._secondCr;
} }
} }
relativeY: { relativeY: {
switch (root.barSide) { switch (root.barSide) {
case "bottom": case "bottom":
return root._cr; return root._secondCr;
case "left": case "left":
return root._cr; return root._secondCr;
case "right": case "right":
return -root._cr; return -root._secondCr;
default: default:
return -root._cr; return -root._secondCr;
} }
} }
radiusX: root._cr radiusX: root._secondCr
radiusY: root._cr radiusY: root._secondCr
direction: root.barSide === "bottom" ? PathArc.Clockwise : PathArc.Counterclockwise direction: root.barSide === "bottom" ? PathArc.Clockwise : PathArc.Counterclockwise
} }
} }

View File

@@ -198,7 +198,9 @@ Item {
"bodyH": root.alignedHeight, "bodyH": root.alignedHeight,
"animX": _connectedChromeAnimX(), "animX": _connectedChromeAnimX(),
"animY": _connectedChromeAnimY(), "animY": _connectedChromeAnimY(),
"screen": root.screen ? root.screen.name : "" "screen": root.screen ? root.screen.name : "",
"omitStartConnector": root._closeGapOmitStartConnector(),
"omitEndConnector": root._closeGapOmitEndConnector()
}; };
} }
@@ -299,6 +301,9 @@ Item {
root._releaseConnectedChromeState(); root._releaseConnectedChromeState();
} }
} }
function onFrameCloseGapsChanged() {
root._syncPopoutChromeState();
}
} }
readonly property bool useBackgroundWindow: !CompositorService.isHyprland || CompositorService.useHyprlandFocusGrab readonly property bool useBackgroundWindow: !CompositorService.isHyprland || CompositorService.useHyprlandFocusGrab
@@ -421,6 +426,7 @@ Item {
readonly property real screenWidth: screen ? screen.width : 0 readonly property real screenWidth: screen ? screen.width : 0
readonly property real screenHeight: screen ? screen.height : 0 readonly property real screenHeight: screen ? screen.height : 0
readonly property real dpr: screen ? screen.devicePixelRatio : 1 readonly property real dpr: screen ? screen.devicePixelRatio : 1
readonly property bool closeFrameGapsActive: SettingsData.frameCloseGaps && frameOwnsConnectedChrome
readonly property real frameInset: { readonly property real frameInset: {
if (!SettingsData.frameEnabled) if (!SettingsData.frameEnabled)
return 0; return 0;
@@ -435,6 +441,83 @@ Item {
return Math.max(ft + gap, fr); return Math.max(ft + gap, fr);
} }
function _popupGapValue() {
const useAutoGaps = storedBarConfig?.popupGapsAuto !== undefined ? storedBarConfig.popupGapsAuto : true;
const manualGapValue = storedBarConfig?.popupGapsManual !== undefined ? storedBarConfig.popupGapsManual : 4;
const rawPopupGap = useAutoGaps ? Math.max(4, storedBarSpacing) : manualGapValue;
return Theme.isConnectedEffect ? 0 : rawPopupGap;
}
function _frameEdgeInset(side) {
if (!SettingsData.frameEnabled || !root.screen)
return 0;
const edges = SettingsData.getActiveBarEdgesForScreen(root.screen);
const raw = edges.includes(side) ? SettingsData.frameBarSize : SettingsData.frameThickness;
return Math.max(0, raw);
}
function _edgeGapFor(side, popupGap) {
if (root.closeFrameGapsActive)
return Math.max(popupGap, _frameEdgeInset(side));
return Math.max(popupGap, frameInset);
}
function _sideAdjacentClearance(side) {
switch (side) {
case "left":
return adjacentBarClearance(adjacentBarInfo.leftBar);
case "right":
return adjacentBarClearance(adjacentBarInfo.rightBar);
case "top":
return adjacentBarClearance(adjacentBarInfo.topBar);
case "bottom":
return adjacentBarClearance(adjacentBarInfo.bottomBar);
default:
return 0;
}
}
function _nearFrameBound(value, bound) {
return Math.abs(value - bound) <= Math.max(1, Theme.hairline(root.dpr) * 2);
}
function _closeGapClampedToFrameSide(side) {
if (!root.closeFrameGapsActive)
return false;
const popupGap = _popupGapValue();
const edgeGap = _edgeGapFor(side, popupGap);
const adjacentGap = _sideAdjacentClearance(side);
if (edgeGap < adjacentGap - Math.max(1, Theme.hairline(root.dpr) * 2))
return false;
switch (side) {
case "left":
return _nearFrameBound(root.alignedX, edgeGap);
case "right":
return _nearFrameBound(root.alignedX, screenWidth - popupWidth - edgeGap);
case "top":
return _nearFrameBound(root.alignedY, edgeGap);
case "bottom":
return _nearFrameBound(root.alignedY, screenHeight - popupHeight - edgeGap);
default:
return false;
}
}
function _closeGapOmitStartConnector() {
const side = contentContainer.connectedBarSide;
if (side === "top" || side === "bottom")
return _closeGapClampedToFrameSide("left");
return _closeGapClampedToFrameSide("top");
}
function _closeGapOmitEndConnector() {
const side = contentContainer.connectedBarSide;
if (side === "top" || side === "bottom")
return _closeGapClampedToFrameSide("right");
return _closeGapClampedToFrameSide("bottom");
}
readonly property var shadowLevel: Theme.elevationLevel3 readonly property var shadowLevel: Theme.elevationLevel3
readonly property real shadowFallbackOffset: 6 readonly property real shadowFallbackOffset: 6
readonly property real shadowRenderPadding: (Theme.elevationEnabled && SettingsData.popoutElevationEnabled) ? Theme.elevationRenderPadding(shadowLevel, effectiveShadowDirection, shadowFallbackOffset, 8, 16) : 0 readonly property real shadowRenderPadding: (Theme.elevationEnabled && SettingsData.popoutElevationEnabled) ? Theme.elevationRenderPadding(shadowLevel, effectiveShadowDirection, shadowFallbackOffset, 8, 16) : 0
@@ -510,47 +593,43 @@ Item {
} }
readonly property real alignedX: Theme.snap((() => { readonly property real alignedX: Theme.snap((() => {
const useAutoGaps = storedBarConfig?.popupGapsAuto !== undefined ? storedBarConfig.popupGapsAuto : true; const popupGap = _popupGapValue();
const manualGapValue = storedBarConfig?.popupGapsManual !== undefined ? storedBarConfig.popupGapsManual : 4; const edgeGapLeft = _edgeGapFor("left", popupGap);
const rawPopupGap = useAutoGaps ? Math.max(4, storedBarSpacing) : manualGapValue; const edgeGapRight = _edgeGapFor("right", popupGap);
const popupGap = Theme.isConnectedEffect ? 0 : rawPopupGap;
const edgeGap = Math.max(popupGap, frameInset);
const anchorX = Theme.isConnectedEffect ? connectedAnchorX : triggerX; const anchorX = Theme.isConnectedEffect ? connectedAnchorX : triggerX;
switch (effectiveBarPosition) { switch (effectiveBarPosition) {
case SettingsData.Position.Left: case SettingsData.Position.Left:
// bar on left: left side is bar-adjacent (popupGap), right side is frame-perpendicular (edgeGap) // bar on left: left side is bar-adjacent (popupGap), right side is frame-perpendicular (edgeGap)
return Math.max(popupGap, Math.min(screenWidth - popupWidth - edgeGap, anchorX)); return Math.max(popupGap, Math.min(screenWidth - popupWidth - edgeGapRight, anchorX));
case SettingsData.Position.Right: case SettingsData.Position.Right:
// bar on right: right side is bar-adjacent (popupGap), left side is frame-perpendicular (edgeGap) // bar on right: right side is bar-adjacent (popupGap), left side is frame-perpendicular (edgeGap)
return Math.max(edgeGap, Math.min(screenWidth - popupWidth - popupGap, anchorX - popupWidth)); return Math.max(edgeGapLeft, Math.min(screenWidth - popupWidth - popupGap, anchorX - popupWidth));
default: default:
const rawX = triggerX + (triggerWidth / 2) - (popupWidth / 2); const rawX = triggerX + (triggerWidth / 2) - (popupWidth / 2);
const minX = Math.max(edgeGap, adjacentBarClearance(adjacentBarInfo.leftBar)); const minX = Math.max(edgeGapLeft, adjacentBarClearance(adjacentBarInfo.leftBar));
const maxX = screenWidth - popupWidth - Math.max(edgeGap, adjacentBarClearance(adjacentBarInfo.rightBar)); const maxX = screenWidth - popupWidth - Math.max(edgeGapRight, adjacentBarClearance(adjacentBarInfo.rightBar));
return Math.max(minX, Math.min(maxX, rawX)); return Math.max(minX, Math.min(maxX, rawX));
} }
})(), dpr) })(), dpr)
readonly property real alignedY: Theme.snap((() => { readonly property real alignedY: Theme.snap((() => {
const useAutoGaps = storedBarConfig?.popupGapsAuto !== undefined ? storedBarConfig.popupGapsAuto : true; const popupGap = _popupGapValue();
const manualGapValue = storedBarConfig?.popupGapsManual !== undefined ? storedBarConfig.popupGapsManual : 4; const edgeGapTop = _edgeGapFor("top", popupGap);
const rawPopupGap = useAutoGaps ? Math.max(4, storedBarSpacing) : manualGapValue; const edgeGapBottom = _edgeGapFor("bottom", popupGap);
const popupGap = Theme.isConnectedEffect ? 0 : rawPopupGap;
const edgeGap = Math.max(popupGap, frameInset);
const anchorY = Theme.isConnectedEffect ? connectedAnchorY : triggerY; const anchorY = Theme.isConnectedEffect ? connectedAnchorY : triggerY;
switch (effectiveBarPosition) { switch (effectiveBarPosition) {
case SettingsData.Position.Bottom: case SettingsData.Position.Bottom:
// bar on bottom: bottom side is bar-adjacent (popupGap), top side is frame-perpendicular (edgeGap) // bar on bottom: bottom side is bar-adjacent (popupGap), top side is frame-perpendicular (edgeGap)
return Math.max(edgeGap, Math.min(screenHeight - popupHeight - popupGap, anchorY - popupHeight)); return Math.max(edgeGapTop, Math.min(screenHeight - popupHeight - popupGap, anchorY - popupHeight));
case SettingsData.Position.Top: case SettingsData.Position.Top:
// bar on top: top side is bar-adjacent (popupGap), bottom side is frame-perpendicular (edgeGap) // bar on top: top side is bar-adjacent (popupGap), bottom side is frame-perpendicular (edgeGap)
return Math.max(popupGap, Math.min(screenHeight - popupHeight - edgeGap, anchorY)); return Math.max(popupGap, Math.min(screenHeight - popupHeight - edgeGapBottom, anchorY));
default: default:
const rawY = triggerY - (popupHeight / 2); const rawY = triggerY - (popupHeight / 2);
const minY = Math.max(edgeGap, adjacentBarClearance(adjacentBarInfo.topBar)); const minY = Math.max(edgeGapTop, adjacentBarClearance(adjacentBarInfo.topBar));
const maxY = screenHeight - popupHeight - Math.max(edgeGap, adjacentBarClearance(adjacentBarInfo.bottomBar)); const maxY = screenHeight - popupHeight - Math.max(edgeGapBottom, adjacentBarClearance(adjacentBarInfo.bottomBar));
return Math.max(minY, Math.min(maxY, rawY)); return Math.max(minY, Math.min(maxY, rawY));
} }
})(), dpr) })(), dpr)