Merge branch 'main' into feat/configurable-exclusion-zone

This commit is contained in:
SpeakingPNG
2026-03-08 16:52:52 +01:00
committed by GitHub
130 changed files with 2797 additions and 1591 deletions
@@ -103,6 +103,10 @@ ShapePath {
readonly property real blMultY: bar ? ShapeCornerHelper.getMultY(bar.bottomLeftCornerState) : 1
readonly property real blRadius: bar ? getCornerRadius(bar.bottomLeftCornerState) : 0
// True when the bar path has valid, non-degenerate geometry to render.
// Mirrors PanelBackground.isRenderable — prevents CurveRenderer crash on zero-area paths.
readonly property bool isRenderable: bar !== null && shouldShow && (isFramed ? (screenWidth > 0 && screenHeight > 0) : (barWidth > 0 && barHeight > 0))
// Extend bar background beyond screen edges where both adjacent corners are flat,
// to prevent CurveRenderer antialiasing artifacts on screen-flush edges
readonly property real screenEdgeOvershoot: 2
@@ -124,160 +128,147 @@ ShapePath {
// ShapePath configuration
strokeWidth: -1 // No stroke, fill only
fillColor: Qt.rgba(backgroundColor.r, backgroundColor.g, backgroundColor.b, backgroundColor.a * opacityFactor)
fillColor: isRenderable ? Qt.rgba(backgroundColor.r, backgroundColor.g, backgroundColor.b, backgroundColor.a * opacityFactor) : "transparent"
fillRule: isFramed ? ShapePath.OddEvenFill : ShapePath.WindingFill
// Starting position
// In framed mode, we start at (0,0) to draw the screen rectangle first
startX: isFramed ? 0 : (barMappedPos.x + leftEdgeOvs + tlRadius * tlMultX)
startY: isFramed ? 0 : (barMappedPos.y + topEdgeOvs)
// Starting position — falls back to off-screen (-1,-1) when not renderable so that
// all subsequent path elements form a valid non-degenerate 1×1 off-screen square,
// preventing CurveRenderer triangulation crashes on zero-area or bare-moveto paths.
startX: isRenderable ? (isFramed ? 0 : (barMappedPos.x + leftEdgeOvs + tlRadius * tlMultX)) : -1
startY: isRenderable ? (isFramed ? 0 : (barMappedPos.y + topEdgeOvs)) : -1
// ========== PATH DEFINITION ==========
// 1. Main Bar / Outer Screen Rectangle
// When !isRenderable all elements use fallback coordinates forming a valid 1×1
// off-screen square ((-1,-1)→(0,-1)→(0,0)→(-1,0)→(-1,-1)) so CurveRenderer
// never receives a zero-area or bare-moveto path.
PathLine {
x: {
if (!root.shouldShow)
return 0;
if (root.isFramed)
return root.screenWidth;
return root.barMappedPos.x + root.barWidth + root.rightEdgeOvs - root.trRadius * root.trMultX;
}
y: root.isFramed ? 0 : (root.barMappedPos.y + root.topEdgeOvs)
x: root.isRenderable ? (root.isFramed ? root.screenWidth : (root.barMappedPos.x + root.barWidth + root.rightEdgeOvs - root.trRadius * root.trMultX)) : 0
y: root.isRenderable ? (root.isFramed ? 0 : (root.barMappedPos.y + root.topEdgeOvs)) : -1
}
// Bar top-right corner (only if not framed)
PathArc {
x: root.isFramed ? (root.shouldShow ? root.screenWidth : 0) : (root.barMappedPos.x + root.barWidth + root.rightEdgeOvs)
y: root.isFramed ? 0 : (root.barMappedPos.y + root.topEdgeOvs + root.trRadius * root.trMultY)
radiusX: root.isFramed ? 0 : root.trRadius
radiusY: root.isFramed ? 0 : root.trRadius
x: root.isRenderable ? (root.isFramed ? root.screenWidth : (root.barMappedPos.x + root.barWidth + root.rightEdgeOvs)) : 0
y: root.isRenderable ? (root.isFramed ? 0 : (root.barMappedPos.y + root.topEdgeOvs + root.trRadius * root.trMultY)) : -1
radiusX: root.isRenderable ? (root.isFramed ? 0 : root.trRadius) : 0
radiusY: root.isRenderable ? (root.isFramed ? 0 : root.trRadius) : 0
direction: ShapeCornerHelper.getArcDirection(root.trMultX, root.trMultY)
}
PathLine {
x: root.isFramed ? (root.shouldShow ? root.screenWidth : 0) : (root.barMappedPos.x + root.barWidth + root.rightEdgeOvs)
y: {
if (!root.shouldShow)
return 0;
if (root.isFramed)
return root.screenHeight;
return root.barMappedPos.y + root.barHeight + root.bottomEdgeOvs - root.brRadius * root.brMultY;
}
x: root.isRenderable ? (root.isFramed ? root.screenWidth : (root.barMappedPos.x + root.barWidth + root.rightEdgeOvs)) : 0
y: root.isRenderable ? (root.isFramed ? root.screenHeight : (root.barMappedPos.y + root.barHeight + root.bottomEdgeOvs - root.brRadius * root.brMultY)) : 0
}
// Bar bottom-right corner (only if not framed)
PathArc {
x: root.isFramed ? (root.shouldShow ? root.screenWidth : 0) : (root.barMappedPos.x + root.barWidth + root.rightEdgeOvs - root.brRadius * root.brMultX)
y: root.isFramed ? (root.shouldShow ? root.screenHeight : 0) : (root.barMappedPos.y + root.barHeight + root.bottomEdgeOvs)
radiusX: root.isFramed ? 0 : root.brRadius
radiusY: root.isFramed ? 0 : root.brRadius
x: root.isRenderable ? (root.isFramed ? root.screenWidth : (root.barMappedPos.x + root.barWidth + root.rightEdgeOvs - root.brRadius * root.brMultX)) : 0
y: root.isRenderable ? (root.isFramed ? root.screenHeight : (root.barMappedPos.y + root.barHeight + root.bottomEdgeOvs)) : 0
radiusX: root.isRenderable ? (root.isFramed ? 0 : root.brRadius) : 0
radiusY: root.isRenderable ? (root.isFramed ? 0 : root.brRadius) : 0
direction: ShapeCornerHelper.getArcDirection(root.brMultX, root.brMultY)
}
PathLine {
x: {
if (!root.shouldShow)
return 0;
if (root.isFramed)
return 0;
return root.barMappedPos.x + root.leftEdgeOvs + root.blRadius * root.blMultX;
}
y: root.isFramed ? (root.shouldShow ? root.screenHeight : 0) : (root.barMappedPos.y + root.barHeight + root.bottomEdgeOvs)
x: root.isRenderable ? (root.isFramed ? 0 : (root.barMappedPos.x + root.leftEdgeOvs + root.blRadius * root.blMultX)) : -1
y: root.isRenderable ? (root.isFramed ? root.screenHeight : (root.barMappedPos.y + root.barHeight + root.bottomEdgeOvs)) : 0
}
// Bar bottom-left corner (only if not framed)
PathArc {
x: root.isFramed ? 0 : (root.barMappedPos.x + root.leftEdgeOvs)
y: root.isFramed ? (root.shouldShow ? root.screenHeight : 0) : (root.barMappedPos.y + root.barHeight + root.bottomEdgeOvs - root.blRadius * root.blMultY)
radiusX: root.isFramed ? 0 : root.blRadius
radiusY: root.isFramed ? 0 : root.blRadius
x: root.isRenderable ? (root.isFramed ? 0 : (root.barMappedPos.x + root.leftEdgeOvs)) : -1
y: root.isRenderable ? (root.isFramed ? root.screenHeight : (root.barMappedPos.y + root.barHeight + root.bottomEdgeOvs - root.blRadius * root.blMultY)) : 0
radiusX: root.isRenderable ? (root.isFramed ? 0 : root.blRadius) : 0
radiusY: root.isRenderable ? (root.isFramed ? 0 : root.blRadius) : 0
direction: ShapeCornerHelper.getArcDirection(root.blMultX, root.blMultY)
}
PathLine {
x: root.isFramed ? 0 : (root.barMappedPos.x + root.leftEdgeOvs)
y: {
if (!root.shouldShow)
return 0;
if (root.isFramed)
return 0;
return root.barMappedPos.y + root.topEdgeOvs + root.tlRadius * root.tlMultY;
}
x: root.isRenderable ? (root.isFramed ? 0 : (root.barMappedPos.x + root.leftEdgeOvs)) : -1
y: root.isRenderable ? (root.isFramed ? 0 : (root.barMappedPos.y + root.topEdgeOvs + root.tlRadius * root.tlMultY)) : -1
}
// Bar top-left corner (only if not framed, back to start)
PathArc {
x: root.isFramed ? 0 : (root.barMappedPos.x + root.leftEdgeOvs + root.tlRadius * root.tlMultX)
y: root.isFramed ? 0 : (root.barMappedPos.y + root.topEdgeOvs)
radiusX: root.isFramed ? 0 : root.tlRadius
radiusY: root.isFramed ? 0 : root.tlRadius
x: root.isRenderable ? (root.isFramed ? 0 : (root.barMappedPos.x + root.leftEdgeOvs + root.tlRadius * root.tlMultX)) : -1
y: root.isRenderable ? (root.isFramed ? 0 : (root.barMappedPos.y + root.topEdgeOvs)) : -1
radiusX: root.isRenderable ? (root.isFramed ? 0 : root.tlRadius) : 0
radiusY: root.isRenderable ? (root.isFramed ? 0 : root.tlRadius) : 0
direction: ShapeCornerHelper.getArcDirection(root.tlMultX, root.tlMultY)
}
// 2. Inner Hole for Framed Mode (Clockwise)
// When !isFramed, draws a tiny 1x1 rectangle inside the bar as a non-degenerate WindingFill
// no-op to prevent a zero-area degenerate subpath crashing qTriangulate.
// Note: an exact duplicate of the outer path cannot be used here because Qt's CurveRenderer
// has issues with exactly coincident subpaths, causing the fill to not render on some systems.
// When !isRenderable, falls back to a valid 1×1 off-screen square at (-3,-3)→(-2,-2).
readonly property real _nhX: barMappedPos.x + barWidth / 2
readonly property real _nhY: barMappedPos.y + barHeight / 2
PathMove {
x: (root.isFramed && root.shouldShow) ? (root.holeX + root.frameRadius) : root.startX
y: (root.isFramed && root.shouldShow) ? root.holeY : root.startY
x: root.isRenderable ? (root.isFramed ? (root.holeX + root.frameRadius) : root._nhX) : -3
y: root.isRenderable ? (root.isFramed ? root.holeY : root._nhY) : -3
}
// Top edge
PathLine {
x: (root.isFramed && root.shouldShow) ? (root.holeX + root.holeWidth - root.frameRadius) : ((root.isFramed && root.shouldShow) ? (root.holeX + root.frameRadius) : root.startX)
y: (root.isFramed && root.shouldShow) ? root.holeY : ((root.isFramed && root.shouldShow) ? root.holeY : root.startY)
x: root.isRenderable ? (root.isFramed ? (root.holeX + root.holeWidth - root.frameRadius) : (root._nhX + 1)) : -2
y: root.isRenderable ? (root.isFramed ? root.holeY : root._nhY) : -3
}
// Top-right corner
PathArc {
x: (root.isFramed && root.shouldShow) ? (root.holeX + root.holeWidth) : ((root.isFramed && root.shouldShow) ? (root.holeX + root.holeWidth - root.frameRadius) : root.startX)
y: (root.isFramed && root.shouldShow) ? (root.holeY + root.frameRadius) : ((root.isFramed && root.shouldShow) ? root.holeY : root.startY)
radiusX: (root.isFramed && root.shouldShow) ? root.frameRadius : 0
radiusY: (root.isFramed && root.shouldShow) ? root.frameRadius : 0
x: root.isRenderable ? (root.isFramed ? (root.holeX + root.holeWidth) : (root._nhX + 1)) : -2
y: root.isRenderable ? (root.isFramed ? (root.holeY + root.frameRadius) : root._nhY) : -3
radiusX: root.isRenderable ? (root.isFramed ? root.frameRadius : 0) : 0
radiusY: root.isRenderable ? (root.isFramed ? root.frameRadius : 0) : 0
direction: PathArc.Clockwise
}
// Right edge
PathLine {
x: (root.isFramed && root.shouldShow) ? (root.holeX + root.holeWidth) : root.startX
y: (root.isFramed && root.shouldShow) ? (root.holeY + root.holeHeight - root.frameRadius) : root.startY
x: root.isRenderable ? (root.isFramed ? (root.holeX + root.holeWidth) : (root._nhX + 1)) : -2
y: root.isRenderable ? (root.isFramed ? (root.holeY + root.holeHeight - root.frameRadius) : (root._nhY + 1)) : -2
}
// Bottom-right corner
PathArc {
x: (root.isFramed && root.shouldShow) ? (root.holeX + root.holeWidth - root.frameRadius) : root.startX
y: (root.isFramed && root.shouldShow) ? (root.holeY + root.holeHeight) : root.startY
radiusX: (root.isFramed && root.shouldShow) ? root.frameRadius : 0
radiusY: (root.isFramed && root.shouldShow) ? root.frameRadius : 0
x: root.isRenderable ? (root.isFramed ? (root.holeX + root.holeWidth - root.frameRadius) : (root._nhX + 1)) : -2
y: root.isRenderable ? (root.isFramed ? (root.holeY + root.holeHeight) : (root._nhY + 1)) : -2
radiusX: root.isRenderable ? (root.isFramed ? root.frameRadius : 0) : 0
radiusY: root.isRenderable ? (root.isFramed ? root.frameRadius : 0) : 0
direction: PathArc.Clockwise
}
// Bottom edge
PathLine {
x: (root.isFramed && root.shouldShow) ? (root.holeX + root.frameRadius) : root.startX
y: (root.isFramed && root.shouldShow) ? (root.holeY + root.holeHeight) : root.startY
x: root.isRenderable ? (root.isFramed ? (root.holeX + root.frameRadius) : root._nhX) : -3
y: root.isRenderable ? (root.isFramed ? (root.holeY + root.holeHeight) : (root._nhY + 1)) : -2
}
// Bottom-left corner
PathArc {
x: (root.isFramed && root.shouldShow) ? root.holeX : root.startX
y: (root.isFramed && root.shouldShow) ? (root.holeY + root.holeHeight - root.frameRadius) : root.startY
radiusX: (root.isFramed && root.shouldShow) ? root.frameRadius : 0
radiusY: (root.isFramed && root.shouldShow) ? root.frameRadius : 0
x: root.isRenderable ? (root.isFramed ? root.holeX : root._nhX) : -3
y: root.isRenderable ? (root.isFramed ? (root.holeY + root.holeHeight - root.frameRadius) : (root._nhY + 1)) : -2
radiusX: root.isRenderable ? (root.isFramed ? root.frameRadius : 0) : 0
radiusY: root.isRenderable ? (root.isFramed ? root.frameRadius : 0) : 0
direction: PathArc.Clockwise
}
// Left edge
PathLine {
x: (root.isFramed && root.shouldShow) ? root.holeX : root.startX
y: (root.isFramed && root.shouldShow) ? (root.holeY + root.frameRadius) : root.startY
x: root.isRenderable ? (root.isFramed ? root.holeX : root._nhX) : -3
y: root.isRenderable ? (root.isFramed ? (root.holeY + root.frameRadius) : root._nhY) : -3
}
// Top-left corner (back to start)
PathArc {
x: (root.isFramed && root.shouldShow) ? (root.holeX + root.frameRadius) : root.startX
y: (root.isFramed && root.shouldShow) ? root.holeY : root.startY
radiusX: (root.isFramed && root.shouldShow) ? root.frameRadius : 0
radiusY: (root.isFramed && root.shouldShow) ? root.frameRadius : 0
x: root.isRenderable ? (root.isFramed ? (root.holeX + root.frameRadius) : root._nhX) : -3
y: root.isRenderable ? (root.isFramed ? root.holeY : root._nhY) : -3
radiusX: root.isRenderable ? (root.isFramed ? root.frameRadius : 0) : 0
radiusY: root.isRenderable ? (root.isFramed ? root.frameRadius : 0) : 0
direction: PathArc.Clockwise
}
}
@@ -53,6 +53,7 @@ ShapePath {
readonly property real panelY: panelBg ? panelBg.y : 0
readonly property real panelWidth: panelBg ? panelBg.width : 0
readonly property real panelHeight: panelBg ? panelBg.height : 0
readonly property bool isRenderable: assignedPanel && panelBg && panelWidth > 0 && panelHeight > 0
// Flatten corners if panel is too small
readonly property bool shouldFlatten: panelBg ? ShapeCornerHelper.shouldFlatten(panelWidth, panelHeight, radius) : false
@@ -87,11 +88,11 @@ ShapePath {
// ShapePath configuration
strokeWidth: -1 // No stroke, fill only
// Starting position (top-left corner, after the arc)
startX: panelX + tlRadius * tlMultX
startY: panelY
// Start point - use tiny off-screen non-degenerate fallback when not renderable.
startX: isRenderable ? (panelX + tlRadius * tlMultX) : -1
startY: isRenderable ? panelY : -1
fillColor: effectiveBackgroundColor
fillColor: isRenderable ? effectiveBackgroundColor : "transparent"
// ========== PATH DEFINITION ==========
// Draws a rectangle with potentially inverted corners
@@ -99,61 +100,61 @@ ShapePath {
// Top edge (moving right)
PathLine {
relativeX: root.panelWidth - root.tlRadius * root.tlMultX - root.trRadius * root.trMultX
relativeX: root.isRenderable ? (root.panelWidth - root.tlRadius * root.tlMultX - root.trRadius * root.trMultX) : 1
relativeY: 0
}
// Top-right corner arc
PathArc {
relativeX: root.trRadius * root.trMultX
relativeY: root.trRadius * root.trMultY
radiusX: root.trRadius
radiusY: root.trRadius
relativeX: root.isRenderable ? (root.trRadius * root.trMultX) : 0
relativeY: root.isRenderable ? (root.trRadius * root.trMultY) : 0
radiusX: root.isRenderable ? root.trRadius : 0
radiusY: root.isRenderable ? root.trRadius : 0
direction: ShapeCornerHelper.getArcDirection(root.trMultX, root.trMultY)
}
// Right edge (moving down)
PathLine {
relativeX: 0
relativeY: root.panelHeight - root.trRadius * root.trMultY - root.brRadius * root.brMultY
relativeY: root.isRenderable ? (root.panelHeight - root.trRadius * root.trMultY - root.brRadius * root.brMultY) : 1
}
// Bottom-right corner arc
PathArc {
relativeX: -root.brRadius * root.brMultX
relativeY: root.brRadius * root.brMultY
radiusX: root.brRadius
radiusY: root.brRadius
relativeX: root.isRenderable ? (-root.brRadius * root.brMultX) : 0
relativeY: root.isRenderable ? (root.brRadius * root.brMultY) : 0
radiusX: root.isRenderable ? root.brRadius : 0
radiusY: root.isRenderable ? root.brRadius : 0
direction: ShapeCornerHelper.getArcDirection(root.brMultX, root.brMultY)
}
// Bottom edge (moving left)
PathLine {
relativeX: -(root.panelWidth - root.brRadius * root.brMultX - root.blRadius * root.blMultX)
relativeX: root.isRenderable ? (-(root.panelWidth - root.brRadius * root.brMultX - root.blRadius * root.blMultX)) : -1
relativeY: 0
}
// Bottom-left corner arc
PathArc {
relativeX: -root.blRadius * root.blMultX
relativeY: -root.blRadius * root.blMultY
radiusX: root.blRadius
radiusY: root.blRadius
relativeX: root.isRenderable ? (-root.blRadius * root.blMultX) : 0
relativeY: root.isRenderable ? (-root.blRadius * root.blMultY) : 0
radiusX: root.isRenderable ? root.blRadius : 0
radiusY: root.isRenderable ? root.blRadius : 0
direction: ShapeCornerHelper.getArcDirection(root.blMultX, root.blMultY)
}
// Left edge (moving up) - closes the path back to start
PathLine {
relativeX: 0
relativeY: -(root.panelHeight - root.blRadius * root.blMultY - root.tlRadius * root.tlMultY)
relativeY: root.isRenderable ? (-(root.panelHeight - root.blRadius * root.blMultY - root.tlRadius * root.tlMultY)) : -1
}
// Top-left corner arc (back to start)
PathArc {
relativeX: root.tlRadius * root.tlMultX
relativeY: -root.tlRadius * root.tlMultY
radiusX: root.tlRadius
radiusY: root.tlRadius
relativeX: root.isRenderable ? (root.tlRadius * root.tlMultX) : 0
relativeY: root.isRenderable ? (-root.tlRadius * root.tlMultY) : 0
radiusX: root.isRenderable ? root.tlRadius : 0
radiusY: root.isRenderable ? root.tlRadius : 0
direction: ShapeCornerHelper.getArcDirection(root.tlMultX, root.tlMultY)
}
}
+9 -7
View File
@@ -203,7 +203,9 @@ PanelWindow {
}
// Blur behind the bar and open panels — attached to PanelWindow (required by BackgroundEffect API)
BackgroundEffect.blurRegion: Region {
BackgroundEffect.blurRegion: Settings.data.general.enableBlurBehind ? blurRegion : null
Region {
id: blurRegion
// ── Non-framed bar (simple/floating): single rectangle with bar corner states ──
Region {
x: (!barPlaceholder.isFramed && root.barShouldShow && !barPlaceholder.isHidden) ? barPlaceholder.x : 0
@@ -460,14 +462,14 @@ PanelWindow {
// Use screen dimensions directly
x: {
if (barPosition === "right")
return screen.width - barHeight - barMarginH;
return (screen?.width ?? 0) - barHeight - barMarginH;
if (isFramed && !barIsVertical)
return frameThickness;
return barMarginH;
}
y: {
if (barPosition === "bottom")
return screen.height - barHeight - barMarginV;
return (screen?.height ?? 0) - barHeight - barMarginV;
if (isFramed && barIsVertical)
return frameThickness;
return barMarginV;
@@ -477,16 +479,16 @@ PanelWindow {
return barHeight;
}
if (isFramed)
return screen.width - frameThickness * 2;
return screen.width - barMarginH * 2;
return (screen?.width ?? 0) - frameThickness * 2;
return (screen?.width ?? 0) - barMarginH * 2;
}
height: {
if (!barIsVertical) {
return barHeight;
}
if (isFramed)
return screen.height - frameThickness * 2;
return screen.height - barMarginV * 2;
return (screen?.height ?? 0) - frameThickness * 2;
return (screen?.height ?? 0) - barMarginV * 2;
}
// Corner states (same as Bar.qml)
+1
View File
@@ -26,6 +26,7 @@ Item {
anchors.fill: parent
preferredRendererType: Shape.CurveRenderer
enabled: false // Disable mouse input
visible: cornersPath.cornerRadius > 0 && width > 0 && height > 0
ShapePath {
id: cornersPath
+32 -27
View File
@@ -163,11 +163,41 @@ Item {
// Reset to default - fixes panel being stuck in one position
root.useButtonPosition = false;
// Calculate the bar window's position on screen based on bar settings
// The BarContentWindow uses anchors + margins, so we need to compute its origin
var barWindowX = 0;
var barWindowY = 0;
var screenWidth = root.screen?.width || 0;
var screenHeight = root.screen?.height || 0;
if (root.barPosition === "right") {
barWindowX = screenWidth - root.barMarginH - root.barHeight;
} else if (root.barPosition === "left") {
barWindowX = root.barMarginH;
} else if (root.isFramed) {
barWindowX = root.frameThickness;
} else {
// Horizontal floating bars: BarContentWindow has margins.left = barMarginH
barWindowX = root.barMarginH;
}
if (root.barPosition === "bottom") {
barWindowY = screenHeight - root.barMarginV - root.barHeight;
} else if (root.barPosition === "top") {
barWindowY = root.barMarginV;
} else if (root.isFramed) {
barWindowY = root.frameThickness;
} else {
// Vertical floating bars: BarContentWindow has margins.top = barMarginV
barWindowY = root.barMarginV;
}
if (!buttonItem && buttonName) {
// Check if buttonName is actually a point object (click coordinates)
if (typeof buttonName === "object" && buttonName.x !== undefined && buttonName.y !== undefined) {
root.buttonItem = null;
root.buttonPosition = buttonName;
// Click coordinates are in BarContentWindow-local space, offset to screen space
root.buttonPosition = Qt.point(barWindowX + buttonName.x, barWindowY + buttonName.y);
root.buttonWidth = 0;
root.buttonHeight = 0;
root.useButtonPosition = true;
@@ -181,34 +211,9 @@ Item {
if (buttonItem && typeof buttonItem.mapToItem === "function") {
try {
root.buttonItem = buttonItem;
// Map button position within its window
// Map button position within its window (BarContentWindow-local coordinates)
var buttonLocal = buttonItem.mapToItem(null, 0, 0);
// Calculate the bar window's position on screen based on bar settings
// The BarContentWindow uses anchors, so we need to compute its position
var barWindowX = 0;
var barWindowY = 0;
var screenWidth = root.screen?.width || 0;
var screenHeight = root.screen?.height || 0;
if (root.barPosition === "right") {
barWindowX = screenWidth - root.barMarginH - root.barHeight;
} else if (root.barPosition === "left") {
barWindowX = root.barMarginH;
} else if (root.isFramed) {
barWindowX = root.frameThickness;
}
// For top/bottom bars, barWindowX stays 0 (full width window) unless framed
if (root.barPosition === "bottom") {
barWindowY = screenHeight - root.barMarginV - root.barHeight;
} else if (root.barPosition === "top") {
barWindowY = root.barMarginV;
} else if (root.isFramed) {
barWindowY = root.frameThickness;
}
// For left/right bars, barWindowY stays 0 (full height window) unless framed
root.buttonPosition = Qt.point(barWindowX + buttonLocal.x, barWindowY + buttonLocal.y);
root.buttonWidth = buttonItem.width;
root.buttonHeight = buttonItem.height;