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:/services"
import "root:/config"
import "components"
import "components/workspaces"
import Quickshell
import QtQuick
Variants {
model: Quickshell.screens
Item {
id: root
StyledWindow {
id: win
required property ShellScreen screen
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
name: "bar"
const ty = tray.y;
const th = tray.implicitHeight;
const trayItems = tray.items;
implicitWidth: content.implicitWidth
exclusiveZone: content.implicitWidth
const n = statusIconsInner.network;
const ny = statusIcons.y + statusIconsInner.y + n.y - spacing / 2;
anchors.top: true
anchors.bottom: true
anchors.left: true
const bls = statusIcons.y + statusIconsInner.y + statusIconsInner.bs - spacing / 2;
const ble = statusIcons.y + statusIconsInner.y + statusIconsInner.be + spacing / 2;
Content {
id: content
const b = statusIconsInner.battery;
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 {
anchors.fill: parent
anchors.leftMargin: -(Appearance.padding.small + BorderConfig.thickness)
anchors.rightMargin: -(Appearance.padding.small + BorderConfig.thickness)
onPressed: event => {
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/dashboard" as Dashboard
import "root:/modules/bar/popouts" as BarPopouts
import QtQuick
import QtQuick.Shapes
Shape {
id: root
required property Panels panels
required property Item bar
anchors.fill: parent
anchors.margins: BorderConfig.thickness
anchors.leftMargin: bar.implicitWidth
preferredRendererType: Shape.CurveRenderer
opacity: Colours.transparency.enabled ? Colours.transparency.base : 1

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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