diff --git a/Modules/Background/ScreenCorners.qml b/Modules/Background/ScreenCorners.qml index de720c4..8573bcf 100644 --- a/Modules/Background/ScreenCorners.qml +++ b/Modules/Background/ScreenCorners.qml @@ -48,6 +48,8 @@ Loader { margins { top: ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "top" && Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0 bottom: ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "bottom" && Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0 + left: ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "left" && Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0 + right: ((modelData && Settings.data.bar.monitors.includes(modelData.name)) || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "right" && Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0 } mask: Region {} diff --git a/Modules/Notification/Notification.qml b/Modules/Notification/Notification.qml index f462a41..ebb1336 100644 --- a/Modules/Notification/Notification.qml +++ b/Modules/Notification/Notification.qml @@ -33,13 +33,14 @@ Variants { screen: modelData color: Color.transparent - // Position based on bar location - anchors.top: Settings.data.bar.position === "top" - anchors.bottom: Settings.data.bar.position === "bottom" - anchors.right: true - margins.top: Settings.data.bar.position === "top" ? (Style.barHeight + Style.marginM + (Settings.data.bar.floating ? Settings.data.bar.marginTop : 0)) * scaling : 0 + // Position based on bar location - always at top + anchors.top: true + anchors.right: Settings.data.bar.position === "left" || Settings.data.bar.position === "top" || Settings.data.bar.position === "bottom" + anchors.left: Settings.data.bar.position === "right" + margins.top: Settings.data.bar.position === "top" ? (Style.barHeight + Style.marginM + (Settings.data.bar.floating ? Settings.data.bar.marginTop : 0)) * scaling : Style.marginM * scaling margins.bottom: Settings.data.bar.position === "bottom" ? (Style.barHeight + Style.marginM + (Settings.data.bar.floating ? Settings.data.bar.marginBottom : 0)) * scaling : 0 - margins.right: Style.marginM * scaling + margins.right: (Settings.data.bar.position === "left" || Settings.data.bar.position === "top" || Settings.data.bar.position === "bottom") ? Style.marginM * scaling : 0 + margins.left: Settings.data.bar.position === "right" ? Style.marginM * scaling : 0 implicitWidth: 360 * scaling implicitHeight: Math.min(notificationStack.implicitHeight, (NotificationService.maxVisible * 120) * scaling) //WlrLayershell.layer: WlrLayer.Overlay @@ -77,10 +78,10 @@ Variants { // Main notification container ColumnLayout { id: notificationStack - // Position based on bar location - anchors.top: Settings.data.bar.position === "top" ? parent.top : undefined - anchors.bottom: Settings.data.bar.position === "bottom" ? parent.bottom : undefined - anchors.right: parent.right + // Position based on bar location - always at top + anchors.top: parent.top + anchors.right: (Settings.data.bar.position === "left" || Settings.data.bar.position === "top" || Settings.data.bar.position === "bottom") ? parent.right : undefined + anchors.left: Settings.data.bar.position === "right" ? parent.left : undefined spacing: Style.marginS * scaling width: 360 * scaling visible: true diff --git a/Modules/Toast/ToastOverlay.qml b/Modules/Toast/ToastOverlay.qml index edc9249..038d76c 100644 --- a/Modules/Toast/ToastOverlay.qml +++ b/Modules/Toast/ToastOverlay.qml @@ -30,10 +30,11 @@ Variants { screen: modelData - // Position based on bar location, like Notification popup does + // Position at top of screen, always allow horizontal centering anchors { - top: Settings.data.bar.position === "top" - bottom: Settings.data.bar.position === "bottom" + top: true + left: true + right: true } // Set a width instead of anchoring left/right so we can click on the side of the toast @@ -45,6 +46,8 @@ Variants { // Set margins based on bar position margins.top: Settings.data.bar.position === "top" ? (Style.barHeight + Style.marginS + (Settings.data.bar.floating ? Settings.data.bar.marginTop : 0)) * scaling : 0 margins.bottom: Settings.data.bar.position === "bottom" ? (Style.barHeight + Style.marginS + (Settings.data.bar.floating ? Settings.data.bar.marginBottom : 0)) * scaling : 0 + margins.right: (Settings.data.bar.position === "left" || Settings.data.bar.position === "top" || Settings.data.bar.position === "bottom") ? Style.marginM * scaling : 0 + margins.left: Settings.data.bar.position === "right" ? Style.marginM * scaling : 0 // Transparent background color: Color.transparent diff --git a/Widgets/NPanel.qml b/Widgets/NPanel.qml index 9b1904e..98b613f 100644 --- a/Widgets/NPanel.qml +++ b/Widgets/NPanel.qml @@ -141,6 +141,7 @@ Loader { // PanelWindow has its own screen property inherited of QsWindow property real scaling: ScalingService.getScreenScale(screen) readonly property real barHeight: Math.round(Style.barHeight * scaling) + readonly property real barWidth: Math.round(Style.barHeight * scaling) readonly property bool barAtBottom: Settings.data.bar.position === "bottom" readonly property bool barIsVisible: (screen !== null) && (Settings.data.bar.monitors.includes(screen.name) || (Settings.data.bar.monitors.length === 0)) @@ -237,31 +238,119 @@ Loader { y: calculatedY property int calculatedX: { - if (root.useButtonPosition) { - // Position panel relative to button - var targetX = root.buttonPosition.x + (root.buttonWidth / 2) - (preferredWidth / 2) + var barPosition = Settings.data.bar.position - // Keep panel within screen bounds - var maxX = panelWindow.width - panelBackground.width - (Style.marginS * scaling) - var minX = Style.marginS * scaling - - return Math.round(Math.max(minX, Math.min(targetX, maxX))) - } else if (!panelAnchorHorizontalCenter && panelAnchorLeft) { + // Check anchor properties first, even when using button positioning + if (!panelAnchorHorizontalCenter && panelAnchorLeft) { return Math.round(Style.marginS * scaling) } else if (!panelAnchorHorizontalCenter && panelAnchorRight) { - return Math.round(panelWindow.width - panelBackground.width - (Style.marginS * scaling)) + // For right anchor, consider bar position + if (barPosition === "right") { + // If bar is on right, position panel to the left of the bar + var maxX = panelWindow.width - barWidth - panelBackground.width - (Style.marginS * scaling) + + // If we have button position, position close to the button like working panels + if (root.useButtonPosition) { + // Use the same logic as working panels - position at edge of bar with spacing + var maxXWithSpacing = panelWindow.width - barWidth - panelBackground.width + // Add spacing - more if screen corners are disabled, less if enabled + if (!Settings.data.general.showScreenCorners || Settings.data.bar.floating) { + maxXWithSpacing -= Style.marginL * scaling + } else { + maxXWithSpacing -= Style.marginM * scaling + } + return Math.round(maxXWithSpacing) + } else { + return Math.round(maxX) + } + } else { + // Default right positioning + var rightX = panelWindow.width - panelBackground.width - (Style.marginS * scaling) + return Math.round(rightX) + } + } else if (root.useButtonPosition) { + // Position panel relative to button (only if no explicit anchoring) + var targetX + + // For vertical bars, position panel close to the button + if (barPosition === "left") { + // Position panel to the right of the left bar, close to the button + var minX = barWidth + // Add spacing - more if screen corners are disabled, less if enabled + if (!Settings.data.general.showScreenCorners || Settings.data.bar.floating) { + minX += Style.marginL * scaling + } else { + minX += Style.marginM * scaling + } + targetX = minX + } else if (barPosition === "right") { + // Position panel to the left of the right bar, close to the button + var maxX = panelWindow.width - barWidth - panelBackground.width + // Add spacing - more if screen corners are disabled, less if enabled + if (!Settings.data.general.showScreenCorners || Settings.data.bar.floating) { + maxX -= Style.marginL * scaling + } else { + maxX -= Style.marginM * scaling + } + targetX = maxX + } else { + // For horizontal bars, center panel on button + targetX = root.buttonPosition.x + (root.buttonWidth / 2) - (panelBackground.width / 2) + } + + // Keep panel within screen bounds + var maxScreenX = panelWindow.width - panelBackground.width - (Style.marginS * scaling) + var minScreenX = Style.marginS * scaling + + return Math.round(Math.max(minScreenX, Math.min(targetX, maxScreenX))) } else { - return Math.round((panelWindow.width - panelBackground.width) / 2) + // For vertical bars, center but avoid bar overlap + var centerX = (panelWindow.width - panelBackground.width) / 2 + if (barPosition === "left") { + var minX = barWidth + // Add spacing - more if screen corners are disabled, less if enabled + if (!Settings.data.general.showScreenCorners || Settings.data.bar.floating) { + minX += Style.marginL * scaling + } else { + minX += Style.marginM * scaling + } + centerX = Math.max(centerX, minX) + } else if (barPosition === "right") { + // For right bar, center but ensure it doesn't overlap with the bar + var maxX = panelWindow.width - barWidth - panelBackground.width + // Add spacing - more if screen corners are disabled, less if enabled + if (!Settings.data.general.showScreenCorners || Settings.data.bar.floating) { + maxX -= Style.marginL * scaling + } else { + maxX -= Style.marginM * scaling + } + centerX = Math.min(centerX, maxX) + } + return Math.round(centerX) } } property int calculatedY: { - if (panelAnchorVerticalCenter) { + var barPosition = Settings.data.bar.position + + if (root.useButtonPosition) { + // Position panel relative to button + var targetY = root.buttonPosition.y + (root.buttonHeight / 2) - (panelBackground.height / 2) + + // Keep panel within screen bounds + var maxY = panelWindow.height - panelBackground.height - (Style.marginS * scaling) + var minY = Style.marginS * scaling + + return Math.round(Math.max(minY, Math.min(targetY, maxY))) + } else if (panelAnchorVerticalCenter) { return Math.round((panelWindow.height - panelBackground.height) / 2) } else if (panelAnchorBottom) { return Math.round(panelWindow.height - panelBackground.height - (Style.marginS * scaling)) } else if (panelAnchorTop) { return Math.round(Style.marginS * scaling) + } else if (barPosition === "left" || barPosition === "right") { + // For vertical bars, center vertically + return Math.round((panelWindow.height - panelBackground.height) / 2) } else if (!barAtBottom) { // Below the top bar return Math.round(Style.marginS * scaling) diff --git a/Widgets/NTooltip.qml b/Widgets/NTooltip.qml index 168d7ee..176551a 100644 --- a/Widgets/NTooltip.qml +++ b/Widgets/NTooltip.qml @@ -46,17 +46,35 @@ Window { return } - if (positionLeft) { + // Auto-detect positioning based on bar position if not explicitly set + var shouldPositionLeft = positionLeft + var shouldPositionRight = positionRight + var shouldPositionAbove = positionAbove + + // If no explicit positioning is set, auto-detect based on bar position + if (!positionLeft && !positionRight && !positionAbove) { + var barPosition = BarService.position + if (barPosition === "left") { + shouldPositionRight = true + } else if (barPosition === "right") { + shouldPositionLeft = true + } else if (barPosition === "bottom") { + shouldPositionAbove = true + } + // For "top" bar, default to below (no change needed) + } + + if (shouldPositionLeft) { // Position tooltip to the left of the target var pos = target.mapToGlobal(0, 0) x = pos.x - width - 12 // 12 px margin to the left y = pos.y - height / 2 + target.height / 2 - } else if (positionRight) { + } else if (shouldPositionRight) { // Position tooltip to the right of the target var pos = target.mapToGlobal(target.width, 0) x = pos.x + 12 // 12 px margin to the right y = pos.y - height / 2 + target.height / 2 - } else if (positionAbove) { + } else if (shouldPositionAbove) { // Position tooltip above the target var pos = target.mapToGlobal(0, 0) x = pos.x - width / 2 + target.width / 2