Merge branch 'main' into feat/fullscreen-reveal-bar
C++ / fmt (pull_request) Successful in 5s
JS/TS / fmt (pull_request) Successful in 15s
JS/TS / lint (pull_request) Successful in 19s
Python / fmt (pull_request) Successful in 31s
Python / lint (pull_request) Successful in 34s
Python / test (pull_request) Successful in 56s
Python / typecheck (pull_request) Successful in 1m23s
Rust / fmt (pull_request) Successful in 41s
C++ / build (pull_request) Successful in 2m35s
Rust / build (pull_request) Successful in 1m49s
Rust / clippy (pull_request) Successful in 59s
Python / buildcheck (pull_request) Successful in 2m19s
C++ / clang-tidy (pull_request) Successful in 6m2s

This commit is contained in:
2026-08-16 11:20:59 +02:00
52 changed files with 1174 additions and 859 deletions
+41 -22
View File
@@ -3,16 +3,15 @@ pragma ComponentBehavior: Bound
import Quickshell
import QtQuick
import QtQuick.Layouts
import qs.Modules
import ZShell.Config
import qs.Modules.SysTray
import qs.Modules.Network
import qs.Modules.Updates
import qs.Modules.Bar.Components
import qs.Modules.Bar.Popouts
RowLayout {
GridLayout {
id: root
required property bool fullscreen
required property bool horizontal
required property bool isHovered
required property Wrapper popouts
required property ClipWrapper popoutsWrapper
@@ -20,8 +19,13 @@ RowLayout {
readonly property int vPadding: 6
required property PersistentProperties visibilities
function checkPopout(x: real): void {
const ch = childAt(x, height / 2) as EntryWrapper;
function axisCenterOf(item: Item): real {
const c = item.mapToItem(root, item.implicitWidth / 2, item.implicitHeight / 2);
return horizontal ? c.x : c.y;
}
function checkPopout(pos: real): void {
const ch = (horizontal ? childAt(pos, height / 2) : childAt(width / 2, pos)) as EntryWrapper;
const id = ch?.entryId;
if (!ch || id === undefined) {
@@ -35,26 +39,21 @@ RowLayout {
if (id === "statusIcons" && Config.bar.popouts.statusIcons) {
const items = (ch.item as StatusIcons).items;
const localX = mapToItem(items, x, 0).x;
const icon = items.childAt(localX, items.height / 2);
const icon = horizontal ? items.childAt(mapToItem(items, pos, 0).x, items.height / 2) : items.childAt(items.width / 2, mapToItem(items, 0, pos).y);
if (icon) {
popouts.currentName = icon.name;
popouts.currentCenter = Qt.binding(() => icon.mapToItem(root, icon.implicitWidth / 2, 0).x);
popouts.currentCenter = Qt.binding(() => axisCenterOf(icon));
popouts.hasCurrent = true;
}
} else if (id === "tray" && Config.bar.popouts.tray && Config.bar.tray.showOnHover) {
const tray = ch.item as TrayIcons;
const layout = tray.layout;
const localX = mapToItem(layout, x, 0).x;
const trayItem = layout.childAt(localX, layout.height / 2);
const trayItem = horizontal ? layout.childAt(mapToItem(layout, pos, 0).x, layout.height / 2) : layout.childAt(tray.width / 2, mapToItem(layout, 0, pos).y);
if (trayItem) {
const idx = trayItem.index;
popouts.currentName = `traymenu${idx}`;
popouts.currentCenter = Qt.binding(() => {
const it = tray.items.itemAt(idx);
return it ? it.mapToItem(root, it.implicitWidth / 2, 0).x : popouts.currentCenter;
});
popouts.currentCenter = Qt.binding(() => axisCenterOf(trayItem));
popouts.hasCurrent = true;
}
@@ -64,12 +63,19 @@ RowLayout {
if (id === "updates") {
popouts.currentName = "updates";
popouts.currentCenter = Qt.binding(() => ch.item.mapToItem(root, (ch.item as Item).implicitWidth / 2, 0).x);
popouts.currentCenter = Qt.binding(() => axisCenterOf(ch.item as Item));
popouts.hasCurrent = true;
}
}
spacing: Tokens.spacing.small
function entryAt(pos: real): string {
const ch = (horizontal ? childAt(pos, height / 2) : childAt(width / 2, pos)) as EntryWrapper;
return ch?.entryId ?? "";
}
columnSpacing: Tokens.spacing.small
columns: horizontal ? -1 : 1
rowSpacing: Tokens.spacing.small
Repeater {
id: repeater
@@ -86,6 +92,7 @@ RowLayout {
delegate: EntryWrapper {
HyprsunsetWidget {
horizontal: root.horizontal
visible: !root.fullscreen || root.isHovered
}
}
@@ -95,7 +102,8 @@ RowLayout {
roleValue: "spacer"
delegate: EntryWrapper {
Layout.fillWidth: true
Layout.fillHeight: !root.horizontal
Layout.fillWidth: root.horizontal
}
}
@@ -104,6 +112,7 @@ RowLayout {
delegate: EntryWrapper {
Workspaces {
horizontal: root.horizontal
screen: root.screen
visible: !root.fullscreen || root.isHovered
}
@@ -115,6 +124,7 @@ RowLayout {
delegate: EntryWrapper {
TrayIcons {
horizontal: root.horizontal
loader: root
popouts: root.popouts
visible: !root.fullscreen || root.isHovered
@@ -127,6 +137,7 @@ RowLayout {
delegate: EntryWrapper {
StatusIcons {
horizontal: root.horizontal
}
}
}
@@ -136,6 +147,7 @@ RowLayout {
delegate: EntryWrapper {
Resources {
horizontal: root.horizontal
visibilities: root.visibilities
visible: !root.fullscreen || root.isHovered
}
@@ -147,6 +159,7 @@ RowLayout {
delegate: EntryWrapper {
UpdatesWidget {
horizontal: root.horizontal
visible: !root.fullscreen || root.isHovered
}
}
@@ -157,6 +170,7 @@ RowLayout {
delegate: EntryWrapper {
NotifBell {
horizontal: root.horizontal
popouts: root.popouts
visibilities: root.visibilities
visible: !root.fullscreen || root.isHovered
@@ -169,6 +183,7 @@ RowLayout {
delegate: EntryWrapper {
Clock {
horizontal: root.horizontal
loader: root
popouts: root.popouts
visibilities: root.visibilities
@@ -183,6 +198,7 @@ RowLayout {
delegate: EntryWrapper {
WindowTitle {
bar: root
horizontal: root.horizontal
visible: !root.fullscreen || root.isHovered
}
}
@@ -202,6 +218,7 @@ RowLayout {
delegate: EntryWrapper {
MediaWidget {
horizontal: root.horizontal
visible: !root.fullscreen || root.isHovered
}
}
@@ -215,9 +232,11 @@ RowLayout {
default property Item item
required property var modelData
Layout.alignment: Qt.AlignVCenter
Layout.leftMargin: index === 0 ? root.vPadding : (entryId === "statusIcons") ? -root.spacing + Tokens.spacing.extraSmall : 0
Layout.rightMargin: index === repeater.count - 1 ? root.vPadding : 0
Layout.alignment: root.horizontal ? Qt.AlignVCenter : Qt.AlignHCenter
Layout.bottomMargin: !root.horizontal && index === repeater.count - 1 ? root.vPadding : 0
Layout.leftMargin: root.horizontal && index === 0 ? root.vPadding : (entryId === "statusIcons" && root.horizontal) ? -root.rowSpacing + Tokens.spacing.extraSmall : 0
Layout.rightMargin: root.horizontal && index === repeater.count - 1 ? root.vPadding : 0
Layout.topMargin: !root.horizontal && index === 0 ? root.vPadding : (entryId === "statusIcons" && !root.horizontal) ? -root.columnSpacing + Tokens.spacing.extraSmall : 0
children: item
implicitHeight: item?.implicitHeight ?? 0
implicitWidth: item?.implicitWidth ?? 0