summaryrefslogtreecommitdiff
path: root/modules/bar
diff options
context:
space:
mode:
Diffstat (limited to 'modules/bar')
-rw-r--r--modules/bar/Bar.qml270
-rw-r--r--modules/bar/BarWrapper.qml9
-rw-r--r--modules/bar/components/ActiveWindow.qml97
-rw-r--r--modules/bar/components/Power.qml28
-rw-r--r--modules/bar/components/StatusIcons.qml73
-rw-r--r--modules/bar/components/workspaces/Workspaces.qml90
6 files changed, 281 insertions, 286 deletions
diff --git a/modules/bar/Bar.qml b/modules/bar/Bar.qml
index 22f21dd..cc191de 100644
--- a/modules/bar/Bar.qml
+++ b/modules/bar/Bar.qml
@@ -1,5 +1,5 @@
-import qs.components
-import qs.components.controls
+pragma ComponentBehavior: Bound
+
import qs.services
import qs.config
import "popouts" as BarPopouts
@@ -7,170 +7,176 @@ import "components"
import "components/workspaces"
import Quickshell
import QtQuick
+import QtQuick.Layouts
-Item {
+ColumnLayout {
id: root
required property ShellScreen screen
required property PersistentProperties visibilities
required property BarPopouts.Wrapper popouts
+ readonly property int padding: Math.max(Appearance.padding.smaller, Config.border.thickness)
+ readonly property int vPadding: Appearance.padding.large
function checkPopout(y: real): void {
- 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;
-
- // Check status icons hover areas
- let statusIconFound = false;
- for (const area of statusIconsInner.hoverAreas) {
- if (!area.enabled)
- continue;
+ const ch = childAt(width / 2, y) as WrappedLoader;
+ if (!ch) {
+ popouts.hasCurrent = false;
+ return;
+ }
- const item = area.item;
- const itemY = statusIcons.y + statusIconsInner.y + item.y - spacing / 2;
- const itemHeight = item.implicitHeight + spacing;
+ const id = ch.id;
+ const top = ch.y;
+ const item = ch.item;
+ const itemHeight = item.implicitHeight;
- if (y >= itemY && y <= itemY + itemHeight) {
- popouts.currentName = area.name;
- popouts.currentCenter = Qt.binding(() => statusIcons.y + statusIconsInner.y + item.y + item.implicitHeight / 2);
+ if (id === "statusIcons") {
+ const items = item.items;
+ const icon = items.childAt(items.width / 2, mapToItem(items, 0, y).y);
+ if (icon) {
+ popouts.currentName = icon.name;
+ popouts.currentCenter = Qt.binding(() => icon.mapToItem(root, 0, icon.implicitHeight / 2).y);
popouts.hasCurrent = true;
- statusIconFound = true;
- break;
}
- }
-
- 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);
+ } else if (id === "tray") {
+ const index = Math.floor(((y - top) / itemHeight) * item.items.count);
+ const trayItem = item.items.itemAt(index);
+ if (trayItem) {
+ popouts.currentName = `traymenu${index}`;
+ popouts.currentCenter = Qt.binding(() => trayItem.mapToItem(root, 0, trayItem.implicitHeight / 2).y);
+ popouts.hasCurrent = true;
+ }
+ } else if (id === "activeWindow") {
+ popouts.currentName = id.toLowerCase();
+ popouts.currentCenter = item.mapToItem(root, 0, itemHeight / 2).y;
popouts.hasCurrent = true;
- } else if (!statusIconFound) {
- popouts.hasCurrent = false;
}
}
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- anchors.left: parent.left
-
- implicitWidth: child.implicitWidth + Math.max(Appearance.padding.smaller, Config.border.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
+ function handleWheel(y: real, angleDelta: point): void {
+ const ch = childAt(width / 2, y) as WrappedLoader;
+ if (ch?.id === "workspaces") {
+ // Workspace scroll
+ const activeWs = Hyprland.activeToplevel?.workspace?.name;
+ if (activeWs?.startsWith("special:"))
+ Hyprland.dispatch(`togglespecialworkspace ${activeWs.slice(8)}`);
+ else if (angleDelta.y < 0 || Hyprland.activeWsId > 1)
+ Hyprland.dispatch(`workspace r${angleDelta.y > 0 ? "-" : "+"}1`);
+ } else if (y < screen.height / 2) {
+ // Volume scroll on top half
+ if (angleDelta.y > 0)
+ Audio.incrementVolume();
+ else if (angleDelta.y < 0)
+ Audio.decrementVolume();
+ } else {
+ // Brightness scroll on bottom half
+ const monitor = Brightness.getMonitorForScreen(screen);
+ if (angleDelta.y > 0)
+ monitor.setBrightness(monitor.brightness + 0.1);
+ else if (angleDelta.y < 0)
+ monitor.setBrightness(monitor.brightness - 0.1);
}
+ }
- StyledRect {
- id: workspaces
-
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.top: osIcon.bottom
- anchors.topMargin: Appearance.spacing.normal
+ spacing: Appearance.spacing.normal
- radius: Appearance.rounding.full
- color: Colours.tPalette.m3surfaceContainer
+ Repeater {
+ id: repeater
- implicitWidth: workspacesInner.implicitWidth + Appearance.padding.small * 2
- implicitHeight: workspacesInner.implicitHeight + Appearance.padding.small * 2
+ model: Config.bar.entries
- CustomMouseArea {
- anchors.fill: parent
- anchors.leftMargin: -Math.max(Appearance.padding.smaller, Config.border.thickness)
- anchors.rightMargin: -Math.max(Appearance.padding.smaller, Config.border.thickness)
+ DelegateChooser {
+ role: "id"
- function onWheel(event: WheelEvent): void {
- const activeWs = Hyprland.activeToplevel?.workspace?.name;
- if (activeWs?.startsWith("special:"))
- Hyprland.dispatch(`togglespecialworkspace ${activeWs.slice(8)}`);
- else if (event.angleDelta.y < 0 || Hyprland.activeWsId > 1)
- Hyprland.dispatch(`workspace r${event.angleDelta.y > 0 ? "-" : "+"}1`);
+ DelegateChoice {
+ roleValue: "spacer"
+ delegate: WrappedLoader {
+ Layout.fillHeight: enabled
}
}
-
- Workspaces {
- id: workspacesInner
-
- anchors.centerIn: parent
+ DelegateChoice {
+ roleValue: "logo"
+ delegate: WrappedLoader {
+ sourceComponent: OsIcon {}
+ }
+ }
+ DelegateChoice {
+ roleValue: "workspaces"
+ delegate: WrappedLoader {
+ sourceComponent: Workspaces {}
+ }
+ }
+ DelegateChoice {
+ roleValue: "activeWindow"
+ delegate: WrappedLoader {
+ sourceComponent: ActiveWindow {
+ bar: root
+ monitor: Brightness.getMonitorForScreen(root.screen)
+ }
+ }
+ }
+ DelegateChoice {
+ roleValue: "tray"
+ delegate: WrappedLoader {
+ sourceComponent: Tray {}
+ }
+ }
+ DelegateChoice {
+ roleValue: "clock"
+ delegate: WrappedLoader {
+ sourceComponent: Clock {}
+ }
+ }
+ DelegateChoice {
+ roleValue: "statusIcons"
+ delegate: WrappedLoader {
+ sourceComponent: StatusIcons {}
+ }
+ }
+ DelegateChoice {
+ roleValue: "power"
+ delegate: WrappedLoader {
+ sourceComponent: Power {
+ visibilities: root.visibilities
+ }
+ }
}
}
+ }
- 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
+ component WrappedLoader: Loader {
+ required property bool enabled
+ required property string id
+ required property int index
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.bottom: statusIcons.top
- anchors.bottomMargin: Appearance.spacing.normal
+ function findFirstEnabled(): Item {
+ const count = repeater.count;
+ for (let i = 0; i < count; i++) {
+ const item = repeater.itemAt(i);
+ if (item?.enabled)
+ return item;
+ }
+ return null;
}
- 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.tPalette.m3surfaceContainer
-
- implicitHeight: statusIconsInner.implicitHeight + Appearance.padding.normal * 2
-
- StatusIcons {
- id: statusIconsInner
-
- anchors.centerIn: parent
+ function findLastEnabled(): Item {
+ for (let i = repeater.count - 1; i >= 0; i--) {
+ const item = repeater.itemAt(i);
+ if (item?.enabled)
+ return item;
}
+ return null;
}
- Power {
- id: power
+ Layout.alignment: Qt.AlignHCenter
+ Layout.leftMargin: root.padding
+ Layout.rightMargin: root.padding
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.bottom: parent.bottom
- anchors.bottomMargin: Appearance.padding.large
+ // 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
- visibilities: root.visibilities
- }
+ visible: enabled
+ active: enabled
}
}
diff --git a/modules/bar/BarWrapper.qml b/modules/bar/BarWrapper.qml
index 7752446..88c3892 100644
--- a/modules/bar/BarWrapper.qml
+++ b/modules/bar/BarWrapper.qml
@@ -14,19 +14,24 @@ Item {
required property BarPopouts.Wrapper popouts
readonly property int exclusiveZone: Config.bar.persistent || visibilities.bar ? content.implicitWidth : Config.border.thickness
+ readonly property bool shouldBeVisible: Config.bar.persistent || visibilities.bar || isHovered
property bool isHovered
function checkPopout(y: real): void {
content.item?.checkPopout(y);
}
+ function handleWheel(y: real, angleDelta: point): void {
+ content.item?.handleWheel(y, angleDelta);
+ }
+
visible: width > Config.border.thickness
implicitWidth: Config.border.thickness
implicitHeight: content.implicitHeight
states: State {
name: "visible"
- when: Config.bar.persistent || root.visibilities.bar || root.isHovered
+ when: root.shouldBeVisible
PropertyChanges {
root.implicitWidth: content.implicitWidth
@@ -63,7 +68,7 @@ Item {
Loader {
id: content
- Component.onCompleted: active = Qt.binding(() => Config.bar.persistent || root.visibilities.bar || root.isHovered || root.visible)
+ Component.onCompleted: active = Qt.binding(() => root.shouldBeVisible || root.visible)
anchors.top: parent.top
anchors.bottom: parent.bottom
diff --git a/modules/bar/components/ActiveWindow.qml b/modules/bar/components/ActiveWindow.qml
index de0f0ad..3bea956 100644
--- a/modules/bar/components/ActiveWindow.qml
+++ b/modules/bar/components/ActiveWindow.qml
@@ -9,73 +9,62 @@ import QtQuick
Item {
id: root
+ required property var bar
required property Brightness.Monitor monitor
property color colour: Colours.palette.m3primary
- readonly property Item child: child
- implicitWidth: child.implicitWidth
- implicitHeight: child.implicitHeight
-
- Item {
- id: child
-
- property Item current: text1
-
- anchors.centerIn: parent
+ readonly property int maxHeight: {
+ const otherModules = bar.children.filter(c => c.id && c.item !== this && c.id !== "spacer");
+ const otherHeight = otherModules.reduce((acc, curr) => acc + curr.height, 0);
+ // Length - 2 cause repeater counts as a child
+ return bar.height - otherHeight - bar.spacing * (bar.children.length - 1) - bar.vPadding * 2;
+ }
+ property Title current: text1
- clip: true
- implicitWidth: Math.max(icon.implicitWidth, current.implicitHeight)
- implicitHeight: icon.implicitHeight + current.implicitWidth + current.anchors.topMargin
+ clip: true
+ implicitWidth: Math.max(icon.implicitWidth, current.implicitHeight)
+ implicitHeight: icon.implicitHeight + current.implicitWidth + current.anchors.topMargin
- MaterialIcon {
- id: icon
+ MaterialIcon {
+ id: icon
- animate: true
- text: Icons.getAppCategoryIcon(Hyprland.activeToplevel?.lastIpcObject.class, "desktop_windows")
- color: root.colour
+ anchors.horizontalCenter: parent.horizontalCenter
- anchors.horizontalCenter: parent.horizontalCenter
- }
+ animate: true
+ text: Icons.getAppCategoryIcon(Hyprland.activeToplevel?.lastIpcObject.class, "desktop_windows")
+ color: root.colour
+ }
- Title {
- id: text1
- }
+ Title {
+ id: text1
+ }
- Title {
- id: text2
- }
+ Title {
+ id: text2
+ }
- TextMetrics {
- id: metrics
+ TextMetrics {
+ id: metrics
- text: Hyprland.activeToplevel?.title ?? qsTr("Desktop")
- font.pointSize: Appearance.font.size.smaller
- font.family: Appearance.font.family.mono
- elide: Qt.ElideRight
- elideWidth: root.height - icon.height
+ text: Hyprland.activeToplevel?.title ?? qsTr("Desktop")
+ font.pointSize: Appearance.font.size.smaller
+ font.family: Appearance.font.family.mono
+ elide: Qt.ElideRight
+ elideWidth: root.maxHeight - icon.height
- onTextChanged: {
- const next = child.current === text1 ? text2 : text1;
- next.text = elidedText;
- child.current = next;
- }
- onElideWidthChanged: child.current.text = elidedText
- }
-
- Behavior on implicitWidth {
- NumberAnimation {
- duration: Appearance.anim.durations.normal
- easing.type: Easing.BezierSpline
- easing.bezierCurve: Appearance.anim.curves.emphasized
- }
+ onTextChanged: {
+ const next = root.current === text1 ? text2 : text1;
+ next.text = elidedText;
+ root.current = next;
}
+ onElideWidthChanged: root.current.text = elidedText
+ }
- Behavior on implicitHeight {
- NumberAnimation {
- duration: Appearance.anim.durations.normal
- easing.type: Easing.BezierSpline
- easing.bezierCurve: Appearance.anim.curves.emphasized
- }
+ Behavior on implicitHeight {
+ NumberAnimation {
+ duration: Appearance.anim.durations.normal
+ easing.type: Easing.BezierSpline
+ easing.bezierCurve: Appearance.anim.curves.emphasized
}
}
@@ -89,7 +78,7 @@ Item {
font.pointSize: metrics.font.pointSize
font.family: metrics.font.family
color: root.colour
- opacity: child.current === this ? 1 : 0
+ opacity: root.current === this ? 1 : 0
transform: Rotation {
angle: 90
diff --git a/modules/bar/components/Power.qml b/modules/bar/components/Power.qml
index 71dc296..917bdf7 100644
--- a/modules/bar/components/Power.qml
+++ b/modules/bar/components/Power.qml
@@ -2,24 +2,22 @@ import qs.components
import qs.services
import qs.config
import Quickshell
+import QtQuick
-MaterialIcon {
+Item {
id: root
required property PersistentProperties visibilities
- text: "power_settings_new"
- color: Colours.palette.m3error
- font.bold: true
- font.pointSize: Appearance.font.size.normal
+ implicitWidth: icon.implicitHeight + Appearance.padding.small * 2
+ implicitHeight: icon.implicitHeight
StateLayer {
+ // Cursed workaround to make the height larger than the parent
anchors.fill: undefined
anchors.centerIn: parent
- anchors.horizontalCenterOffset: 1
-
- implicitWidth: parent.implicitHeight + Appearance.padding.small * 2
- implicitHeight: implicitWidth
+ implicitWidth: implicitHeight
+ implicitHeight: icon.implicitHeight + Appearance.padding.small * 2
radius: Appearance.rounding.full
@@ -27,4 +25,16 @@ MaterialIcon {
root.visibilities.session = !root.visibilities.session;
}
}
+
+ MaterialIcon {
+ id: icon
+
+ anchors.centerIn: parent
+ anchors.horizontalCenterOffset: -1
+
+ text: "power_settings_new"
+ color: Colours.palette.m3error
+ font.bold: true
+ font.pointSize: Appearance.font.size.normal
+ }
}
diff --git a/modules/bar/components/StatusIcons.qml b/modules/bar/components/StatusIcons.qml
index c364d6b..f7d9828 100644
--- a/modules/bar/components/StatusIcons.qml
+++ b/modules/bar/components/StatusIcons.qml
@@ -10,51 +10,29 @@ import Quickshell.Services.UPower
import QtQuick
import QtQuick.Layouts
-Item {
+StyledRect {
id: root
property color colour: Colours.palette.m3secondary
+ readonly property alias items: iconColumn
- readonly property list<var> hoverAreas: [
- {
- name: "audio",
- item: audioIcon,
- enabled: Config.bar.status.showAudio
- },
- {
- name: "network",
- item: networkIcon,
- enabled: Config.bar.status.showNetwork
- },
- {
- name: "bluetooth",
- item: bluetoothGroup,
- enabled: Config.bar.status.showBluetooth
- },
- {
- name: "battery",
- item: batteryIcon,
- enabled: Config.bar.status.showBattery
- }
- ]
+ color: Colours.tPalette.m3surfaceContainer
+ radius: Appearance.rounding.full
clip: true
- implicitWidth: iconColumn.implicitWidth
- implicitHeight: iconColumn.implicitHeight
+ implicitWidth: iconColumn.implicitWidth + Appearance.padding.normal * 2
+ implicitHeight: iconColumn.implicitHeight + Appearance.padding.normal * 2
ColumnLayout {
id: iconColumn
- anchors.horizontalCenter: parent.horizontalCenter
+ anchors.centerIn: parent
spacing: Appearance.spacing.smaller / 2
// Audio icon
- Loader {
- id: audioIcon
-
- asynchronous: true
+ WrappedLoader {
+ name: "audio"
active: Config.bar.status.showAudio
- visible: active
sourceComponent: MaterialIcon {
animate: true
@@ -65,8 +43,6 @@ Item {
// Keyboard layout icon
Loader {
- id: kbLayout
-
Layout.alignment: Qt.AlignHCenter
asynchronous: true
active: Config.bar.status.showKbLayout
@@ -81,12 +57,9 @@ Item {
}
// Network icon
- Loader {
- id: networkIcon
-
- asynchronous: true
+ WrappedLoader {
+ name: "network"
active: Config.bar.status.showNetwork
- visible: active
sourceComponent: MaterialIcon {
animate: true
@@ -95,13 +68,10 @@ Item {
}
}
- // Bluetooth section (grouped for hover area)
- Loader {
- id: bluetoothGroup
-
- asynchronous: true
+ // Bluetooth section
+ WrappedLoader {
+ name: "bluetooth"
active: Config.bar.status.showBluetooth
- visible: active
sourceComponent: ColumnLayout {
spacing: Appearance.spacing.smaller / 2
@@ -157,12 +127,9 @@ Item {
}
// Battery icon
- Loader {
- id: batteryIcon
-
- asynchronous: true
+ WrappedLoader {
+ name: "battery"
active: Config.bar.status.showBattery
- visible: active
sourceComponent: MaterialIcon {
animate: true
@@ -194,6 +161,14 @@ Item {
Anim {}
}
+ component WrappedLoader: Loader {
+ required property string name
+
+ Layout.alignment: Qt.AlignHCenter
+ asynchronous: true
+ visible: active
+ }
+
component Anim: NumberAnimation {
duration: Appearance.anim.durations.large
easing.type: Easing.BezierSpline
diff --git a/modules/bar/components/workspaces/Workspaces.qml b/modules/bar/components/workspaces/Workspaces.qml
index 0a806f7..fb6201d 100644
--- a/modules/bar/components/workspaces/Workspaces.qml
+++ b/modules/bar/components/workspaces/Workspaces.qml
@@ -2,10 +2,11 @@ pragma ComponentBehavior: Bound
import qs.services
import qs.config
+import qs.components
import QtQuick
import QtQuick.Layouts
-Item {
+StyledRect {
id: root
readonly property list<Workspace> workspaces: layout.children.filter(c => c.isWorkspace).sort((w1, w2) => w1.ws - w2.ws)
@@ -15,60 +16,69 @@ Item {
}, {})
readonly property int groupOffset: Math.floor((Hyprland.activeWsId - 1) / Config.bar.workspaces.shown) * Config.bar.workspaces.shown
- implicitWidth: layout.implicitWidth
- implicitHeight: layout.implicitHeight
+ implicitWidth: layout.implicitWidth + Appearance.padding.small * 2
+ implicitHeight: layout.implicitHeight + Appearance.padding.small * 2
+ color: Colours.tPalette.m3surfaceContainer
+ radius: Appearance.rounding.full
- ColumnLayout {
- id: layout
+ Item {
+ id: inner
- spacing: 0
- layer.enabled: true
- layer.smooth: true
+ anchors.fill: parent
+ anchors.margins: Appearance.padding.small
- Repeater {
- model: Config.bar.workspaces.shown
+ ColumnLayout {
+ id: layout
- Workspace {
- occupied: root.occupied
- groupOffset: root.groupOffset
+ spacing: 0
+ layer.enabled: true
+ layer.smooth: true
+
+ Repeater {
+ model: Config.bar.workspaces.shown
+
+ Workspace {
+ occupied: root.occupied
+ groupOffset: root.groupOffset
+ }
}
}
- }
- Loader {
- active: Config.bar.workspaces.occupiedBg
- asynchronous: true
+ Loader {
+ active: Config.bar.workspaces.occupiedBg
+ asynchronous: true
- z: -1
- anchors.fill: parent
+ z: -1
+ anchors.fill: parent
- sourceComponent: OccupiedBg {
- workspaces: root.workspaces
- occupied: root.occupied
- groupOffset: root.groupOffset
+ sourceComponent: OccupiedBg {
+ workspaces: root.workspaces
+ occupied: root.occupied
+ groupOffset: root.groupOffset
+ }
}
- }
- Loader {
- active: Config.bar.workspaces.activeIndicator
- asynchronous: true
+ Loader {
+ active: Config.bar.workspaces.activeIndicator
+ asynchronous: true
- sourceComponent: ActiveIndicator {
- workspaces: root.workspaces
- mask: layout
- maskWidth: root.width
- maskHeight: root.height
- groupOffset: root.groupOffset
+ sourceComponent: ActiveIndicator {
+ workspaces: root.workspaces
+ mask: layout
+ maskWidth: inner.width
+ maskHeight: inner.height
+ groupOffset: root.groupOffset
+ }
}
- }
- MouseArea {
- anchors.fill: parent
+ MouseArea {
+ anchors.fill: parent
- onPressed: event => {
- const ws = layout.childAt(event.x, event.y).index + root.groupOffset + 1;
- if (Hyprland.activeWsId !== ws)
- Hyprland.dispatch(`workspace ${ws}`);
+ onPressed: event => {
+ const ws = layout.childAt(event.x, event.y).index + root.groupOffset + 1;
+ if (Hyprland.activeWsId !== ws)
+ Hyprland.dispatch(`workspace ${ws}`);
+ }
}
}
}