internal: move bar to drawer window

Fixes a few bugs, also removes need for hyprland order layerrule
This commit is contained in:
2 * r + 2 * t 2025-06-07 14:47:24 +10:00
parent 687f5a5fd0
commit e3dcdbb67c
11 changed files with 179 additions and 203 deletions

View file

@ -1,30 +1,158 @@
import "root:/widgets" import "root:/widgets"
import "root:/services"
import "root:/config" import "root:/config"
import "components"
import "components/workspaces"
import Quickshell import Quickshell
import QtQuick import QtQuick
Variants { Item {
model: Quickshell.screens id: root
StyledWindow { required property ShellScreen screen
id: win
required property ShellScreen modelData function checkPopout(y: real): void {
const spacing = Appearance.spacing.small;
const aw = activeWindow.child;
const awy = activeWindow.y + aw.y;
screen: modelData const ty = tray.y;
name: "bar" const th = tray.implicitHeight;
const trayItems = tray.items;
implicitWidth: content.implicitWidth const n = statusIconsInner.network;
exclusiveZone: content.implicitWidth const ny = statusIcons.y + statusIconsInner.y + n.y - spacing / 2;
anchors.top: true const bls = statusIcons.y + statusIconsInner.y + statusIconsInner.bs - spacing / 2;
anchors.bottom: true const ble = statusIcons.y + statusIconsInner.y + statusIconsInner.be + spacing / 2;
anchors.left: true
Content { const b = statusIconsInner.battery;
id: content const by = statusIcons.y + statusIconsInner.y + b.y - spacing / 2;
screen: win.modelData if (y >= awy && y <= awy + aw.implicitHeight) {
Popouts.currentName = "activewindow";
Popouts.currentCenter = Qt.binding(() => activeWindow.y + aw.y + aw.implicitHeight / 2);
Popouts.hasCurrent = true;
} else if (y > ty && y < ty + th) {
const index = Math.floor(((y - ty) / th) * trayItems.count);
const item = trayItems.itemAt(index);
Popouts.currentName = `traymenu${index}`;
Popouts.currentCenter = Qt.binding(() => tray.y + item.y + item.implicitHeight / 2);
Popouts.hasCurrent = true;
} else if (y >= ny && y <= ny + n.implicitHeight + spacing) {
Popouts.currentName = "network";
Popouts.currentCenter = Qt.binding(() => statusIcons.y + statusIconsInner.y + n.y + n.implicitHeight / 2);
Popouts.hasCurrent = true;
} else if (y >= bls && y <= ble) {
Popouts.currentName = "bluetooth";
Popouts.currentCenter = Qt.binding(() => statusIcons.y + statusIconsInner.y + statusIconsInner.bs + (statusIconsInner.be - statusIconsInner.bs) / 2);
Popouts.hasCurrent = true;
} else if (y >= by && y <= by + b.implicitHeight + spacing) {
Popouts.currentName = "battery";
Popouts.currentCenter = Qt.binding(() => statusIcons.y + statusIconsInner.y + b.y + b.implicitHeight / 2);
Popouts.hasCurrent = true;
} else {
Popouts.hasCurrent = false;
}
}
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
implicitWidth: child.implicitWidth + BorderConfig.thickness * 2
Item {
id: child
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
implicitWidth: Math.max(osIcon.implicitWidth, workspaces.implicitWidth, activeWindow.implicitWidth, tray.implicitWidth, clock.implicitWidth, statusIcons.implicitWidth, power.implicitWidth)
OsIcon {
id: osIcon
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: Appearance.padding.large
}
StyledClippingRect {
id: workspaces
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: osIcon.bottom
anchors.topMargin: Appearance.spacing.normal
radius: Appearance.rounding.full
color: Colours.palette.m3surfaceContainer
implicitWidth: workspacesInner.implicitWidth + Appearance.padding.small * 2
implicitHeight: workspacesInner.implicitHeight + Appearance.padding.small * 2
Workspaces {
id: workspacesInner
anchors.centerIn: parent
}
}
ActiveWindow {
id: activeWindow
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: workspaces.bottom
anchors.bottom: tray.top
anchors.margins: Appearance.spacing.large
monitor: Brightness.getMonitorForScreen(root.screen)
}
Tray {
id: tray
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: clock.top
anchors.bottomMargin: Appearance.spacing.larger
}
Clock {
id: clock
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: statusIcons.top
anchors.bottomMargin: Appearance.spacing.normal
}
StyledRect {
id: statusIcons
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: power.top
anchors.bottomMargin: Appearance.spacing.normal
radius: Appearance.rounding.full
color: Colours.palette.m3surfaceContainer
implicitHeight: statusIconsInner.implicitHeight + Appearance.padding.normal * 2
StatusIcons {
id: statusIconsInner
anchors.centerIn: parent
}
}
Power {
id: power
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: Appearance.padding.large
} }
} }
} }

View file

@ -1,174 +0,0 @@
import "root:/widgets"
import "root:/services"
import "root:/config"
import "components"
import "components/workspaces"
import Quickshell
import QtQuick
StyledRect {
id: root
required property ShellScreen screen
function checkPopout(y: real): var {
const spacing = Appearance.spacing.small;
const aw = activeWindow.child;
const awy = activeWindow.y + aw.y;
const ty = tray.y;
const th = tray.implicitHeight;
const trayItems = tray.items;
const n = statusIconsInner.network;
const ny = statusIcons.y + statusIconsInner.y + n.y - spacing / 2;
const bls = statusIcons.y + statusIconsInner.y + statusIconsInner.bs - spacing / 2;
const ble = statusIcons.y + statusIconsInner.y + statusIconsInner.be + spacing / 2;
const b = statusIconsInner.battery;
const by = statusIcons.y + statusIconsInner.y + b.y - spacing / 2;
if (y >= awy && y <= awy + aw.implicitHeight) {
Popouts.currentName = "activewindow";
Popouts.currentCenter = Qt.binding(() => activeWindow.y + aw.y + aw.implicitHeight / 2);
Popouts.hasCurrent = true;
} else if (y > ty && y < ty + th) {
const index = Math.floor(((y - ty) / th) * trayItems.count);
const item = trayItems.itemAt(index);
Popouts.currentName = `traymenu${index}`;
Popouts.currentCenter = Qt.binding(() => tray.y + item.y + item.implicitHeight / 2);
Popouts.hasCurrent = true;
} else if (y >= ny && y <= ny + n.implicitHeight + spacing) {
Popouts.currentName = "network";
Popouts.currentCenter = Qt.binding(() => statusIcons.y + statusIconsInner.y + n.y + n.implicitHeight / 2);
Popouts.hasCurrent = true;
} else if (y >= bls && y <= ble) {
Popouts.currentName = "bluetooth";
Popouts.currentCenter = Qt.binding(() => statusIcons.y + statusIconsInner.y + statusIconsInner.bs + (statusIconsInner.be - statusIconsInner.bs) / 2);
Popouts.hasCurrent = true;
} else if (y >= by && y <= by + b.implicitHeight + spacing) {
Popouts.currentName = "battery";
Popouts.currentCenter = Qt.binding(() => statusIcons.y + statusIconsInner.y + b.y + b.implicitHeight / 2);
Popouts.hasCurrent = true;
} else {
Popouts.hasCurrent = false;
}
}
anchors.top: parent.top
anchors.bottom: parent.bottom
implicitWidth: child.implicitWidth + BorderConfig.thickness
color: BorderConfig.colour
Component.onCompleted: Visibilities.bars[screen] = this
MouseArea {
anchors.fill: parent
hoverEnabled: true
onPositionChanged: event => root.checkPopout(event.y)
onContainsMouseChanged: {
if (!containsMouse)
Popouts.hasCurrent = false;
}
}
Item {
id: child
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
implicitWidth: Math.max(osIcon.implicitWidth, workspaces.implicitWidth, activeWindow.implicitWidth, tray.implicitWidth, clock.implicitWidth, statusIcons.implicitWidth, power.implicitWidth)
OsIcon {
id: osIcon
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: Appearance.padding.large
}
StyledClippingRect {
id: workspaces
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: osIcon.bottom
anchors.topMargin: Appearance.spacing.normal
radius: Appearance.rounding.full
color: Colours.palette.m3surfaceContainer
implicitWidth: workspacesInner.implicitWidth + Appearance.spacing.small
implicitHeight: workspacesInner.implicitHeight + Appearance.spacing.small * 2
Workspaces {
id: workspacesInner
anchors.centerIn: parent
}
}
ActiveWindow {
id: activeWindow
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: workspaces.bottom
anchors.bottom: tray.top
anchors.margins: Appearance.spacing.large
monitor: Brightness.getMonitorForScreen(root.screen)
}
Tray {
id: tray
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: clock.top
anchors.bottomMargin: Appearance.spacing.larger
}
Clock {
id: clock
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: statusIcons.top
anchors.bottomMargin: Appearance.spacing.normal
}
StyledRect {
id: statusIcons
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: power.top
anchors.bottomMargin: Appearance.spacing.normal
radius: Appearance.rounding.full
color: Colours.palette.m3surfaceContainer
implicitHeight: statusIconsInner.implicitHeight + Appearance.padding.normal * 2
StatusIcons {
id: statusIconsInner
anchors.centerIn: parent
}
}
Power {
id: power
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: Appearance.padding.large
}
}
}

