nosignal-shell/modules/drawers/Regions.qml
28allday b1e2bb3bc6 feat(bar): horizontal top bar — Phase A geometry (NoSignal layout)
Convert the bar from a vertical left-edge strip to a horizontal top bar. The
shell had no orientation abstraction, so this flips the geometry across the bar
and the drawer/region/interaction layer:

- Bar.qml: ColumnLayout -> RowLayout; hit-testing (checkPopout/handleWheel),
  scroll halves and popout-center anchoring all keyed off x instead of y;
  first/last padding -> left/right margins.
- BarWrapper.qml: the bar's "thickness" is now its height (clampedHeight/
  contentHeight/implicitHeight); content anchors left/right/top.
- drawers: Exclusions (exclusive zone moved left->top), Panels (content inset
  topMargin = bar height), Regions + ContentWindow (panel->window coordinate
  mapping and the thick border flip left->top), Interactions (bar-region check
  y<barHeight, panel Y-origin uses bar height, scroll passes x, bar drag-reveal
  is vertical).
- widgets: Clock (Row, HH:MM with a colon), StatusIcons (Row), Workspaces +
  Workspace (Row), Tray (Row, expand chevron at the right) — each sizes to the
  bar height instead of width.

Verified live in the dev VM: top bar renders with centered-clock entries, the
exclusion zone keeps windows below the bar, and the dashboard drops down
correctly. Popout fly-outs still anchor sideways (Phase B).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 23:26:55 +01:00

84 lines
2.3 KiB
QML

pragma ComponentBehavior: Bound
import QtQuick
import Quickshell
import Caelestia.Config
import qs.modules.bar as Bar
Region {
id: root
required property Bar.BarWrapper bar
required property Panels panels
required property var win
readonly property real borderThickness: win.contentItem.Config.border.thickness
readonly property real clampedThickness: win.contentItem.Config.border.clampedThickness
x: clampedThickness + win.dragMaskPadding
y: bar.clampedHeight + win.dragMaskPadding
width: win.width - clampedThickness * 2 - win.dragMaskPadding * 2
height: win.height - bar.clampedHeight - clampedThickness - win.dragMaskPadding * 2
intersection: Intersection.Xor
R {
panel: root.panels.dashboard
y: 0
height: panel.height * (1 - root.panels.dashboard.offsetScale) + root.borderThickness
}
R {
panel: root.panels.launcher
y: root.win.height - height
height: panel.height * (1 - root.panels.launcher.offsetScale) + root.borderThickness
}
R {
id: sessionRegion
panel: root.panels.sessionWrapper
x: root.win.width - width
width: panel.width * (1 - root.panels.session.offsetScale) + root.borderThickness + sidebarRegion.width
}
R {
id: sidebarRegion
panel: root.panels.sidebar
x: root.win.width - width
width: panel.width * (1 - root.panels.sidebar.offsetScale) + root.borderThickness
}
R {
panel: root.panels.osdWrapper
x: root.win.width - width
width: panel.width * (1 - root.panels.osd.offsetScale) + root.borderThickness + sessionRegion.width
}
R {
panel: root.panels.notifications
y: 0
height: panel.height + root.borderThickness
}
R {
panel: root.panels.utilities
y: root.win.height - height
height: panel.height * (1 - root.panels.utilities.offsetScale) + root.borderThickness
}
R {
panel: root.panels.popoutsWrapper
width: panel.width * (1 - root.panels.popoutsWrapper.offsetScale)
}
component R: Region {
required property Item panel
x: panel.x + root.borderThickness
y: panel.y + root.bar.implicitHeight
width: panel.width
height: panel.height
intersection: Intersection.Subtract
}
}