import QtQuick import QtQuick.Layouts import Quickshell import Quickshell.I3 import Quickshell.Hyprland import "../config" import "../services" // Workspace switcher for a single monitor. Three backends, one chip renderer // (WorkspaceChip): // // * Sway/i3 and Hyprland expose the same item shape (name / active / focused // / urgent / monitor.name / activate()), so both feed the same Repeater. // * attwm is a different model entirely -- nine fixed tags addressed by // bitmask, several of which can be viewed at once -- so it gets its own // Repeater over an index range. // // Exactly one of the two Repeaters is ever non-empty. The `?:` and `&&` guards // only evaluate the taken branch, which is what keeps the unused backend // singletons from being instantiated (no stray IPC) -- see Compositor. Row { id: root required property var screen // ShellScreen this bar lives on spacing: Theme.gap // Name of the output this bar is on, used to filter workspaces. readonly property string monitorName: screen ? screen.name : "" // attwm keeps tags, layout and geometry per output, so the tag row on this // bar reflects this monitor rather than whichever one has focus. readonly property var attwmOutput: Compositor.isAttwm ? Attwm.outputFor(monitorName) : null // ── Sway/i3 and Hyprland ──────────────────────────────────────────────── Repeater { model: Compositor.isAttwm ? 0 : Compositor.isHyprland ? Hyprland.workspaces : I3.workspaces WorkspaceChip { 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 label: modelData.name active: modelData.active focused: modelData.focused urgent: modelData.urgent onClicked: modelData.activate() } } // ── attwm ─────────────────────────────────────────────────────────────── Repeater { // 0 until the socket has produced a state object, so nothing is drawn // if we guessed the window manager wrong. model: Compositor.isAttwm ? Attwm.tagCount : 0 WorkspaceChip { id: tag required property int index readonly property bool viewing: Attwm.tagActive(root.attwmOutput, index) readonly property bool occupied: Attwm.tagOccupied(root.attwmOutput, index) label: Attwm.tagNames[index] ?? (index + 1) active: viewing // Tags are per output and several outputs can view a tag at once; // only the focused output's get the focused colour. focused: viewing && !!root.attwmOutput && root.attwmOutput.focused dimmed: !viewing && !occupied dot: occupied && !viewing // dwm's mouse bindings: view / toggle into view / send window there. onClicked: button => { const n = index + 1; if (button === Qt.RightButton) Attwm.send(`toggle-view ${n}`); else if (button === Qt.MiddleButton) Attwm.send(`tag ${n}`); else Attwm.send(`view ${n}`); } } } }