import QtQuick import QtQuick.Layouts import Quickshell import Quickshell.I3 import Quickshell.Hyprland import "../config" // Workspace switcher for a single monitor. Works on both Sway/i3 and Hyprland: // the compositor is detected once from its instance env var, and the matching // Quickshell backend model is used. The two backends expose the same item shape // (name / active / focused / urgent / monitor.name / activate()), so a single // chip renderer covers both. The `?:` on `model` only evaluates the taken // branch, so the unused backend singleton is never instantiated (no stray IPC). Row { id: root required property var screen // ShellScreen this bar lives on spacing: Theme.gap // Which compositor are we under? Hyprland always exports this signature. readonly property bool isHyprland: !!Quickshell.env("HYPRLAND_INSTANCE_SIGNATURE") // Name of the output this bar is on, used to filter workspaces. readonly property string monitorName: screen ? screen.name : "" Repeater { model: root.isHyprland ? Hyprland.workspaces : I3.workspaces Rectangle { id: chip required property var modelData // only show workspaces belonging to this monitor. Both I3Workspace // and HyprlandWorkspace expose .monitor as an object with a .name. visible: modelData.monitor && modelData.monitor.name === root.monitorName width: visible ? Math.max(height, label.implicitWidth + 16) : 0 height: Theme.barHeight - Theme.gap * 2 radius: Theme.radius readonly property bool isFocused: modelData.focused readonly property bool isUrgent: modelData.urgent color: isUrgent ? Theme.red : isFocused ? Theme.blue : modelData.active ? Theme.surface1 : Theme.surface0 Text { id: label anchors.centerIn: parent text: chip.modelData.name font.family: Theme.font font.pixelSize: Theme.fontSize font.bold: chip.isFocused || chip.isUrgent color: (chip.isFocused || chip.isUrgent) ? Theme.mantle : Theme.text } MouseArea { anchors.fill: parent cursorShape: Qt.PointingHandCursor onClicked: chip.modelData.activate() } } } }