hyprmoncfg

repository·main·Indexed 43 days ago

https://github.com/crmne/hyprmoncfg

A visual multi-monitor layout editor and automatic profile switcher for Hyprland. It features a TUI for arranging monitors, a CLI for profile management, and a daemon (hyprmoncfgd) that automatically applies hardware-aware profiles based on hotplug events or laptop lid status.

Tokens
18.4K
Snippets
71
Records
103
Agent score
57%

What's inside hyprmoncfg

  1. Overview of hyprmoncfg

    main

    hyprmoncfg is a terminal-first monitor configurator and auto-switching tool for Hyprland. It allows you to visually create multi-monitor layouts, save these configurations as profiles, and enable automatic profile switching triggered by monitor hotplug events or laptop lid events.

    Key characteristics:

    • Zero Dependencies: Ships as compiled Go binaries with no graphical toolkit or runtime dependencies required beyond Hyprland.
    • Profile-Based: Monitor setups are managed as discrete profiles that can be switched manually or automatically.
  2. What is hyprmoncfg?

    main

    hyprmoncfg is a terminal-first monitor configurator and auto-switching tool designed specifically for Hyprland. It allows you to create multi-monitor layouts using a spatial TUI (Terminal User Interface) with drag-and-drop capabilities, save these layouts as profiles, and switch between them automatically based on connected hardware.

    Key features include:

    • Spatial Layout Editor: A TUI canvas for visual monitor placement, snapping, and workspace planning.
    • Hardware-based Profiles: Profiles identify monitors by make, model, and serial number rather than connector names (e.g., DP-1), ensuring layouts persist even if ports are swapped.
    • Safe Apply Engine: Automatically writes monitor configurations, reloads Hyprland, and verifies the configuration was actually loaded. For Hyprland 0.55+ Lua configs, it uses the active Lua state to confirm the change and rolls back if it fails.
    • Zero Dependencies: Distributed as compiled Go binaries with only Hyprland as a runtime dependency (no Python, GTK, or D-Bus required).
  3. Overview of the hyprmoncfgd IPC Protocol

    main

    The hyprmoncfgd daemon uses a versioned Unix-socket protocol for controlling monitor configurations. The protocol is newline-delimited JSON (NDJSON) and is exposed via a socket located at:

    $XDG_RUNTIME_DIR/hyprmoncfgd.sock

    The socket has mode 0600.

    Important Ownership Rule: When the daemon is running, it is the canonical writer. Clients should not attempt to edit profiles or the active generated monitor file directly. The bundled TUI and CLI only fall back to the core engine when no daemon owns the session writer lock.

    Socket Path: $XDG_RUNTIME_DIR/hyprmoncfgd.sock
    Permissions: 0600
  4. Understand how hyprmoncfg manages generated files

    main

    hyprmoncfg manages files it creates and owns by marking them with Generated by hyprmoncfg on the first line.

    • Managed Files: If the marker is present, hyprmoncfg will fully manage and rewrite the file.
    • User-Owned Files: If the marker is missing, the file is treated as user-owned. The TUI/CLI will ask before replacing it, and the daemon/non-interactive CLI will refuse to replace it.
    • Safety: Files are written atomically (using a temporary file and rename) to prevent corruption.
    • Best Practice: Do not put unrelated settings (like render, cursor, or env) in the generated monitor files. Keep them in separate sourced files.
  5. How the Safe Preview Lifecycle works

    main

    The preview method creates a transaction that allows testing a profile without making it permanent.

    Lifecycle and Ownership

    • Only one preview can be active at a time.
    • If the client that created the preview disconnects, the preview remains active until its deadline expires.
    • A replacement client can reclaim a disconnected preview by sending the same transaction_id to confirm, commit, or revert.
    • A preview is marked as reclaimable in the status document (daemon.preview.reclaimable: true) only after the original owning connection has disappeared.
    • Warning: Do not show modal confirmations for a preview unless it was created by your connection or is explicitly marked as reclaimable.

    Completion and Rollback

    • Revert: A preview is reverted if the client calls revert, the deadline expires, the daemon shuts down, or monitor management is turned off. Rollback restores generated monitor rules and any root-config changes.
    • Confirm: Makes the profile a session-scoped override. Automatic best-match selection is paused until hardware changes, the daemon restarts, or set_profile_auto is called with enabled: true.
    • Commit: Completes the transaction and can atomically save the profile. Use save_on_commit: true in the preview call to perform a "keep and save" operation in one step.
  6. Handle laptop lid states in profiles

    main

    In hyprmoncfg, profiles are based on the attached monitor setup, not the lid state itself.

    When a laptop lid is closed while external monitors are connected:

    1. Applying a profile will force internal laptop-panel outputs off for that application.
    2. Workspace rules will automatically move away from the forced-off internal panel.

    Internal laptop panels are identified as internal displays in the layout view.

  7. How profile matching works in hyprmoncfgd

    main

    The daemon automatically selects a profile by scoring every JSON file in your profiles directory (~/.config/hyprmoncfg/profiles/) against the currently connected hardware. Profiles are matched by hardware identity (make, model, serial) rather than connector names.

    Scoring Logic

    ConditionPoints
    Monitor enabled in profile and connected+100
    Monitor disabled in profile but connected+50
    Connected monitor not in the profile−20
    Monitor enabled in profile but not connected−30
    Monitor disabled in profile and not connected−10

    Tie-breaking: The profile that wins is the one with the highest score. If scores are tied, the profile that comes first alphabetically by name wins.

    Best Practices for Reliable Auto-switching

    • Save one profile per unique monitor setup; avoid accumulating near-duplicates.
    • Delete experimental or "throwaway" profiles immediately, as the daemon scores every file in the profiles directory.
    • If the wrong profile is picked, check ~/.config/hyprmoncfg/profiles/ for forgotten files.
  8. How automatic reconciliation works in hyprmoncfg

    main

    The daemon uses an automatic matching system to preserve layouts.

    1. Matching: It attempts to preserve a complete saved layout already on screen before falling back to hardware scores.
    2. Persistence: Once a layout is matched, it stays active until hardware or lid state changes.
    3. Stability: To prevent unnecessary reloads, the following do NOT trigger reconciliation: VRR activity, equivalent buffer formats, or rounded scale readbacks.
    4. Triggers: Changes to the saved configuration (including config-only settings), layout, or workspace rules WILL trigger reconciliation.
  9. Manage Laptop Display settings via hyprmoncfg

    main

    The hyprmoncfg daemon integrates with Omarchy's native Laptop Display toggle.

    • Automatic Sync: When a profile disables the internal display while an external display is active, the daemon records this in Omarchy's manual-disable flag. This ensures Omarchy's wake and clamshell paths respect the setting and do not repeatedly enable the panel.
    • Manual Toggle: Changing Hardware → Laptop Display (or its keybinding) updates the active profile's internal-display setting.
    • Profile Persistence: The daemon uses the saved profile as a base, preserving position, scale, and mode when turning the display back on. If an external-only profile is used, enabling the laptop display adds it to the right of the existing layout.
    • Recovery vs Edits: Changes occurring during sleep, lid changes, or external-monitor reconnection are treated as recovery activity and do not modify your saved profiles.
  10. Understand profile contents and monitor identification

    main

    A profile JSON file contains:

    • Monitor outputs: Hardware identity (make, model, serial), resolution, refresh rate, scale, position, transform, and VRR mode.
    • Workspace settings: Strategy, max workspaces, group size, monitor order, and explicit rules.

    Hardware Identity: Monitors are identified by a hardware key (make|model|serial) rather than a connector name. This ensures profiles remain valid even if you swap cables or change ports between boots.

  11. Understand hyprmoncfg exit behavior and error handling

    main

    CLI Exit Codes

    hyprmoncfg commands exit with a non-zero status in the following cases:

    • Hyprland query failures
    • Invalid layouts
    • Missing profiles
    • Generated-config verification failures

    Lua Configuration Support

    For Hyprland users with Lua configs, the apply command reloads Hyprland and asks the active Lua state to confirm that the generated monitor file actually ran. If confirmation fails, it restores the previous file.

    Daemon and Locking

    • The daemon exits cleanly on SIGINT or SIGTERM.
    • Writer Lock: Only one monitor writer can run per user session. If the daemon owns the writer lock, the TUI and mutating CLI commands will automatically use its IPC socket.
  12. How hyprmoncfg works: The Apply Engine

    main

    Both the TUI (hyprmoncfg) and the daemon (hyprmoncfgd) use the same core engine to apply layouts. This ensures consistency and safety. The workflow is:

    1. Write: Generate the monitor configuration file (.conf or .lua).
    2. Reload: Trigger a Hyprland reload.
    3. Verify: Check the live state of the monitors.
    4. Confirm/Revert: If the result is incorrect, the engine can revert to the previous state. If correct, the change is finalized.

    When the daemon is running, it acts as the single writer via a versioned Unix-socket IPC. If the daemon is not running, the TUI and CLI operate in 'direct mode' by writing to files directly.