# Switcher Service in vorssaint-utils: Features, Configuration, and Implementation Guide

> Discover the Switcher service in vorssaint-utils. Explore its features like icon-row/grid layouts, custom shortcuts, live previews, and session management. Optimize your macOS window switching.

- Repository: [vorssaint/vorssaint-utils](https://github.com/vorssaint/vorssaint-utils)
- Tags: deep-dive
- Published: 2026-09-08

---

**The Switcher service in vorssaint-utils provides a highly configurable macOS window-switching panel with icon-row and grid layouts, customizable shortcuts, live window previews, and advanced session management.**

The vorssaint-utils repository delivers a powerful App Switcher feature through its Switcher service, offering macOS users a customizable alternative to the native Command-Tab interface. This Swift-based implementation supports multiple display modes, per-app rules, and robust event handling for seamless window navigation. Whether you need a compact icon bar or a full thumbnail grid, the Switcher service adapts to your workflow with extensive configuration options.

## Core Window-Switching Capabilities

The Switcher service operates as the central orchestrator for the App Switcher feature, handling everything from window enumeration to UI rendering. At its core, [`AppSwitcher.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/AppSwitcher.swift) manages the session lifecycle, while [`SwitcherView.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/SwitcherView.swift) renders the actual panel using SwiftUI.

The service supports two primary visual modes controlled by the `iconRowMode` and `simpleMode` settings. In [`Sources/Vorssaint/UI/Switcher/SwitcherView.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/Sources/Vorssaint/UI/Switcher/SwitcherView.swift), the `body` property (lines 56-64) automatically selects between `iconRowPanel` and `standardPanel` based on these user preferences. This allows the switcher to present either a compact horizontal row of application icons or a comprehensive grid showing live window thumbnails.

## Panel Layout Modes: Icon-Row vs. Grid

### Icon-Row Layout

The **icon-row layout** displays applications as a compact horizontal strip with configurable spacing and geometry. The `SwitcherIconRowLayout.compute(...)` method in [`Sources/Vorssaint/Services/Switcher/SwitcherSupport.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/Sources/Vorssaint/Services/Switcher/SwitcherSupport.swift) (lines 79-106) calculates:

- Visible icon count based on screen width
- Panel dimensions and positioning
- Horizontal spacing between icons
- Whether shortcut hint overlays appear

This layout supports **hover-edge behavior**: when the cursor remains on the last visible icon, the row automatically scrolls after a configurable interval. The timing constants `iconRowEdgeHoverInterval`, `iconRowEdgeHoverRepeatInterval`, and `iconRowEdgeHoverAnimationDuration` in [`SwitcherSupport.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/SwitcherSupport.swift) (lines 72-86) control this interaction.

### Grid Layout with Live Previews

The **standard grid layout** provides a visual overview of all open windows using captured thumbnails. The `SwitcherGrid` struct dynamically calculates rows and columns based on screen real estate and window count. Preview resolution is controlled by `captureAlphaGridSize` in [`SwitcherSupport.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/SwitcherSupport.swift) (lines 69-71), allowing performance tuning based on hardware capabilities.

Users can enable **minimal-preview mode** by setting the `minimalPreviews` AppStorage key, which disables the thin outline stroke around each thumbnail for a cleaner aesthetic (handled in [`SwitcherView.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/SwitcherView.swift), lines 80-84).

## Advanced Configuration Options

### Screen Placement Control

The **SwitcherScreenPlacement** enum in [`SwitcherSupport.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/SwitcherSupport.swift) (lines 93-104) defines three positioning strategies:
- **Pointer screen**: Opens on the display containing the cursor
- **Menu-bar screen**: Opens on the primary display with the menu bar
- **Active window screen**: Opens on the display containing the currently focused window

### Appearance Delay

Users can configure the delay before the panel appears when holding the activation shortcut. The default value is stored in `SwitcherSupport.defaultAppearanceDelayMilliseconds`, with sanitizing helpers ensuring valid ranges (lines 33-38).

### Session Scope Modes

The **SwitcherSessionScope** enum controls enumeration behavior:
- `allApps`: Lists all applications with their windows
- `frontmostApp`: Shows only windows belonging to the currently active application

## Keyboard Shortcuts and Navigation

### Global Shortcut Handling

The service intercepts system shortcuts using **SwitcherNativeSymbolicHotKey** (lines 48-60 in [`SwitcherSupport.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/SwitcherSupport.swift)), mapping hot-key IDs for:
- `command-tab` and `command-shift-tab` navigation
- Next/previous window selection
- Optional takeover of native macOS shortcuts

### Shortcut Hint Overlays

When enabled via `showsShortcutHints`, the panel displays visual indicators for available keyboard shortcuts. The **SwitcherShortcutHints** struct (lines 28-32) stores the hint strings rendered in the UI.

### Letter Actions

While the panel is visible, specific key presses trigger **SwitcherLetterAction** behaviors:
- `W`: Close the selected window
- `Q`: Quit the selected application
- `S`: Pin the search field

### Search and Pinning

The switcher includes a real-time search field that filters the window list. The **pinning feature** (`isSearchPinned`) allows users to continue typing without holding the modifier key. In [`SwitcherView.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/SwitcherView.swift) (lines 24-32), a visual chip indicates the pinned state, and the `searchQuery` property drives the filtering logic.

## Session Management and App Behavior

### Windowless App Entries

The **SwitcherWindowlessApps** enum (lines 62-73) handles applications without open windows:
- `off`: Hides windowless apps
- `finder`: Shows only Finder when it has no windows
- `all`: Displays all running apps regardless of window state

### App-Specific Rules

Per-application overrides allow fine-grained control via the **SwitcherAppRule** enum (lines 17-27):
- Force apps to appear without windows
- Restrict apps to windows-only display
- Hide specific applications entirely

### Hidden App Tracking

The service maintains state for hidden applications across sessions using functions like `isConfirmedHiddenAppWindow` (demonstrated in [`MetricsTests.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/MetricsTests.swift), lines 2769-2777), ensuring hidden apps reappear correctly in subsequent switching sessions.

### Merge Tabs Option

When `mergeWindowsByApp` is enabled (stored in AppStorage and honored in [`SwitcherView.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/SwitcherView.swift), lines 51-52), multiple windows from the same application collapse into a single selectable entry, reducing panel clutter.

### Robust Concurrency Handling

[`AppSwitcher.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/AppSwitcher.swift) (lines 21-46) implements thread-safe session management using `SwitcherPendingKeyDecision` and `SwitcherPendingSessionStart` enums with lock-protected state. This prevents race conditions during concurrent event-tap threads and ensures graceful cancellation when users release modifier keys before the panel appears.

## Implementation Architecture

The Switcher service relies on several coordinated components:

- **[`Sources/Vorssaint/Services/Switcher/SwitcherSupport.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/Sources/Vorssaint/Services/Switcher/SwitcherSupport.swift)**: Central definitions including enums, layout calculations, and timing constants
- **[`Sources/Vorssaint/Services/Switcher/AppSwitcher.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/Sources/Vorssaint/Services/Switcher/AppSwitcher.swift)**: Main orchestrator class managing enumeration, shortcuts, and UI state
- **[`Sources/Vorssaint/UI/Switcher/SwitcherView.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/Sources/Vorssaint/UI/Switcher/SwitcherView.swift)**: SwiftUI view implementing the panel rendering
- **[`Sources/Vorssaint/Services/Switcher/SwitcherModels.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/Sources/Vorssaint/Services/Switcher/SwitcherModels.swift)**: Data models for `SwitcherItem` and window identifiers
- **[`Sources/Vorssaint/UI/Settings/SwitcherAppRulesList.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/Sources/Vorssaint/UI/Settings/SwitcherAppRulesList.swift)**: Settings interface for per-app rule configuration

## Code Examples

### Activating the Switcher Programmatically

```swift
import Vorssaint

// Access the shared singleton instance
let switcher = AppSwitcher.shared

// Start a session listing all applications
switcher.startSession(scope: .allApps, reversed: false)

// Navigate using Tab / Shift-Tab or arrow keys

```

### Querying Window State

```swift
let windows = switcher.windows               // Array of SwitcherItem
let selected = switcher.selectedIndex        // Currently highlighted index
let totalCount = switcher.totalWindowCount   // Total window count

```

### Configuring User Preferences

```swift
// Enable compact icon-row mode
UserDefaults.standard.set(true, forKey: DefaultsKey.switcherIconRowMode)

// Display shortcut hint overlays
UserDefaults.standard.set(true, forKey: DefaultsKey.switcherShowShortcutHints)

```

### Customizing Appearance Timing

```swift
// Set 250ms delay before panel appears
UserDefaults.standard.set(250, forKey: DefaultsKey.switcherAppearanceDelay)

```

### Defining App-Specific Rules

```swift
// Force Music app to appear even without windows
let rules: [String: SwitcherAppRule] = ["com.apple.Music": .showWithoutWindows]
UserDefaults.standard.set(SwitcherAppRule.storedValue(rules),
                          forKey: DefaultsKey.switcherAppRules)

```

### Managing Windows and Search

```swift
// Close a specific window
if let window = switcher.windows.first {
    switcher.closeWindow(window)
}

// Pin the search field to release modifier key
switcher.isSearchPinned = true

```

## Summary

- The **Switcher service** provides dual layout modes (icon-row and grid) with automatic geometry calculations via `SwitcherIconRowLayout.compute()`.
- **Configuration options** include screen placement strategies, appearance delays, and session scopes (`allApps` vs `frontmostApp`).
- **Advanced features** encompass windowless app entries, per-app override rules via `SwitcherAppRule`, and hidden app state preservation.
- **Navigation enhancements** include global shortcut interception, letter actions (`W` for close, `Q` for quit), and a pinnable search field.
- **Thread-safe implementation** uses `SwitcherPendingKeyDecision` and lock-protected state in [`AppSwitcher.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/AppSwitcher.swift) to handle concurrent event taps safely.

## Frequently Asked Questions

### How does the Switcher service handle apps without open windows?

The service uses the `SwitcherWindowlessApps` enum defined in [`SwitcherSupport.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/SwitcherSupport.swift) to control visibility of windowless applications. You can configure it to hide all windowless apps, show only Finder, or display all running applications regardless of window state. This setting integrates with the Accessibility-based window enumeration performed by [`WindowEnumerator.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/WindowEnumerator.swift).

### What is the difference between icon-row mode and simple mode?

**Icon-row mode** displays a horizontal strip of application icons with optional shortcut hints and hover-edge scrolling. **Simple mode** (controlled by the `simpleMode` setting) further strips down the interface by hiding live previews entirely, showing only the icon bar. Simple mode is ideal for low-resource environments or users who prefer minimal visual overhead, as implemented in [`SwitcherView.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/SwitcherView.swift) lines 94-100.

### Can I customize which keyboard shortcuts activate the switcher?

Yes. The `SwitcherNativeSymbolicHotKey` enum maps symbolic hot-key IDs that the service registers with the WindowServer. While the default implementation uses Command-Tab bindings, the architecture supports custom shortcut takeovers. The [`AppSwitcher.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/AppSwitcher.swift) class handles the global event tap and translates these into `startSession` calls with appropriate `reversed` parameters for backward navigation.

### How does the search pinning feature work?

When you press the `S` key while the switcher is visible (as defined in `SwitcherLetterAction`), the `isSearchPinned` boolean toggles to true. This allows you to release the modifier key while continuing to type your search query. The UI displays a visual chip indicating the pinned state, and the `searchQuery` property filters the `windows` array in real-time without requiring held keys.