Files
omarchycn/default/quickshell/omarchy-shell/Ui
..

qs.Ui — Omarchy shell UI kit

Reusable QML components for omarchy-shell's built-in panels and any third-party plugin that wants a consistent look and behaviour. Every type is exposed under the qs.Ui module via the qmldir next to this file, so consumers write:

import qs.Ui

Item {
  PanelSeparator { foreground: someColor }
  PillButton { text: "Click me"; onClicked: ... }
}

Theme tokens (corner radius, accent, focus styling) live on the qs.Commons.Style singleton; every Ui component already binds to them, so toggling omarchy style corners <sharp|round> updates every consumer in one shot.

Visual reference

Run the dev gallery to see every component live:

omarchy-shell-ipc shell summon omarchy.dev-gallery '{}'

The gallery renders the real components (not copies), so it doubles as a smoke test — if a component starts misbehaving the gallery is the fastest place to see it.

Components

Grouped by what they're for, not alphabetically.

Panel surfaces

Type Purpose
KeyboardPanel Layer-shell popup with WlrKeyboardFocus.Exclusive. Use for panels summoned from a bar widget that need keyboard focus on map (j/k navigation, inline editors).
PopupCard xdg-popup based panel. Use for click/hover overlays that don't need to steal keyboard focus (calendar, weather flyout).

Cursor model

Type Purpose
CursorSurface Rectangle that paints fill + 1px border when hasCursor is true, and fill alone when current is true. The foundation for "single highlight on screen across keyboard and mouse" rows. Never read containsMouse for visuals — bind hasCursor from the panel's cursor state instead.
PanelKeyCatcher Item that emits semantic signals: moveRequested(dx, dy), activateRequested(), closeRequested(), deleteRequested(), textKey(string). Drop inside a panel root, wire signals to the panel's state mutators. blocked: true freezes everything except — nothing; it's a hard gate for inline editors.

Interactive primitives

Type Purpose
PillButton Rounded button with optional icon + label + tooltip. Has active, hasCursor (keyboard cursor), focusable (Tab-focus with accent ring), bordered (persistent 1px idle border for primary form buttons), and enabled. Hover and keyboard cursor render identically (fill + border) via the shared hot state; Tab-focus uses an accent ring that wins over both.
CursorPill PillButton that participates in a panel's single-cursor model. Adds a hovered(bool) signal so the panel can update its cursor state on mouse enter/leave. Use for DNS-pill / header-pill / segmented-choice patterns.
ChoiceButton A single button in a mutually-exclusive choice group (segmented control). selected uses accent fill+border; focus uses Style.focusBorderColor so keyboard nav reads differently from selection.
Toggle Title + description + switch. Click anywhere on the row to flip; caller updates checked in response.
TextField Single-line input. Inherits from Qt Quick Controls TextField so all of its base API (text, placeholderText, accepted, validator, ...) is available. Adds password: bool, foreground / accent / selectionTint color overrides, and horizontalPadding / verticalPadding size knobs. Focus styling uses Style.focusBorderColor to match Toggle and ChoiceButton.
PanelActionButton 22×22 right-edge action button (confirm, forget, unpair). hoverColor swaps between default foreground tint and urgent (red) tint. focusable: true enables Tab-focus with an accent ring — used for the bar settings widget-card row controls.
PanelSlider Volume/progress slider. Drag, click track, or wheel. moved(value) fires per change, released(value) once at end. (Named to avoid colliding with QtQuick.Controls.Slider.)
WidgetButton Bar widget chrome — for the strip itself, not for inside panels.

Structure

Type Purpose
PanelSeparator 1px alpha rule between sections. strength tweaks opacity.
PanelSectionHeader Small-bold label that introduces a section ("DNS provider", "Wi-Fi networks").
PanelToolTip Styled wrapper around Qt's ToolTip. Drop inside the hovered item and bind visible to the hover state. Use property names panelForeground/panelBackground (not foreground/background) to avoid clashing with ToolTip's built-ins.

Theme integration

qs.Commons.Style exposes:

  • cornerRadius — mirrors ~/.local/state/omarchy/toggles/quickshell-menu.json, hot-reloaded
  • focusBorderColor, focusFillColor, focusBorderWidth — derived from Color.accent
  • hotFill — the standard hover/cursor tint (foreground at 0.12 alpha)

qs.Commons.Color exposes the foundational palette plus per-surface roles loaded from the theme's colors.toml + shell.toml. Components in this kit default-bind to Color.foreground / Color.accent / Color.background so a caller with no explicit theme just works.

Conventions

  • Components are stateless about the values they display. They emit signals and let the caller mutate. Don't bake panel-specific state machines into kit components.
  • Mouse hover and keyboard cursor should converge on a single visual state. Bind hasCursor from the panel root; have hover handlers update the same root state via onHovered.
  • Property names follow the underlying QML type's convention. Where a clash is unavoidable (Toggle/ToolTip already define background in QQC), the kit uses a panel* prefix.

Adding a new component

  1. Write the QML file in this directory.
  2. Add a line to qmldir: TypeName 1.0 TypeName.qml.
  3. Add a live demo section to plugins/dev-gallery/GalleryPanel.qml using the real component — copy/paste reimplementations defeat the smoke-test value of the gallery.
  4. Update the table above.