From f4eef3c7a7cb69432d61f23043e6c6cf53ac5aaf Mon Sep 17 00:00:00 2001 From: ferreo Date: Wed, 16 Jul 2025 12:19:34 +0100 Subject: [PATCH] feat: remove the stolen screen space --- Bar/Bar.qml | 109 ++++++++++------ Bar/Modules/ActiveWindow.qml | 241 +++++++++++++++++++---------------- 2 files changed, 197 insertions(+), 153 deletions(-) diff --git a/Bar/Bar.qml b/Bar/Bar.qml index e249d11..ccdc72d 100644 --- a/Bar/Bar.qml +++ b/Bar/Bar.qml @@ -32,47 +32,13 @@ Scope { id: panel screen: modelData color: "transparent" - implicitHeight: barBackground.height + 24 + implicitHeight: barBackground.height anchors.top: true anchors.left: true anchors.right: true visible: true - property string lastFocusedWindowTitle: "" - property bool activeWindowVisible: false - property string displayedWindowTitle: "" - - onLastFocusedWindowTitleChanged: { - displayedWindowTitle = (lastFocusedWindowTitle === "(No active window)") ? "" : lastFocusedWindowTitle - } - - Timer { - id: hideTimer - interval: 4000 - repeat: false - onTriggered: panel.activeWindowVisible = false - } - - Connections { - target: Niri - function onFocusedWindowTitleChanged() { - var newTitle = Niri.focusedWindowTitle - - if (newTitle !== panel.lastFocusedWindowTitle) { - panel.lastFocusedWindowTitle = newTitle - - if (newTitle === "(No active window)") { - panel.activeWindowVisible = false - hideTimer.stop() - } else { - panel.activeWindowVisible = true - hideTimer.restart() - } - } - } - } - Rectangle { id: barBackground width: parent.width @@ -98,7 +64,9 @@ Scope { } } - ActiveWindow {} + ActiveWindow { + screen: modelData + } Workspace { id: workspace @@ -153,6 +121,25 @@ Scope { } } + + + Background {} + Overview {} + } + + PanelWindow { + id: topCornerPanel + anchors.top: true + anchors.left: true + anchors.right: true + color: "transparent" + screen: modelData + margins.top: 36 + WlrLayershell.exclusionMode: ExclusionMode.Ignore + visible: true + + implicitHeight: 24 + Corners { id: topleftCorner position: "bottomleft" @@ -160,7 +147,7 @@ Scope { fillColor: (Theme.backgroundPrimary !== undefined && Theme.backgroundPrimary !== null) ? Theme.backgroundPrimary : "#222" offsetX: -39 offsetY: 0 - anchors.top: barBackground.bottom + anchors.top: parent.top } Corners { @@ -170,14 +157,56 @@ Scope { fillColor: (Theme.backgroundPrimary !== undefined && Theme.backgroundPrimary !== null) ? Theme.backgroundPrimary : "#222" offsetX: 39 offsetY: 0 - anchors.top: barBackground.bottom + anchors.top: parent.top } + } - Background {} - Overview {} + PanelWindow { + id: bottomLeftPanel + anchors.bottom: true + anchors.left: true + color: "transparent" + screen: modelData + WlrLayershell.exclusionMode: ExclusionMode.Ignore + visible: true + + implicitHeight: 24 + + Corners { + id: bottomLeftCorner + position: "topleft" + size: 1.3 + fillColor: (Theme.backgroundPrimary !== undefined && Theme.backgroundPrimary !== null) ? Theme.backgroundPrimary : "#222" + offsetX: -39 + offsetY: 0 + anchors.top: parent.top + } + } + + PanelWindow { + id: bottomRightCornerPanel + anchors.bottom: true + anchors.right: true + color: "transparent" + screen: modelData + WlrLayershell.exclusionMode: ExclusionMode.Ignore + visible: true + + implicitHeight: 24 + + Corners { + id: bottomRightCorner + position: "topright" + size: 1.3 + fillColor: (Theme.backgroundPrimary !== undefined && Theme.backgroundPrimary !== null) ? Theme.backgroundPrimary : "#222" + offsetX: 39 + offsetY: 0 + anchors.top: parent.top + } } } } + } // This alias exposes the visual bar's visibility to the outside world diff --git a/Bar/Modules/ActiveWindow.qml b/Bar/Modules/ActiveWindow.qml index d3cf692..eeda285 100644 --- a/Bar/Modules/ActiveWindow.qml +++ b/Bar/Modules/ActiveWindow.qml @@ -5,132 +5,147 @@ import qs.Settings import Quickshell.Wayland import Quickshell.Widgets -Item { - id: activeWindowWrapper - width: parent.width - property int fullHeight: activeWindowTitleContainer.height - property bool shouldShow: false - - Timer { - id: visibilityTimer - interval: 4000 - running: false - onTriggered: { - activeWindowWrapper.shouldShow = false +PanelWindow { + id: activeWindowPanel + screen: (typeof modelData !== 'undefined' ? modelData : null) + WlrLayershell.exclusionMode: ExclusionMode.Ignore + anchors.top: true + anchors.left: true + anchors.right: true + margins.top: barHeight + visible: activeWindowWrapper.shouldShow + implicitHeight: activeWindowTitleContainer.height + property int barHeight: 36 + color: "transparent" + + function getIcon() { + var icon = Quickshell.iconPath(ToplevelManager.activeToplevel.appId.toLowerCase(), true); + if (!icon) { + icon = Quickshell.iconPath(ToplevelManager.activeToplevel.appId, true); + } + if (!icon) { + icon = Quickshell.iconPath(ToplevelManager.activeToplevel.title, true); + } + if (!icon) { + icon = Quickshell.iconPath(ToplevelManager.activeToplevel.title.toLowerCase(), "application-x-executable"); + } + + return icon; } - } - - Connections { - target: ToplevelManager - function onActiveToplevelChanged() { - if (ToplevelManager.activeToplevel?.appId) { - activeWindowWrapper.shouldShow = true - visibilityTimer.restart() - } else { - activeWindowWrapper.shouldShow = false - visibilityTimer.stop() + + Item { + id: activeWindowWrapper + width: parent.width + property int fullHeight: activeWindowTitleContainer.height + property bool shouldShow: false + + Timer { + id: visibilityTimer + interval: 4000 + running: false + onTriggered: { + activeWindowWrapper.shouldShow = false; } } - } - y: shouldShow ? barBackground.height : barBackground.height - fullHeight - height: shouldShow ? fullHeight : 1 - opacity: shouldShow ? 1 : 0 - clip: true - - function getIcon() { - var icon = Quickshell.iconPath(ToplevelManager.activeToplevel.appId.toLowerCase(), true); - if (!icon) { - icon = Quickshell.iconPath(ToplevelManager.activeToplevel.appId, true); - } - if (!icon) { - icon = Quickshell.iconPath(ToplevelManager.activeToplevel.title, true); - } - if (!icon) { - icon = Quickshell.iconPath(ToplevelManager.activeToplevel.title.toLowerCase(), "application-x-executable"); + Connections { + target: ToplevelManager + function onActiveToplevelChanged() { + if (ToplevelManager.activeToplevel?.appId) { + activeWindowWrapper.shouldShow = true; + visibilityTimer.restart(); + } else { + activeWindowWrapper.shouldShow = false; + visibilityTimer.stop(); + } + } } - return icon; - } + y: shouldShow ? 0 : -activeWindowPanel.barHeight + height: shouldShow ? fullHeight : 1 + opacity: shouldShow ? 1 : 0 + clip: true - Behavior on height { - NumberAnimation { - duration: 300 - easing.type: Easing.OutQuad + + + Behavior on height { + NumberAnimation { + duration: 300 + easing.type: Easing.OutQuad + } } - } - Behavior on y { - NumberAnimation { - duration: 300 - easing.type: Easing.OutQuad + Behavior on y { + NumberAnimation { + duration: 300 + easing.type: Easing.OutQuad + } } - } - Behavior on opacity { - NumberAnimation { - duration: 250 - } - } - - Rectangle { - id: activeWindowTitleContainer - color: Theme.backgroundPrimary - bottomLeftRadius: Math.max(0, width / 2) - bottomRightRadius: Math.max(0, width / 2) - - width: Math.min(barBackground.width - 200, activeWindowTitle.implicitWidth + (Settings.showActiveWindowIcon ? 28 : 22)) - height: activeWindowTitle.implicitHeight + 12 - - anchors.top: parent.top - anchors.horizontalCenter: parent.horizontalCenter - - IconImage { - id: icon - width: 12 - height: 12 - anchors.left: parent.left - anchors.leftMargin: 6 - anchors.verticalCenter: parent.verticalCenter - source: ToplevelManager?.activeToplevel ? getIcon() : "" - visible: Settings.showActiveWindowIcon - anchors.verticalCenterOffset: -3 + Behavior on opacity { + NumberAnimation { + duration: 250 + } } - Text { - id: activeWindowTitle - text: ToplevelManager?.activeToplevel?.title && ToplevelManager?.activeToplevel?.title.length > 60 ? ToplevelManager?.activeToplevel?.title.substring(0, 60) + "..." : ToplevelManager?.activeToplevel?.title || "" - font.pixelSize: 12 - color: Theme.textSecondary - elide: Text.ElideRight - anchors.left: icon.right - anchors.leftMargin: Settings.showActiveWindowIcon ? 4 : 6 - anchors.right: parent.right - anchors.rightMargin: 6 - anchors.verticalCenter: parent.verticalCenter - anchors.verticalCenterOffset: -3 - horizontalAlignment: Settings.showActiveWindowIcon ? Text.AlignRight : Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - maximumLineCount: 1 + Rectangle { + id: activeWindowTitleContainer + color: Theme.backgroundPrimary + bottomLeftRadius: Math.max(0, width / 2) + bottomRightRadius: Math.max(0, width / 2) + + width: Math.min(barBackground.width - 200, activeWindowTitle.implicitWidth + (Settings.showActiveWindowIcon ? 28 : 22)) + height: activeWindowTitle.implicitHeight + 12 + + anchors.top: parent.top + anchors.horizontalCenter: parent.horizontalCenter + + IconImage { + id: icon + width: 12 + height: 12 + anchors.left: parent.left + anchors.leftMargin: 6 + anchors.verticalCenter: parent.verticalCenter + source: ToplevelManager?.activeToplevel ? getIcon() : "" + visible: Settings.showActiveWindowIcon + anchors.verticalCenterOffset: -3 + } + + Text { + id: activeWindowTitle + text: ToplevelManager?.activeToplevel?.title && ToplevelManager?.activeToplevel?.title.length > 60 ? ToplevelManager?.activeToplevel?.title.substring(0, 60) + "..." : ToplevelManager?.activeToplevel?.title || "" + font.pixelSize: 12 + color: Theme.textSecondary + elide: Text.ElideRight + anchors.left: icon.right + anchors.leftMargin: Settings.showActiveWindowIcon ? 4 : 6 + anchors.right: parent.right + anchors.rightMargin: 6 + anchors.verticalCenter: parent.verticalCenter + anchors.verticalCenterOffset: -3 + horizontalAlignment: Settings.showActiveWindowIcon ? Text.AlignRight : Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + maximumLineCount: 1 + } } - } - Corners { - id: activeCornerRight - position: "bottomleft" - size: 1.1 - fillColor: Theme.backgroundPrimary - offsetX: activeWindowTitleContainer.x + activeWindowTitleContainer.width - 34 - offsetY: -1 - anchors.top: activeWindowTitleContainer.top - } + Corners { + id: activeCornerRight + position: "bottomleft" + size: 1.1 + fillColor: Theme.backgroundPrimary + offsetX: activeWindowTitleContainer.x + activeWindowTitleContainer.width - 34 + offsetY: -1 + anchors.top: activeWindowTitleContainer.top + } - Corners { - id: activeCornerLeft - position: "bottomright" - size: 1.1 - fillColor: Theme.backgroundPrimary - anchors.top: activeWindowTitleContainer.top - x: activeWindowTitleContainer.x + 34 - width - offsetY: -1 + Corners { + id: activeCornerLeft + position: "bottomright" + size: 1.1 + fillColor: Theme.backgroundPrimary + anchors.top: activeWindowTitleContainer.top + x: activeWindowTitleContainer.x + 34 - width + offsetY: -1 + } } } -