// The quick settings popover — GNOME's system menu (Super+S). // // A layer-shell surface rather than a PopupWindow because it needs keyboard // focus for the wifi password field, and because the bar it hangs from is // owned by a different module. import QtQuick import Quickshell import Quickshell.Wayland import Quickshell.Hyprland import qs.config import qs.services import qs.widgets PanelWindow { id: root visible: ShellState.quickSettingsOpen color: "transparent" // Hangs off the top-right corner, clear of the floating bar. anchors.top: true anchors.right: true margins.top: Theme.barHeight + Theme.barGap * 2 margins.right: Theme.barSideMargin exclusiveZone: 0 implicitWidth: Theme.popoverWidth implicitHeight: panel.implicitHeight // The `qs-popover` prefix is matched by a layerrule in hypr/rules.lua. WlrLayershell.namespace: "qs-popover-quicksettings" WlrLayershell.layer: WlrLayer.Overlay // OnDemand rather than Exclusive: the panel must be able to take typing for // the wifi password field, but must not steal it while merely visible. WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand onVisibleChanged: { if (root.visible) openAnim.restart(); else panel.reset(); } // Closes the panel when a click lands anywhere else on the desktop. HyprlandFocusGrab { windows: [root] active: root.visible onCleared: ShellState.close() } Rectangle { id: surface anchors.fill: parent radius: Theme.popoverRadius color: Theme.alpha(Theme.bgPopover, Theme.popoverAlpha) border.width: 1 border.color: Theme.alpha(Theme.fg, 0.08) // The prism edge — see widgets/PrismEdge.qml. Sits just inside the 1px // border so the two don't fight for the same row of pixels. PrismEdge { anchors.top: parent.top anchors.topMargin: 1 anchors.left: parent.left anchors.right: parent.right inset: parent.radius } transform: Scale { id: openScale origin.x: surface.width origin.y: 0 xScale: 1 yScale: 1 } // Escape reaches here by propagating up from whatever holds focus // (usually the password field), so it works in every sub-state. Item { anchors.fill: parent focus: true Keys.onEscapePressed: ShellState.close() QuickSettingsPanel { id: panel anchors.fill: parent } } } NumberAnimation { id: openAnim target: openScale property: "yScale" from: 0.94 to: 1.0 duration: Theme.durNormal easing.type: Easing.OutCubic } }