How to Use the BorderSurface QML API in Omarchy

The BorderSurface component in Omarchy accepts a borderSpec property—created via the Border singleton—to render optimized native borders or complex gradient/per-side borders through an automatic overlay fallback.

Omarchy's UI toolkit provides a standardized way to add borders to any rectangular element through the BorderSurface QML API. This component lives in shell/Ui/BorderSurface.qml and integrates with the Border singleton (shell/Commons/Border.qml) to deliver theme-aware, performant borders across the desktop environment. This guide shows you how to use the BorderSurface API with practical, runnable examples.

Core Architecture of the BorderSurface API

Understanding the three key components helps you use the API effectively.

Component Location Purpose
BorderSurface shell/Ui/BorderSurface.qml Rectangle-derived wrapper that exposes borderSpec, padding properties, and automatic BorderOverlay loading
Border shell/Commons/Border.qml Singleton factory for creating border specifications with helpers like canUseNative(), needsOverlay(), and per-side width accessors
BorderOverlay shell/Ui/BorderOverlay.qml Shape-based renderer for non-uniform borders or gradients when native Rectangle.border is insufficient

How BorderSurface Renders Borders

When you assign a borderSpec to BorderSurface, the component follows this decision path:

  1. Evaluate the specification — Border.canUseNative(borderSpec) checks if the border can use the cheap native Rectangle.border property (uniform width, solid color, no gradient).

  2. Choose rendering path —

    • Native path: Direct assignment to Rectangle.border for maximum performance
    • Overlay path: Sets usesOverlayBorder to true and loads BorderOverlay via a Loader to draw complex borders
  3. Compute content insets — Read-only properties contentTopInset, contentRightInset, contentBottomInset, and contentLeftInset combine resolved border widths with padding values so child items position correctly.

Creating Border Specifications with the Border Singleton

The Border singleton provides factory methods for common specification patterns.

Border.flat() — Simple Static Borders

Use Border.flat(color, width) for uniform, solid-color borders.

import QtQuick 2.15
import qs.Commons  // Brings in Border singleton

BorderSurface {
    width: 200
    height: 100
    borderSpec: Border.flat("#4a90e2", 3)   // 3 px solid blue border
    padding: 8

    Text {
        anchors.centerIn: parent
        text: "Hello Omarchy"
        color: "#fff"
    }
}

Border.surfaceSpec() — Theme-Driven Borders

Use Border.surfaceSpec(section, token, fallbackColor, fallbackWidth, alphaKey) to resolve values from Omarchy's theme configuration.

import QtQuick 2.15
import qs.Commons

BorderSurface {
    width: 300
    height: 150
    borderSpec: Border.surfaceSpec("panel", "border", "#222", 1, "border-alpha")
    padding: 12

    Image {
        anchors.fill: parent
        source: "qrc:/icons/logo.svg"
        fillMode: Image.PreserveAspectFit
    }
}

This example pulls the border definition from the [panel] section of the theme, using the border token with fallback values and alpha channel lookup.

Advanced Gradient and Per-Side Borders

When you need gradients or non-uniform widths, BorderSurface automatically falls back to BorderOverlay.

Gradient Border with Manual Specification

import QtQuick 2.15
import qs.Commons

BorderSurface {
    width: 250
    height: 120

    borderSpec: {
        let spec = Border.flat("transparent", 0);
        spec.gradient = { 
            colors: ["#ff7e5f", "#feb47b"], 
            angle: 45, 
            enabled: true 
        };
        spec.widths = { top: 4, right: 4, bottom: 4, left: 4 };
        return spec;
    }

    padding: 10

    Rectangle {
        anchors.fill: parent
        color: "#1e1e1e"
        radius: 8
    }
}

The presence of gradient.enabled: true triggers Border.needsOverlay(spec) to return true, causing BorderSurface to instantiate BorderOverlay internally.

Controlling Padding and Content Insets

BorderSurface provides flexible padding control that combines with border widths to produce final content insets.

Padding Properties

Property Default Description
padding 0 Sets all sides to the same value
topPadding padding Overrides top inset
rightPadding padding Overrides right inset
bottomPadding padding Overrides bottom inset
leftPadding padding Overrides left inset

Content Inset Properties (Read-Only)

These computed properties tell child items how much space to leave for borders and padding:

  • contentTopInset = borderSpec.topWidth + topPadding
  • contentRightInset = borderSpec.rightWidth + rightPadding
  • contentBottomInset = borderSpec.bottomWidth + bottomPadding
  • contentLeftInset = borderSpec.leftWidth + leftPadding

Use these when positioning children that must not overlap the border area:

BorderSurface {
    id: surface
    borderSpec: Border.surfaceSpec("window", "border", "#333", 2)
    padding: 10

    Text {
        anchors {
            top: parent.top
            left: parent.left
            topMargin: surface.contentTopInset
            leftMargin: surface.contentLeftInset
        }
        text: "Positioned inside border"
    }
}

Helper Utilities in BorderGeometry.js

The shell/Commons/BorderGeometry.js module provides low-level utilities used by both Border and BorderSurface:

  • Width string parsing (e.g., "1 2 3 4" → per-side values)
  • Maximum width calculation for overlay bounds
  • Overlay need detection based on specification complexity

You rarely interact with this directly, but it's available for custom border implementations.

Summary

  • BorderSurface (shell/Ui/BorderSurface.qml) is the primary component for bordered rectangles in Omarchy

  • Border singleton (shell/Commons/Border.qml) creates specifications via Border.flat() and Border.surfaceSpec()

  • Automatic optimization — Native Rectangle.border for simple borders, BorderOverlay for gradients and per-side widths

  • Computed insets — contentTopInset and siblings combine border widths with padding for proper child positioning

  • Theme integration — Border.surfaceSpec() resolves values from Omarchy's centralized theme configuration

Frequently Asked Questions

How do I know if my border will use the native or overlay renderer?

Call Border.canUseNative(borderSpec) or check Border.needsOverlay(borderSpec) before assignment. Native rendering requires uniform width, solid color, and no gradient. Any deviation triggers overlay fallback.

Can I use BorderSurface without importing qs.Commons?

No. The Border singleton lives in qs.Commons, so you must import it to create valid borderSpec objects. The BorderSurface type itself comes from qs.Ui or your local shell/Ui import path.

What happens if the theme token doesn't exist in surfaceSpec()?

Border.surfaceSpec() uses the fallbackColor and fallbackWidth parameters you provide. In the example Border.surfaceSpec("panel", "border", "#222", 1, "border-alpha"), a missing panel.border token results in a 1-pixel #222 border.

Is there a performance cost to gradient borders?

Yes. Gradient borders always use BorderOverlay, which creates a Shape item with ShapePath elements. This is more expensive than native Rectangle.border but necessary for visual effects that Qt Quick's native border cannot express.

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 →