How the Interactive State System ([controls]) Works in Omarchy Themes

The [controls] section in Omarchy’s TOML-based theme system defines a unified token set for interactive UI elements, enabling consistent styling of buttons, dropdowns, and focus states through shallow-merged configuration files that update at runtime.

Omarchy’s theming engine relies on a token-based architecture where colors.toml files drive the visual appearance of the desktop environment. The interactive state system, exposed via the [controls] section, centralizes styling for all clickable and focusable chrome components according to the basecamp/omarchy source code.

What Is the [controls] Interactive State System?

The [controls] section acts as a dedicated namespace within Omarchy’s theme configuration. It isolates visual properties for interactive "chrome"—buttons, dropdown arrows, text input fields, and selection highlights—from the generic appearance tokens defined in [style].

Token Scope and Purpose

According to docs/theming.md at line 275, [controls] governs shared controls such as buttons, dropdowns, and text fields【/__modal/volumes/vo-cSqLfqnnIwYXEonuEJnnZa/repos/github.com/basecamp/omarchy/quattro/docs/theming.md#L275】. The system exposes state-specific tokens including:

  • bg and fg – default background and foreground colors
  • hover-bg and hover-fg – mouse-over states
  • selected-bg and selected-fg – active or highlighted states
  • disabled-bg and disabled-fg – non-interactive states
  • border and radius – structural dimensions

These tokens ensure that every interactive element shares a cohesive visual language across the shell.

Configuration Structure

Each theme stores its [controls] definition inside a colors.toml file. The default theme provides baseline values, while user-customized themes override specific tokens without replacing the entire set. This shallow-merge behavior means undefined tokens inherit from the parent theme, while explicitly declared values take precedence.

How [controls] Tokens Are Resolved at Runtime

Omarchy’s shell does not hardcode colors. Instead, it queries a theme manager that resolves token names like controls.bg or controls.selected-fg against the active configuration.

Theme Merging and Inheritance

The inheritance model follows a strict hierarchy:

  1. Default theme loads first, populating the token map with baseline [controls] values.
  2. User theme (e.g., ~/.config/omarchy/themes/custom/colors.toml) loads second, shallow-merging its [controls] section into the default map.
  3. Runtime resolution occurs when QML widgets request Theme.controls.hover-bg or similar properties.

As documented in docs/omarchy-shell.md at lines 220-229, this system standardizes reusable control chrome and only governs the shared button/dropdown chrome【/__modal/volumes/vo-cSqLfqnnIwYXEonuEJnnZa/repos/github.com/basecamp/omarchy/quattro/docs/omarchy-shell.md#L220】, leaving application-specific styling untouched.

QML Integration and Dynamic Updates

Widgets written in QML access [controls] tokens through the Theme or OmarchyTheme helper objects. When the user switches themes via the CLI command omarchy theme set <name>, the theme manager reloads the TOML files, recomputes the merged token map, and emits change notifications. All bound QML properties update instantly, triggering a seamless visual transition without restarting the shell.

Practical Implementation Examples

Customizing Control States in colors.toml

Create or edit a user theme file to override specific interactive states:


# ~/.config/omarchy/themes/nord-custom/colors.toml

[controls]
bg          = "#2e3440"
fg          = "#d8dee9"
hover-bg    = "#3b4252"
hover-fg    = "#eceff4"
selected-bg = "#88c0d0"
selected-fg = "#2e3440"
disabled-bg = "#4c566a"
disabled-fg = "#d8dee9"
radius      = "6px"

Only the tokens defined here replace the defaults; all other [controls] values inherit from the parent theme.

Consuming Tokens in QML Widgets

Reference the tokens in widget code to ensure consistent styling:

// Example button implementation in a panel widget
Rectangle {
    id: controlButton
    width: 120
    height: 32
    radius: Theme.controls.radius
    color: Theme.controls.bg
    
    Text {
        anchors.centerIn: parent
        text: "Submit"
        color: Theme.controls.fg
    }
    
    MouseArea {
        anchors.fill: parent
        hoverEnabled: true
        
        onEntered: controlButton.color = Theme.controls.hover-bg
        onExited:  controlButton.color = Theme.controls.bg
        onPressed: controlButton.color = Theme.controls.selected-bg
    }
}

The Theme.controls object resolves to the merged [controls] section from the active theme configuration.

Switching Themes via CLI

Activate a different theme to instantly swap [controls] values across the entire shell:


# Switch to the tokyo-night theme which includes its own [controls] definition

omarchy theme set tokyo-night

The shell references config/omarchy/shell.json to locate the theme directory, reloads the TOML, and reapplies all control states without requiring a session restart.

Summary

  • The [controls] section in colors.toml files defines the interactive state system for Omarchy themes, separating button and dropdown styling from generic [style] tokens.
  • Token inheritance uses a shallow-merge strategy, allowing users to override specific states (hover-bg, selected-fg, etc.) while retaining default values for unspecified properties.
  • The theme manager resolves tokens at runtime through Theme.controls accessors, enabling QML widgets to bind directly to configuration values.
  • Source documentation in docs/theming.md (line 275) and docs/omarchy-shell.md (lines 220-229) explicitly defines [controls] as the governing system for shared interactive chrome.
  • Theme switches propagate instantly to all UI components, providing a dynamic, configuration-driven desktop environment.

Frequently Asked Questions

What file format does Omarchy use for the [controls] interactive state system?

Omarchy uses TOML files named colors.toml located within individual theme directories (e.g., themes/tokyo-night/colors.toml or ~/.config/omarchy/themes/custom/colors.toml). The [controls] header within these files groups the interactive state tokens separately from [style] or [accent] sections.

How do I override default [controls] tokens without breaking existing themes?

Override tokens by creating a user-specific theme directory and defining only the keys you wish to change inside [controls]. The system performs a shallow merge, so any token you omit continues to inherit from the default theme loaded from the base installation.

Do [controls] tokens affect non-interactive UI elements?

No. According to the source documentation, [controls] only governs the shared button/dropdown chrome and explicitly excludes generic window backgrounds, text content, or decorative elements. Those properties reside under the [style] section or other specialized token groups.

Can I animate [controls] state changes in QML?

Yes. Because QML properties bind to Theme.controls values, you can apply standard QML animation behaviors (such as Behavior on color { ColorAnimation { duration: 150 } }) to properties driven by [controls] tokens. The theme system provides the values; the widget implementation handles the interpolation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →