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>
This commit is contained in:
parent
152923f5d8
commit
b1e2bb3bc6
12 changed files with 131 additions and 117 deletions
|
|
@ -10,14 +10,18 @@ import Caelestia.Config
|
|||
import qs.components
|
||||
import qs.services
|
||||
|
||||
ColumnLayout {
|
||||
// NoSignal: horizontal top bar. The widgets flow left->right in a RowLayout and
|
||||
// the bar's "thickness" is its HEIGHT; hit-testing / scroll / popout anchoring all
|
||||
// key off the x-axis (the position along the bar). Upstream caelestia is a
|
||||
// vertical left-edge bar — this is the NoSignal layout fork (Phase 3).
|
||||
RowLayout {
|
||||
id: root
|
||||
|
||||
required property ShellScreen screen
|
||||
required property DrawerVisibilities visibilities
|
||||
required property BarPopouts.Wrapper popouts
|
||||
required property bool fullscreen
|
||||
readonly property int vPadding: Tokens.padding.large
|
||||
readonly property int hPadding: Tokens.padding.large
|
||||
|
||||
function closeTray(): void {
|
||||
if (!Config.bar.tray.compact)
|
||||
|
|
@ -31,8 +35,8 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
|
||||
function checkPopout(y: real): void {
|
||||
const ch = childAt(width / 2, y) as WrappedLoader;
|
||||
function checkPopout(x: real): void {
|
||||
const ch = childAt(x, height / 2) as WrappedLoader;
|
||||
|
||||
if (ch?.id !== "tray")
|
||||
closeTray();
|
||||
|
|
@ -43,24 +47,24 @@ ColumnLayout {
|
|||
}
|
||||
|
||||
const id = ch.id;
|
||||
const top = ch.y;
|
||||
const left = ch.x;
|
||||
|
||||
if (id === "statusIcons" && Config.bar.popouts.statusIcons) {
|
||||
const items = (ch.item as StatusIcons).items;
|
||||
const icon = items.childAt(items.width / 2, mapToItem(items, 0, y).y);
|
||||
const icon = items.childAt(mapToItem(items, x, 0).x, items.height / 2);
|
||||
if (icon) {
|
||||
popouts.currentName = icon.name;
|
||||
popouts.currentCenter = Qt.binding(() => icon.mapToItem(root, 0, icon.implicitHeight / 2).y);
|
||||
popouts.currentCenter = Qt.binding(() => icon.mapToItem(root, icon.implicitWidth / 2, 0).x);
|
||||
popouts.hasCurrent = true;
|
||||
}
|
||||
} else if (id === "tray" && Config.bar.popouts.tray) {
|
||||
const tray = ch.item as Tray;
|
||||
if (!Config.bar.tray.compact || (tray.expanded && !tray.expandIcon.contains(mapToItem(tray.expandIcon, tray.implicitWidth / 2, y)))) {
|
||||
const index = Math.floor(((y - top - tray.padding * 2 + tray.spacing) / tray.layout.implicitHeight) * tray.items.count);
|
||||
if (!Config.bar.tray.compact || (tray.expanded && !tray.expandIcon.contains(mapToItem(tray.expandIcon, x, tray.implicitHeight / 2)))) {
|
||||
const index = Math.floor(((x - left - tray.padding * 2 + tray.spacing) / tray.layout.implicitWidth) * tray.items.count);
|
||||
const trayItem = tray.items.itemAt(index);
|
||||
if (trayItem) {
|
||||
popouts.currentName = `traymenu${index}`;
|
||||
popouts.currentCenter = Qt.binding(() => trayItem.mapToItem(root, 0, trayItem.implicitHeight / 2).y);
|
||||
popouts.currentCenter = Qt.binding(() => trayItem.mapToItem(root, trayItem.implicitWidth / 2, 0).x);
|
||||
popouts.hasCurrent = true;
|
||||
} else {
|
||||
popouts.hasCurrent = false;
|
||||
|
|
@ -71,13 +75,13 @@ ColumnLayout {
|
|||
}
|
||||
} else if (id === "activeWindow" && Config.bar.popouts.activeWindow && Config.bar.activeWindow.showOnHover) {
|
||||
popouts.currentName = id.toLowerCase();
|
||||
popouts.currentCenter = (ch.item as Item).mapToItem(root, 0, (ch.item as Item).implicitHeight / 2).y ?? 0;
|
||||
popouts.currentCenter = (ch.item as Item).mapToItem(root, (ch.item as Item).implicitWidth / 2, 0).x ?? 0;
|
||||
popouts.hasCurrent = true;
|
||||
}
|
||||
}
|
||||
|
||||
function handleWheel(y: real, angleDelta: point): void {
|
||||
const ch = childAt(width / 2, y) as WrappedLoader;
|
||||
function handleWheel(x: real, angleDelta: point): void {
|
||||
const ch = childAt(x, height / 2) as WrappedLoader;
|
||||
if (ch?.id === "workspaces" && Config.bar.scrollActions.workspaces) {
|
||||
// Workspace scroll
|
||||
const mon = (GlobalConfig.bar.workspaces.perMonitorWorkspaces ? Hypr.monitorFor(screen) : Hypr.focusedMonitor);
|
||||
|
|
@ -86,14 +90,14 @@ ColumnLayout {
|
|||
Hypr.dispatch(`togglespecialworkspace ${specialWs.slice(8)}`);
|
||||
else if (angleDelta.y < 0 || (GlobalConfig.bar.workspaces.perMonitorWorkspaces ? mon.activeWorkspace?.id : Hypr.activeWsId) > 1)
|
||||
Hypr.dispatch(`workspace r${angleDelta.y > 0 ? "-" : "+"}1`);
|
||||
} else if (y < screen.height / 2 && Config.bar.scrollActions.volume) {
|
||||
// Volume scroll on top half
|
||||
} else if (x < screen.width / 2 && Config.bar.scrollActions.volume) {
|
||||
// Volume scroll on left half
|
||||
if (angleDelta.y > 0)
|
||||
Audio.incrementVolume();
|
||||
else if (angleDelta.y < 0)
|
||||
Audio.decrementVolume();
|
||||
} else if (Config.bar.scrollActions.brightness) {
|
||||
// Brightness scroll on bottom half
|
||||
// Brightness scroll on right half
|
||||
const monitor = Brightness.getMonitorForScreen(screen);
|
||||
if (angleDelta.y > 0)
|
||||
monitor.setBrightness(monitor.brightness + GlobalConfig.services.brightnessIncrement);
|
||||
|
|
@ -115,7 +119,7 @@ ColumnLayout {
|
|||
DelegateChoice {
|
||||
roleValue: "spacer"
|
||||
delegate: WrappedLoader {
|
||||
Layout.fillHeight: enabled
|
||||
Layout.fillWidth: enabled
|
||||
}
|
||||
}
|
||||
DelegateChoice {
|
||||
|
|
@ -201,11 +205,11 @@ ColumnLayout {
|
|||
}
|
||||
|
||||
asynchronous: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
// Cursed ahh thing to add padding to first and last enabled components
|
||||
Layout.topMargin: findFirstEnabled() === this ? root.vPadding : 0
|
||||
Layout.bottomMargin: findLastEnabled() === this ? root.vPadding : 0
|
||||
Layout.leftMargin: findFirstEnabled() === this ? root.hPadding : 0
|
||||
Layout.rightMargin: findLastEnabled() === this ? root.hPadding : 0
|
||||
|
||||
visible: enabled
|
||||
active: enabled
|
||||
|
|
|
|||
|
|
@ -17,10 +17,13 @@ Item {
|
|||
|
||||
readonly property bool disabled: Strings.testRegexList(Config.bar.excludedScreens, screen.name)
|
||||
|
||||
readonly property int clampedWidth: Math.max(Config.border.minThickness, implicitWidth)
|
||||
// NoSignal horizontal top bar: the bar's "thickness" is its HEIGHT (was width
|
||||
// for the upstream vertical left-edge bar). clampedHeight/contentHeight and
|
||||
// implicitHeight carry the thickness; the wrapper fills the screen width.
|
||||
readonly property int clampedHeight: Math.max(Config.border.minThickness, implicitHeight)
|
||||
readonly property int padding: Math.max(Tokens.padding.small, Config.border.thickness)
|
||||
readonly property int contentWidth: Tokens.sizes.bar.innerWidth + padding * 2
|
||||
readonly property int exclusiveZone: !disabled && (Config.bar.persistent || visibilities.bar) ? contentWidth : Config.border.thickness
|
||||
readonly property int contentHeight: Tokens.sizes.bar.innerWidth + padding * 2
|
||||
readonly property int exclusiveZone: !disabled && (Config.bar.persistent || visibilities.bar) ? contentHeight : Config.border.thickness
|
||||
readonly property bool shouldBeVisible: !fullscreen && !disabled && (Config.bar.persistent || visibilities.bar || isHovered)
|
||||
property bool isHovered
|
||||
|
||||
|
|
@ -28,24 +31,24 @@ Item {
|
|||
(content.item as Bar)?.closeTray();
|
||||
}
|
||||
|
||||
function checkPopout(y: real): void {
|
||||
(content.item as Bar)?.checkPopout(y);
|
||||
function checkPopout(x: real): void {
|
||||
(content.item as Bar)?.checkPopout(x);
|
||||
}
|
||||
|
||||
function handleWheel(y: real, angleDelta: point): void {
|
||||
(content.item as Bar)?.handleWheel(y, angleDelta);
|
||||
function handleWheel(x: real, angleDelta: point): void {
|
||||
(content.item as Bar)?.handleWheel(x, angleDelta);
|
||||
}
|
||||
|
||||
clip: true
|
||||
visible: width > Config.border.thickness
|
||||
implicitWidth: fullscreen ? 0 : Config.border.thickness
|
||||
visible: height > Config.border.thickness
|
||||
implicitHeight: fullscreen ? 0 : Config.border.thickness
|
||||
|
||||
states: State {
|
||||
name: "visible"
|
||||
when: root.shouldBeVisible
|
||||
|
||||
PropertyChanges {
|
||||
root.implicitWidth: root.contentWidth
|
||||
root.implicitHeight: root.contentHeight
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -56,7 +59,7 @@ Item {
|
|||
|
||||
Anim {
|
||||
target: root
|
||||
property: "implicitWidth"
|
||||
property: "implicitHeight"
|
||||
}
|
||||
},
|
||||
Transition {
|
||||
|
|
@ -65,7 +68,7 @@ Item {
|
|||
|
||||
Anim {
|
||||
target: root
|
||||
property: "implicitWidth"
|
||||
property: "implicitHeight"
|
||||
type: Anim.Emphasized
|
||||
}
|
||||
}
|
||||
|
|
@ -74,14 +77,14 @@ Item {
|
|||
Loader {
|
||||
id: content
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
|
||||
active: root.shouldBeVisible
|
||||
|
||||
sourceComponent: Bar {
|
||||
width: root.contentWidth
|
||||
height: root.contentHeight
|
||||
screen: root.screen
|
||||
visibilities: root.visibilities
|
||||
popouts: root.popouts // qmllint disable incompatible-type
|
||||
|
|
|
|||
|
|
@ -13,20 +13,20 @@ StyledRect {
|
|||
readonly property int padding: Config.bar.clock.background ? Tokens.padding.medium : Tokens.padding.extraSmall
|
||||
readonly property var font: Tokens.font.body.builders.small.scale(1.1)
|
||||
|
||||
implicitWidth: Tokens.sizes.bar.innerWidth
|
||||
implicitHeight: layout.implicitHeight + root.padding * 2
|
||||
implicitHeight: Tokens.sizes.bar.innerWidth
|
||||
implicitWidth: layout.implicitWidth + root.padding * 2
|
||||
|
||||
color: Qt.alpha(Colours.tPalette.m3surfaceContainer, Config.bar.clock.background ? Colours.tPalette.m3surfaceContainer.a : 0)
|
||||
radius: Tokens.rounding.full
|
||||
|
||||
ColumnLayout {
|
||||
RowLayout {
|
||||
id: layout
|
||||
|
||||
anchors.centerIn: parent
|
||||
spacing: Tokens.spacing.small
|
||||
|
||||
Loader {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
asynchronous: true
|
||||
active: Config.bar.clock.showIcon
|
||||
visible: active
|
||||
|
|
@ -38,24 +38,26 @@ StyledRect {
|
|||
}
|
||||
|
||||
StyledText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
visible: Config.bar.clock.showDate
|
||||
|
||||
horizontalAlignment: StyledText.AlignHCenter
|
||||
text: Time.format("ddd\nd")
|
||||
text: Time.format("ddd d")
|
||||
font: Tokens.font.body.small
|
||||
color: root.colour
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Layout.topMargin: root.padding
|
||||
Layout.bottomMargin: root.padding
|
||||
visible: Config.bar.clock.showDate
|
||||
implicitHeight: 1
|
||||
implicitWidth: 1
|
||||
color: Colours.palette.m3outlineVariant
|
||||
}
|
||||
|
||||
StyledText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: Time.hourStr
|
||||
font: {
|
||||
const scale = text === "11" ? 1.15 : Math.min(1.05, Math.max(hourMetrics.width, minMetrics.width) / hourMetrics.width);
|
||||
|
|
@ -72,8 +74,14 @@ StyledRect {
|
|||
}
|
||||
|
||||
StyledText {
|
||||
Layout.topMargin: -parent.spacing - 4
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: ":"
|
||||
font: root.font.build()
|
||||
color: root.colour
|
||||
}
|
||||
|
||||
StyledText {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: Time.minuteStr
|
||||
font: {
|
||||
const scale = text === "11" ? 1.15 : Math.min(1.05, Math.max(hourMetrics.width, minMetrics.width) / minMetrics.width);
|
||||
|
|
@ -90,8 +98,7 @@ StyledRect {
|
|||
}
|
||||
|
||||
Loader {
|
||||
Layout.topMargin: -parent.spacing - 4
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
asynchronous: true
|
||||
active: GlobalConfig.services.useTwelveHourClock
|
||||
visible: active
|
||||
|
|
|
|||
|
|
@ -20,16 +20,13 @@ StyledRect {
|
|||
radius: Tokens.rounding.full
|
||||
|
||||
clip: true
|
||||
implicitWidth: Tokens.sizes.bar.innerWidth
|
||||
implicitHeight: iconColumn.implicitHeight + Tokens.padding.medium * 2 - (Config.bar.status.showLockStatus && !Hypr.capsLock && !Hypr.numLock ? iconColumn.spacing : 0)
|
||||
implicitHeight: Tokens.sizes.bar.innerWidth
|
||||
implicitWidth: iconColumn.implicitWidth + Tokens.padding.medium * 2 - (Config.bar.status.showLockStatus && !Hypr.capsLock && !Hypr.numLock ? iconColumn.spacing : 0)
|
||||
|
||||
ColumnLayout {
|
||||
RowLayout {
|
||||
id: iconColumn
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: Tokens.padding.medium
|
||||
anchors.centerIn: parent
|
||||
|
||||
spacing: Tokens.spacing.medium / 2
|
||||
|
||||
|
|
@ -261,7 +258,7 @@ StyledRect {
|
|||
required property string name
|
||||
|
||||
asynchronous: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
visible: active
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,27 +19,27 @@ StyledRect {
|
|||
|
||||
property bool expanded
|
||||
|
||||
readonly property real nonAnimHeight: {
|
||||
readonly property real nonAnimWidth: {
|
||||
if (!Config.bar.tray.compact)
|
||||
return layout.implicitHeight + padding * 2;
|
||||
return (expanded ? expandIcon.implicitHeight + layout.implicitHeight + spacing : expandIcon.implicitHeight) + padding * 2;
|
||||
return layout.implicitWidth + padding * 2;
|
||||
return (expanded ? expandIcon.implicitWidth + layout.implicitWidth + spacing : expandIcon.implicitWidth) + padding * 2;
|
||||
}
|
||||
|
||||
clip: true
|
||||
visible: height > 0
|
||||
visible: width > 0
|
||||
|
||||
implicitWidth: Tokens.sizes.bar.innerWidth
|
||||
implicitHeight: nonAnimHeight
|
||||
implicitHeight: Tokens.sizes.bar.innerWidth
|
||||
implicitWidth: nonAnimWidth
|
||||
|
||||
color: Qt.alpha(Colours.tPalette.m3surfaceContainer, (Config.bar.tray.background && items.count > 0) ? Colours.tPalette.m3surfaceContainer.a : 0)
|
||||
radius: Tokens.rounding.full
|
||||
|
||||
Column {
|
||||
Row {
|
||||
id: layout
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: root.padding
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: root.padding
|
||||
spacing: Tokens.spacing.small
|
||||
|
||||
opacity: root.expanded || !Config.bar.tray.compact ? 1 : 0
|
||||
|
|
@ -86,37 +86,37 @@ StyledRect {
|
|||
|
||||
asynchronous: true
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
|
||||
active: Config.bar.tray.compact && items.count > 0
|
||||
|
||||
sourceComponent: Item {
|
||||
implicitWidth: expandIconInner.implicitWidth
|
||||
implicitHeight: expandIconInner.implicitHeight - Tokens.padding.small
|
||||
implicitHeight: expandIconInner.implicitHeight
|
||||
implicitWidth: expandIconInner.implicitWidth - Tokens.padding.small
|
||||
|
||||
MaterialIcon {
|
||||
id: expandIconInner
|
||||
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: Config.bar.tray.background ? Tokens.padding.extraSmall : -Tokens.padding.extraSmall
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: Config.bar.tray.background ? Tokens.padding.extraSmall : -Tokens.padding.extraSmall
|
||||
text: "expand_less"
|
||||
fontStyle: Tokens.font.icon.large
|
||||
rotation: root.expanded ? 180 : 0
|
||||
rotation: root.expanded ? 270 : 90
|
||||
|
||||
Behavior on rotation {
|
||||
Anim {}
|
||||
}
|
||||
|
||||
Behavior on anchors.bottomMargin {
|
||||
Behavior on anchors.rightMargin {
|
||||
Anim {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on implicitHeight {
|
||||
Behavior on implicitWidth {
|
||||
Anim {}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ ColumnLayout {
|
|||
readonly property bool isOccupied: occupied[ws] ?? false
|
||||
readonly property bool hasWindows: isOccupied && Config.bar.workspaces.showWindows
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.preferredHeight: size
|
||||
|
||||
spacing: 0
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ StyledClippingRect {
|
|||
|
||||
property real blur: onSpecial ? 1 : 0
|
||||
|
||||
implicitWidth: Tokens.sizes.bar.innerWidth
|
||||
implicitHeight: layout.implicitHeight + Tokens.padding.small
|
||||
implicitHeight: Tokens.sizes.bar.innerWidth
|
||||
implicitWidth: layout.implicitWidth + Tokens.padding.small
|
||||
|
||||
color: Colours.tPalette.m3surfaceContainer
|
||||
radius: Tokens.rounding.full
|
||||
|
|
@ -60,7 +60,7 @@ StyledClippingRect {
|
|||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
RowLayout {
|
||||
id: layout
|
||||
|
||||
anchors.centerIn: parent
|
||||
|
|
@ -81,7 +81,7 @@ StyledClippingRect {
|
|||
|
||||
Loader {
|
||||
asynchronous: true
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
active: Config.bar.workspaces.activeIndicator
|
||||
|
||||
sourceComponent: ActiveIndicator {
|
||||
|
|
|
|||
|
|
@ -85,14 +85,14 @@ StyledWindow {
|
|||
Region {
|
||||
id: emptyRegion
|
||||
|
||||
x: panels.notifications.x + bar.implicitWidth
|
||||
y: panels.notifications.y + root.borderThickness
|
||||
x: panels.notifications.x + root.borderThickness
|
||||
y: panels.notifications.y + bar.implicitHeight
|
||||
width: panels.notifications.width
|
||||
height: panels.notifications.height
|
||||
|
||||
Region {
|
||||
x: root.width - width
|
||||
y: panels.osdWrapper.y + root.borderThickness
|
||||
y: panels.osdWrapper.y + bar.implicitHeight
|
||||
width: panels.osdWrapper.width * (1 - panels.osd.offsetScale) + root.borderThickness
|
||||
height: panels.osd.height
|
||||
}
|
||||
|
|
@ -155,9 +155,9 @@ StyledWindow {
|
|||
anchors.margins: -50 // Make border thicker to smooth out bulge from closed drawers
|
||||
group: blobGroup
|
||||
radius: root.borderRounding
|
||||
borderLeft: bar.implicitWidth - anchors.margins - root.sdfBorderOffset
|
||||
borderLeft: root.borderThickness - anchors.margins - root.sdfBorderOffset
|
||||
borderRight: root.borderThickness - anchors.margins - root.sdfBorderOffset
|
||||
borderTop: root.borderThickness - anchors.margins - root.sdfBorderOffset
|
||||
borderTop: bar.implicitHeight - anchors.margins - root.sdfBorderOffset
|
||||
borderBottom: root.borderThickness - anchors.margins - root.sdfBorderOffset
|
||||
}
|
||||
|
||||
|
|
@ -180,7 +180,7 @@ StyledWindow {
|
|||
|
||||
panel: panels.sessionWrapper
|
||||
deformAmount: 0.2
|
||||
x: panels.sessionWrapper.x + panels.session.x + bar.implicitWidth
|
||||
x: panels.sessionWrapper.x + panels.session.x + root.borderThickness
|
||||
implicitWidth: panels.session.width
|
||||
}
|
||||
|
||||
|
|
@ -199,7 +199,7 @@ StyledWindow {
|
|||
|
||||
panel: panels.osdWrapper
|
||||
deformAmount: 0.25
|
||||
x: panels.osdWrapper.x + panels.osd.x + bar.implicitWidth
|
||||
x: panels.osdWrapper.x + panels.osd.x + root.borderThickness
|
||||
implicitWidth: panels.osd.width
|
||||
}
|
||||
|
||||
|
|
@ -226,7 +226,7 @@ StyledWindow {
|
|||
|
||||
panel: panels.popoutsWrapper
|
||||
deformAmount: panels.popouts.isDetached ? 0.05 : panels.popouts.hasCurrent ? 0.15 : 0.1
|
||||
x: panels.popoutsWrapper.x + panels.popouts.x + bar.implicitWidth - panels.popouts.width * extraWidth
|
||||
x: panels.popoutsWrapper.x + panels.popouts.x + root.borderThickness - panels.popouts.width * extraWidth
|
||||
implicitWidth: panels.popouts.width * (1 + extraWidth)
|
||||
|
||||
Behavior on extraWidth {
|
||||
|
|
@ -292,8 +292,9 @@ StyledWindow {
|
|||
BarWrapper {
|
||||
id: bar
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
screen: root.screen
|
||||
visibilities: visibilities
|
||||
|
|
@ -310,8 +311,8 @@ StyledWindow {
|
|||
property real deformAmount: 0.15
|
||||
|
||||
group: blobGroup
|
||||
x: panel.x + bar.implicitWidth
|
||||
y: panel.y + root.borderThickness
|
||||
x: panel.x + root.borderThickness
|
||||
y: panel.y + bar.implicitHeight
|
||||
implicitWidth: panel.width
|
||||
implicitHeight: panel.height
|
||||
radius: Tokens.rounding.extraLarge
|
||||
|
|
|
|||
|
|
@ -14,11 +14,11 @@ Scope {
|
|||
|
||||
ExclusionZone {
|
||||
anchors.left: true
|
||||
exclusiveZone: root.bar.exclusiveZone
|
||||
}
|
||||
|
||||
ExclusionZone {
|
||||
anchors.top: true
|
||||
exclusiveZone: root.bar.exclusiveZone
|
||||
}
|
||||
|
||||
ExclusionZone {
|
||||
|
|
|
|||
|
|
@ -23,27 +23,29 @@ CustomMouseArea {
|
|||
property bool osdShortcutActive
|
||||
property bool utilitiesShortcutActive
|
||||
|
||||
// NoSignal top bar: the bar's thickness now insets the TOP, so panel Y-origins
|
||||
// are offset by bar.implicitHeight; the left inset is just the border thickness.
|
||||
function withinPanelHeight(panel: Item, x: real, y: real): bool {
|
||||
const panelY = root.borderThickness + panel.y;
|
||||
const panelY = root.bar.implicitHeight + panel.y;
|
||||
return y >= panelY - Config.border.rounding && y <= panelY + panel.height + Config.border.rounding;
|
||||
}
|
||||
|
||||
function withinPanelWidth(panel: Item, x: real, y: real): bool {
|
||||
const panelX = bar.implicitWidth + panel.x;
|
||||
const panelX = root.borderThickness + panel.x;
|
||||
return x >= panelX - Config.border.rounding && x <= panelX + panel.width + Config.border.rounding;
|
||||
}
|
||||
|
||||
function inLeftPanel(panel: Item, x: real, y: real): bool {
|
||||
return x < bar.implicitWidth + panel.x + panel.width && withinPanelHeight(panel, x, y);
|
||||
return x < root.borderThickness + panel.x + panel.width && withinPanelHeight(panel, x, y);
|
||||
}
|
||||
|
||||
function inRightPanel(panel: Item, x: real, y: real): bool {
|
||||
return x > Math.min(width - Config.border.minThickness, bar.implicitWidth + panel.x) && withinPanelHeight(panel, x, y);
|
||||
return x > Math.min(width - Config.border.minThickness, root.borderThickness + panel.x) && withinPanelHeight(panel, x, y);
|
||||
}
|
||||
|
||||
function inTopPanel(panel: Item, x: real, y: real): bool {
|
||||
const panelHeight = panel.height * (1 - (panel.offsetScale ?? 0)); // qmllint disable missing-property
|
||||
return y < Math.max(Config.border.minThickness, Config.border.thickness + panelHeight) && withinPanelWidth(panel, x, y);
|
||||
return y < Math.max(Config.border.minThickness, root.bar.implicitHeight + panelHeight) && withinPanelWidth(panel, x, y);
|
||||
}
|
||||
|
||||
function inBottomPanel(panel: Item, x: real, y: real, isCorner = false): bool {
|
||||
|
|
@ -54,8 +56,8 @@ CustomMouseArea {
|
|||
function onWheel(event: WheelEvent): void {
|
||||
if (fullscreen)
|
||||
return;
|
||||
if (event.x < bar.implicitWidth) {
|
||||
bar.handleWheel(event.y, event.angleDelta);
|
||||
if (event.y < bar.implicitHeight) {
|
||||
bar.handleWheel(event.x, event.angleDelta);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -102,15 +104,15 @@ CustomMouseArea {
|
|||
return;
|
||||
}
|
||||
|
||||
// Show bar in non-exclusive mode on hover
|
||||
if (!visibilities.bar && Config.bar.showOnHover && x < bar.clampedWidth)
|
||||
// Show bar in non-exclusive mode on hover (top edge)
|
||||
if (!visibilities.bar && Config.bar.showOnHover && y < bar.clampedHeight)
|
||||
bar.isHovered = true;
|
||||
|
||||
// Show/hide bar on drag
|
||||
if (pressed && dragStart.x < bar.clampedWidth) {
|
||||
if (dragX > Config.bar.dragThreshold)
|
||||
// Show/hide bar on drag (vertical, from the top edge)
|
||||
if (pressed && dragStart.y < bar.clampedHeight) {
|
||||
if (dragY > Config.bar.dragThreshold)
|
||||
visibilities.bar = true;
|
||||
else if (dragX < -Config.bar.dragThreshold)
|
||||
else if (dragY < -Config.bar.dragThreshold)
|
||||
visibilities.bar = false;
|
||||
}
|
||||
|
||||
|
|
@ -128,7 +130,7 @@ CustomMouseArea {
|
|||
root.panels.osd.hovered = true;
|
||||
}
|
||||
|
||||
const showSidebar = pressed && dragStart.x > Math.min(width - Config.border.minThickness, bar.implicitWidth + panels.sidebar.x);
|
||||
const showSidebar = pressed && dragStart.x > Math.min(width - Config.border.minThickness, root.borderThickness + panels.sidebar.x);
|
||||
|
||||
// Show/hide session on drag
|
||||
if (pressed && inRightPanel(panels.sessionWrapper, dragStart.x, dragStart.y) && withinPanelHeight(panels.sessionWrapper, x, y)) {
|
||||
|
|
@ -213,9 +215,9 @@ CustomMouseArea {
|
|||
utilitiesShortcutActive = false;
|
||||
}
|
||||
|
||||
// Show popouts on hover
|
||||
if (x < bar.implicitWidth) {
|
||||
bar.checkPopout(y);
|
||||
// Show popouts on hover (top bar)
|
||||
if (y < bar.implicitHeight) {
|
||||
bar.checkPopout(x);
|
||||
} else if ((!popouts.currentName.startsWith("traymenu") || ((popouts.current as StackView)?.depth ?? 0) <= 1) && !inLeftPanel(panels.popoutsWrapper, x, y)) {
|
||||
popouts.hasCurrent = false;
|
||||
bar.closeTray();
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ Item {
|
|||
|
||||
anchors.fill: parent
|
||||
anchors.margins: borderThickness
|
||||
anchors.leftMargin: bar.implicitWidth
|
||||
anchors.topMargin: bar.implicitHeight
|
||||
|
||||
Item {
|
||||
id: osdWrapper
|
||||
|
|
|
|||
|
|
@ -15,10 +15,10 @@ Region {
|
|||
readonly property real borderThickness: win.contentItem.Config.border.thickness
|
||||
readonly property real clampedThickness: win.contentItem.Config.border.clampedThickness
|
||||
|
||||
x: bar.clampedWidth + win.dragMaskPadding
|
||||
y: clampedThickness + win.dragMaskPadding
|
||||
width: win.width - bar.clampedWidth - clampedThickness - win.dragMaskPadding * 2
|
||||
height: win.height - clampedThickness * 2 - win.dragMaskPadding * 2
|
||||
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 {
|
||||
|
|
@ -75,8 +75,8 @@ Region {
|
|||
component R: Region {
|
||||
required property Item panel
|
||||
|
||||
x: panel.x + root.bar.implicitWidth
|
||||
y: panel.y + root.borderThickness
|
||||
x: panel.x + root.borderThickness
|
||||
y: panel.y + root.bar.implicitHeight
|
||||
width: panel.width
|
||||
height: panel.height
|
||||
intersection: Intersection.Subtract
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue