How Omarchy Integrates with Hyprland: Window Gaps, Monitor Focus, and Reload Guards

Omarchy extends Hyprland through Lua modules that implement reload guards to prevent stale state, dynamic window gap toggles, and monitor-aware event handlers that synchronize widgets across displays.

Omarchy is an open-source desktop environment that deeply integrates with the Hyprland compositor through custom Lua scripting. When you configure Omarchy to integrate with Hyprland, it injects bootstrap logic, toggle commands, and event listeners directly into Hyprland's configuration lifecycle. This integration enables real-time gap adjustments, intelligent module reloading, and responsive monitor focus tracking without requiring session restarts.

Reload Guard Mechanism

The reload guard ensures that Omarchy's Lua modules are freshly loaded when Hyprland reloads its configuration, while preserving third-party modules. This prevents stale state from persisting across hyprctl reload commands.

Selective Module Clearing

In default/hypr/bootstrap.lua, Omarchy defines a set of module prefixes that identify its own code. The should_reload_module function checks if a loaded module matches any of these prefixes before clearing it from package.loaded.

-- https://github.com/omacom/omarchy/blob/quattro/default/hypr/bootstrap.lua#L4-L18
local reload_prefixes = {
  "default.hypr",
  "hypr",
  "omarchy.current.theme",
}

local function should_reload_module(module)
  for _, prefix in ipairs(reload_prefixes) do
    if module == prefix or module:sub(1, #prefix + 1) == prefix .. "." then
      return true
    end
  end
  return false
end

When Hyprland reloads, the bootstrap iterates over package.loaded, removes matching modules by setting them to nil, and leaves external dependencies intact.

Package Path Reconstruction

After clearing stale modules, the bootstrap reconstructs package.path to prioritize user-specific configuration directories over system defaults. This ensures that modifications in ~/.config/ or ~/.local/state/ take precedence immediately.

-- https://github.com/omacom/omarchy/blob/quattro/default/hypr/bootstrap.lua#L31-L39
package.path = home .. "/.local/state/?.lua;" ..
               home .. "/.config/?.lua;" ..
               (os.getenv("OMARCHY_PATH") or "/usr/share/omarchy") .. "/?.lua;" ..
               package.path

Window Gaps Toggle System

Omarchy exposes a window gaps toggle that switches between default spacing and zero-gap layouts without requiring a configuration reload.

Command Registration and Keybindings

The toggle command omarchy-hyprland-window-gaps-toggle is registered in two locations. First, in default/omarchy/omarchy-menu.jsonc as a UI menu entry:

// https://github.com/omacom/omarchy/blob/quattro/default/omarchy/omarchy-menu.jsonc#L98
"trigger.toggle.window-gaps": {"icon":"","label":"Window Gaps","action":"omarchy-hyprland-window-gaps-toggle"}

Second, in default/hypr/bindings/utilities.lua as a keyboard shortcut:

-- https://github.com/omacom/omarchy/blob/quattro/default/hypr/bindings/utilities.lua#L20
o.bind("SUPER + SHIFT + BACKSPACE", "Toggle window gaps", "omarchy-hyprland-window-gaps-toggle")

Gap State Implementation

The actual toggle logic resides in default/hypr/toggles/window-no-gaps.lua. This script reads the current gaps_in and gaps_out values from Hyprland's live configuration, swaps them between default values (typically gaps_in = 5, gaps_out = 10) and zero gaps (gaps_in = 0, gaps_out = 0), and applies the changes immediately via Hyprland's dispatch system. No session restart is required for the changes to take effect.

Monitor Focus Event Handling

To maintain UI consistency across multiple displays, Omarchy listens to Hyprland's monitor.focused events and recalculates widget geometries dynamically.

Event Listener Registration

In default/hypr/qconsole.lua, Omarchy registers a callback function named fit to handle monitor focus changes:

-- https://github.com/omacom/omarchy/blob/quattro/default/hypr/qconsole.lua#L27-L33
hl.on("monitor.focused", fit)

Hyprland emits this event whenever the active monitor changes, such as when using CTRL + ALT + TAB to cycle displays.

Dynamic UI Synchronization

The fit function updates the geometry of screen-aware components including the qconsole overlay, dynamic notification widgets, and the "focus-app" launcher. By reacting to focus events in real-time, Omarchy ensures that all positioned UI elements align correctly with the current monitor's dimensions and offset.

Practical Configuration Examples

Custom Monitor Focus Handler

You can extend the monitor focus behavior by creating a custom handler in your user configuration:

-- ~/.config/hypr/custom-focus.lua
local hl = require("omarchy.helpers")

local function my_focus_handler(info)
  -- info contains monitor id, geometry, etc.
  print("Monitor focused:", info.name, info.geometry)
  hl.dispatch(hl.dsp.notify({title="Monitor", body=info.name}))
end

hl.on("monitor.focused", my_focus_handler)

Manual Gap Toggle from Command Line

Execute the toggle directly without using the keybinding:

omarchy-hyprland-window-gaps-toggle

Forcing a Clean Reload

When you need to reload Hyprland configuration while ensuring Omarchy clears its internal state:

hyprctl reload

The bootstrap script automatically detects the reload and clears Omarchy-specific modules from package.loaded before reinitializing.

Summary

  • Reload Guard: The default/hypr/bootstrap.lua script filters package.loaded using prefix matching (default.hypr, hypr, omarchy.current.theme) to clear only Omarchy modules during configuration reloads.
  • Window Gaps: The omarchy-hyprland-window-gaps-toggle command, bound to SUPER + SHIFT + BACKSPACE in default/hypr/bindings/utilities.lua, switches gap values between default and zero without restarting Hyprland.
  • Monitor Focus: The fit function in default/hypr/qconsole.lua handles monitor.focused events to keep widgets synchronized with the active display geometry.
  • Module Path: Omarchy reconstructs package.path to prioritize user directories (~/.local/state, ~/.config) over system paths ($OMARCHY_PATH).

Frequently Asked Questions

How does Omarchy prevent stale Lua modules when Hyprland reloads?

Omarchy implements a reload guard in default/hypr/bootstrap.lua that iterates through package.loaded and removes modules matching specific prefixes (default.hypr, hypr, omarchy.current.theme). This selective clearing ensures that Omarchy's code refreshes on hyprctl reload while third-party Lua modules remain cached and unaffected.

What is the default keybinding to toggle window gaps in Omarchy?

The default keybinding is SUPER + SHIFT + BACKSPACE, defined in default/hypr/bindings/utilities.lua. This triggers the omarchy-hyprland-window-gaps-toggle command, which switches between configured gap values and zero gaps in default/hypr/toggles/window-no-gaps.lua without requiring a configuration reload.

How does Omarchy handle monitor switching in Hyprland?

Omarchy registers an event listener in default/hypr/qconsole.lua using hl.on("monitor.focused", fit). When Hyprland emits a focus event (triggered by display switching), the fit function recalculates widget positions for the qconsole overlay, notification system, and focus-app launcher to match the new monitor's geometry.

Where is the Hyprland bootstrap entry point located in Omarchy?

The bootstrap script is located at default/hypr/bootstrap.lua within the Omarchy repository. This file is typically sourced from the user's ~/.config/hypr/hyprland.lua (or the system-wide default) and handles module prefix filtering, package path reconstruction, and initial library loading for the Hyprland session.

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 →