View file

@ -65,6 +65,8 @@ Item {
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: -(Appearance.padding.small + BorderConfig.thickness)
anchors.rightMargin: -(Appearance.padding.small + BorderConfig.thickness)
onPressed: event => { onPressed: event => {
const ws = layout.childAt(event.x, event.y).index + root.groupOffset + 1; const ws = layout.childAt(event.x, event.y).index + root.groupOffset + 1;

View file

@ -6,15 +6,18 @@ import "root:/modules/session" as Session
import "root:/modules/launcher" as Launcher import "root:/modules/launcher" as Launcher
import "root:/modules/dashboard" as Dashboard import "root:/modules/dashboard" as Dashboard
import "root:/modules/bar/popouts" as BarPopouts import "root:/modules/bar/popouts" as BarPopouts
import QtQuick
import QtQuick.Shapes import QtQuick.Shapes
Shape { Shape {
id: root id: root
required property Panels panels required property Panels panels
required property Item bar
anchors.fill: parent anchors.fill: parent
anchors.margins: BorderConfig.thickness anchors.margins: BorderConfig.thickness
anchors.leftMargin: bar.implicitWidth
preferredRendererType: Shape.CurveRenderer preferredRendererType: Shape.CurveRenderer
opacity: Colours.transparency.enabled ? Colours.transparency.base : 1 opacity: Colours.transparency.enabled ? Colours.transparency.base : 1

View file

@ -8,6 +8,8 @@ import QtQuick.Effects
Item { Item {
id: root id: root
required property Item bar
anchors.fill: parent anchors.fill: parent
StyledRect { StyledRect {
@ -28,6 +30,7 @@ Item {
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
anchors.margins: BorderConfig.thickness anchors.margins: BorderConfig.thickness
anchors.leftMargin: root.bar.implicitWidth
radius: BorderConfig.rounding radius: BorderConfig.rounding
} }
} }

View file

@ -3,6 +3,7 @@ pragma ComponentBehavior: Bound
import "root:/widgets" import "root:/widgets"
import "root:/services" import "root:/services"
import "root:/config" import "root:/config"
import "root:/modules/bar"
import Quickshell import Quickshell
import Quickshell.Wayland import Quickshell.Wayland
import Quickshell.Hyprland import Quickshell.Hyprland
@ -18,6 +19,7 @@ Variants {
Exclusions { Exclusions {
screen: scope.modelData screen: scope.modelData
bar: bar
} }
StyledWindow { StyledWindow {
@ -29,9 +31,9 @@ Variants {
WlrLayershell.keyboardFocus: visibilities.launcher || visibilities.session ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None WlrLayershell.keyboardFocus: visibilities.launcher || visibilities.session ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None
mask: Region { mask: Region {
x: BorderConfig.thickness x: bar.implicitWidth
y: BorderConfig.thickness y: BorderConfig.thickness
width: win.width - BorderConfig.thickness * 2 width: win.width - bar.implicitWidth - BorderConfig.thickness
height: win.height - BorderConfig.thickness * 2 height: win.height - BorderConfig.thickness * 2
intersection: Intersection.Xor intersection: Intersection.Xor
@ -43,8 +45,6 @@ Variants {
anchors.left: true anchors.left: true
anchors.right: true anchors.right: true
margins.left: Visibilities.bars[screen]?.implicitWidth ?? 0
Variants { Variants {
id: regions id: regions
@ -53,7 +53,7 @@ Variants {
Region { Region {
required property Item modelData required property Item modelData
x: modelData.x + BorderConfig.thickness x: modelData.x + bar.implicitWidth
y: modelData.y + BorderConfig.thickness y: modelData.y + BorderConfig.thickness
width: modelData.width width: modelData.width
height: modelData.height height: modelData.height
@ -90,10 +90,13 @@ Variants {
anchors.fill: parent anchors.fill: parent
visible: false visible: false
Border {} Border {
bar: bar
}
Backgrounds { Backgrounds {
panels: panels panels: panels
bar: bar
} }
} }
@ -116,14 +119,22 @@ Variants {
screen: scope.modelData screen: scope.modelData
visibilities: visibilities visibilities: visibilities
panels: panels panels: panels
bar: bar
Panels { Panels {
id: panels id: panels
screen: scope.modelData screen: scope.modelData
visibilities: visibilities visibilities: visibilities
bar: bar
} }
} }
Bar {
id: bar
screen: scope.modelData
}
} }
} }
} }

View file

@ -3,14 +3,17 @@ pragma ComponentBehavior: Bound
import "root:/widgets" import "root:/widgets"
import "root:/config" import "root:/config"
import Quickshell import Quickshell
import QtQuick
Scope { Scope {
id: root id: root
required property ShellScreen screen required property ShellScreen screen
required property Item bar
ExclusionZone { ExclusionZone {
anchors.left: true anchors.left: true
exclusiveZone: root.bar.implicitWidth
} }
ExclusionZone { ExclusionZone {

View file

@ -10,6 +10,7 @@ MouseArea {
required property ShellScreen screen required property ShellScreen screen
required property PersistentProperties visibilities required property PersistentProperties visibilities
required property Panels panels required property Panels panels
required property Item bar
property bool osdHovered property bool osdHovered
property point dragStart property point dragStart
@ -20,11 +21,11 @@ MouseArea {
} }
function inRightPanel(panel: Item, x: real, y: real): bool { function inRightPanel(panel: Item, x: real, y: real): bool {
return x > BorderConfig.thickness + panel.x && withinPanelHeight(panel, x, y); return x > bar.implicitWidth + panel.x && withinPanelHeight(panel, x, y);
} }
function inTopPanel(panel: Item, x: real, y: real): bool { function inTopPanel(panel: Item, x: real, y: real): bool {
const panelX = BorderConfig.thickness + panel.x; const panelX = bar.implicitWidth + panel.x;
return y < BorderConfig.thickness + panel.y + panel.height && x >= panelX - BorderConfig.rounding && x <= panelX + panel.width + BorderConfig.rounding; return y < BorderConfig.thickness + panel.y + panel.height && x >= panelX - BorderConfig.rounding && x <= panelX + panel.width + BorderConfig.rounding;
} }
@ -61,10 +62,10 @@ MouseArea {
// Show popouts on hover // Show popouts on hover
const popout = panels.popouts; const popout = panels.popouts;
if (x < BorderConfig.thickness + popout.width) { if (x < bar.implicitWidth + popout.width) {
if (x < BorderConfig.thickness) if (x < bar.implicitWidth)
// Handle like part of bar // Handle like part of bar
Visibilities.bars[screen].checkPopout(y); bar.checkPopout(y);
else else
// Keep on hover // Keep on hover
Popouts.hasCurrent = withinPanelHeight(popout, x, y); Popouts.hasCurrent = withinPanelHeight(popout, x, y);

View file

@ -14,6 +14,7 @@ Item {
required property ShellScreen screen required property ShellScreen screen
required property PersistentProperties visibilities required property PersistentProperties visibilities
required property Item bar
readonly property Osd.Wrapper osd: osd readonly property Osd.Wrapper osd: osd
readonly property Notifications.Wrapper notifications: notifications readonly property Notifications.Wrapper notifications: notifications
@ -24,6 +25,7 @@ Item {
anchors.fill: parent anchors.fill: parent
anchors.margins: BorderConfig.thickness anchors.margins: BorderConfig.thickness
anchors.leftMargin: bar.implicitWidth
Component.onCompleted: Visibilities.panels[screen] = this Component.onCompleted: Visibilities.panels[screen] = this

View file

@ -4,7 +4,6 @@ import Quickshell
Singleton { Singleton {
property var screens: ({}) property var screens: ({})
property var bars: ({})
property var panels: ({}) property var panels: ({})
function getForActive(): PersistentProperties { function getForActive(): PersistentProperties {

View file

@ -1,11 +1,9 @@
import "modules" import "modules"
import "modules/bar"
import "modules/drawers" import "modules/drawers"
import "modules/background" import "modules/background"
import Quickshell import Quickshell
ShellRoot { ShellRoot {
Bar {}
Background {} Background {}
Drawers {} Drawers {}