HyprDynamicMonitors Documentation

repository·main·Indexed 18 days ago

https://github.com/fiffeek/hyprdynamicmonitors

An event-driven service for Hyprland that automatically manages monitor configurations based on connected displays, power states (AC/battery), and laptop lid states. It features an interactive TUI for profile management, a 'freeze' command to capture current setups as templates, and a 'prepare' utility to prevent Hyprland boot failures caused by disabled monitors.

Tokens
35.4K
Snippets
130
Records
172
Agent score
62%

What's inside HyprDynamicMonitors

  1. What is HyprDynamicMonitors?

    main

    HyprDynamicMonitors is an event-driven service designed specifically for Hyprland to automatically manage monitor configurations based on connected displays and power states (e.g., AC vs. battery, or lid open/closed).

    It operates using a fail-fast architecture, meaning it is designed to exit quickly on critical errors rather than attempting complex recoveries. For production use, it is intended to be run under systemd or a wrapper script that provides automatic restarts to ensure reliability.

  2. Core Features of HyprDynamicMonitors

    main

    HyprDynamicMonitors provides several key capabilities for managing display profiles:

    • Event-driven automation: Responds in real-time to monitor connection/disconnection, power state changes, and lid events.
    • Interactive TUI: A standalone terminal user interface for visual monitor configuration and profile management.
    • Profile-based configuration: Allows defining different monitor settings for different hardware setups.
    • Template support: Enables dynamic configuration generation.
    • Hot reloading: Optionally watches configuration files and applies changes without a full service restart.
    • Theming: Supports built-in themes and dynamic theme generation based on wallpapers.
    • Desktop notifications: Optional notifications for configuration changes.
  3. What is scale snapping and why use it?

    main

    Scale snapping is a TUI feature that automatically adjusts your monitor scale to valid values that Hyprland can render without fractional pixels.

    Hyprland requires that the logical size of your display (physical pixels divided by scale) results in whole numbers. Using invalid scales (those that produce fractional logical pixels) can cause:

    • Blurry text and UI elements
    • Rendering artifacts
    • Incorrect pixel alignment
    • Visual glitches in applications

    Example (1920x1080 monitor):

    • Valid: Scale 1.5 → 1920÷1.5 = 1280, 1080÷1.5 = 720
    • Invalid: Scale 1.3 → 1920÷1.3 = 1476.92... (fractional pixels)
  4. What is `hyprdynamicmonitors prepare` and when to use it

    main

    The hyprdynamicmonitors prepare command is a utility designed to prevent Hyprland from failing to start when all monitors are disabled in your current profile.

    The Problem: Hyprland cannot start if its configuration file contains only disabled monitors (e.g., monitor=eDP-1,disable). If you use profiles that disable certain screens (like a laptop screen when using external monitors) and then unplug those monitors, Hyprland may boot into a blank screen because the configuration still instructs it to disable the only available display.

    The Solution: hyprdynamicmonitors prepare scans your destination configuration file (defined by config.general.destination) and removes all monitor=...,disable lines. This ensures Hyprland starts with a clean monitor configuration. Once Hyprland is running, hyprdynamicmonitors run will automatically re-apply your desired profile.

    When to use it: Only use this command if you use monitor=...,disable in any of your monitor profiles. If you do not disable monitors in your profiles, this command is unnecessary.

  5. Use .MonitorsByTag to reference specific monitors

    main

    The .MonitorsByTag variable is a map of tagged monitors (monitor_tag -> monitor object). This is the recommended way to reference specific hardware (like a laptop screen vs. an external monitor) without hardcoding connector names like eDP-1.

    {{- $laptop := index .MonitorsByTag "laptop" -}}
    {{- $external := index .MonitorsByTag "external" -}}
    
    monitor={{$laptop.Name}},2880x1920@120,0x0,2.0
    monitor={{$external.Name}},preferred,auto,1
  6. Using TUI markers for manual edits

    main

    When saving a profile via the TUI (using n or a), the TUI wraps the monitor configuration in special Go template markers:

    # <<<<< TUI AUTO START
    monitor=eDP-1,2880x1920@120.00000,0x0,2.0,vrr,1
    monitor=DP-1,3840x2160@60.00000,2880x0,1.0
    # <<<<< TUI AUTO END

    Best Practices for Manual Edits:

    • Preserve Edits: Add custom Hyprland directives (like windowrule or workspace) outside these markers. The TUI will only overwrite content inside the markers when you save.
    • Full Control: If you remove the markers entirely, the TUI will append a new markers block at the end of the file on the next save.
  7. Use Lid State in Hyprland Templates

    main

    Lid state can be used within Hyprland configuration templates to dynamically change monitor layouts (e.g., disabling the laptop screen when the lid is closed).

    Available Template Functions

    • isLidClosed: Returns true if the lid is closed.
    • isLidOpened: Returns true if the lid is open.
    • .LidState: Returns the lid state as a string: "Closed", "Opened", or "UNKNOWN" (if events are disabled or state is undetermined).
    {{if isLidClosed}}
    # Disable laptop screen when lid is closed
    monitor=eDP-1,disable
    {{else}}
    monitor=eDP-1,2880x1920@120,0x0,2.0
    {{end}}
  8. How HyprDynamicMonitors works

    main

    HyprDynamicMonitors (HDM) automates Hyprland monitor configurations by matching your current hardware setup to predefined profiles. The workflow follows these steps:

    1. Aggregate system information: Collects battery/lid states (optional).
    2. Aggregate Hyprland information: Detects currently connected outputs (via hyprctl monitors all).
    3. Read profiles: Loads user-defined profiles from config.toml.
    4. Match profiles: Compares connected monitors against each profile's required_monitors list.
    5. Render configuration: Generates the final Hyprland configuration at the config.general.destination location (e.g., ~/.config/hypr/monitors.conf) using either a Go template or a static file.

    This process can be automated by running the daemon, or performed manually via the TUI.

  9. Understand HyprDynamicMonitors systemd services

    main

    HyprDynamicMonitors uses two distinct systemd services to manage monitor configurations:

    1. hyprdynamicmonitors.service: The main daemon responsible for monitoring events and switching monitor profiles.
    2. hyprdynamicmonitors-prepare.service: A oneshot cleanup service that runs at boot (before Hyprland starts). It removes monitor=...,disable lines from your configuration to prevent Hyprland from failing to launch due to 'no active displays'.

    If you are using power or lid events, ensure UPower is enabled and running on your system.

  10. Use TUI markers for visual configuration

    main

    When using the interactive TUI to configure monitors, you can place <<<<< TUI AUTO START and <<<<< TUI AUTO END markers within your .go.tmpl file. The TUI will specifically target and update the section of the template contained between these markers when you apply changes visually. You can move these markers to any mode section to control which part of the template is editable via the TUI.

    {{ if eq .mode "presentation" }}
    # <<<<< TUI AUTO START
    monitor=desc:BOE NE135A1M-NY1,1920x1080@60,0x0,1.5,transform,0,vrr,0
    monitor=desc:LG Electronics 27GL850,1920x1080@60,0x0,1.0,transform,0,vrr,0
    # <<<<< TUI AUTO END
    {{ end }}
  11. Hyprland-Native Integration and Configuration

    main

    Instead of using a custom configuration format, HyprDynamicMonitors integrates with Hyprland by managing its native configuration. It detects the required state based on current monitors and power supply, then applies it via one of two methods:

    1. Templated Generation: Generates a templated Hyprland config file at a specified destination.
    2. Symlinking: Creates a symlink to a user-provided static configuration file.

    Note on Reloading: Hyprland automatically detects and applies these changes. If your Hyprland setup has automatic reloading disabled, you must use Hyprland callbacks to execute hyprctl reload to apply the changes made by the service.

  12. Understand Profile Structure and Configuration Types

    main

    Profiles in hyprdynamicmonitors define monitor configurations for specific hardware setups. Each profile specifies a configuration file and its type.

    There are two configuration types:

    1. Static Configuration: Plain Hyprland config files. The service creates a symlink to these files.
    2. Template Configuration: Files using Go template syntax for dynamic generation based on monitor properties and system state.

    A profile must define at least one required_monitor to be valid.

    [profiles.PROFILE_NAME]
    config_file = "path/to/config/file" # absolute or relative to config.toml
    config_file_type = "static"  # or "template"
    
    [profiles.PROFILE_NAME.conditions]
    # ... conditions ...
    
    [[profiles.PROFILE_NAME.conditions.required_monitors]]
    name = "eDP-1"