Dynamic Profile Modes Pattern
What are dynamic profile modes?
Dynamic profile modes allow a single profile to adapt its behavior based on context without creating multiple separate profiles. This is useful when you want different monitor configurations for the same physical setup depending on what you're doing (e.g., gaming, presenting, working).
Instead of creating home-gaming, home-presentation, and home-standard profiles, you can have one home profile that changes its configuration based on a mode variable.
When to use this pattern
Use dynamic profile modes when:
- You have the same monitor setup but need different configurations for different activities
- You want to quickly switch between configurations without disconnecting/reconnecting monitors
- You need context-specific settings (refresh rates, scaling, positioning) for the same hardware
Examples:
- Switch between high refresh rate for gaming and lower refresh rate for power saving
- Mirror displays for presentations but extend them for regular work
- Different scaling factors for reading vs. video editing
TUI Demo
Everything in this guide can be accomplished using the TUI:

Prerequisites
This feature requires the hyprdynamicmonitors daemon to be running, as it monitors your configuration file for changes and automatically re-renders profiles when you switch modes:
hyprdynamicmonitors run
Or in your Hyprland config:
exec-once = hyprdynamicmonitors run
Setting up dynamic modes
Let's assume you have the following configuration:
[general]
destination = "$HOME/.config/hypr/config.d/99_autogenerated-monitors.conf"
[profiles.home]
config_file = "hyprconfigs/home.go.tmpl"
config_file_type = "template"
[[profiles.home.conditions.required_monitors]]
name = "eDP-1"
monitor_tag = "laptop"
[[profiles.home.conditions.required_monitors]]
name = "DP-11"
monitor_tag = "external"
With a simple template created by the TUI at hyprconfigs/home.go.tmpl:
# <<<<< TUI AUTO START
monitor=desc:BOE NE135A1M-NY1,2880x1920@120.00000,0x0,2.00000000,transform,0,vrr,1
monitor=desc:LG Electronics LG SDQHD 301NTBKDU037,2560x2880@59.96700,-1800x0,1.60000000,transform,3,vrr,0
# <<<<< TUI AUTO END
The problem
Sometimes at home, you use the same setup differently - maybe to play games or run a presentation. You'd like the home profile to "specialize" depending on the context.
Since hyprdynamicmonitors monitors your configuration for changes, it's easy to combine the TUI and daemon to achieve this.
Step 1: Add a mode variable
First, add a mode static variable to your profile:
[profiles.home.static_template_values]
mode = "standard"
Your complete configuration now looks like this:
[general]
destination = "$HOME/.config/hypr/config.d/99_autogenerated-monitors.conf"
[profiles.home]
config_file = "hyprconfigs/home.go.tmpl"
config_file_type = "template"
[profiles.home.static_template_values]
mode = "standard"
[[profiles.home.conditions.required_monitors]]
name = "eDP-1"
monitor_tag = "laptop"
[[profiles.home.conditions.required_monitors]]
name = "DP-11"
monitor_tag = "external"
Step 2: Wrap the template in a conditional
Now adjust your template (hyprconfigs/home.go.tmpl) to use the mode variable:
{{ if eq .mode "standard" }}
# <<<<< TUI AUTO START
monitor=desc:BOE NE135A1M-NY1,2880x1920@120.00000,0x0,2.00000000,transform,0,vrr,1
monitor=desc:LG Electronics LG SDQHD 301NTBKDU037,2560x2880@59.96700,-1800x0,1.60000000,transform,3,vrr,0
# <<<<< TUI AUTO END
{{ end }}
This means the monitor lines will only render when mode is set to "standard".
Step 3: Add additional modes
Now add a presentation mode. Edit your template to add a new conditional block:
{{ if eq .mode "standard" }}
monitor=desc:BOE NE135A1M-NY1,2880x1920@120.00000,0x0,2.00000000,transform,0,vrr,1
monitor=desc:LG Electronics LG SDQHD 301NTBKDU037,2560x2880@59.96700,-1800x0,1.60000000,transform,3,vrr,0
{{ end }}
{{ if eq .mode "presentation" }}
# <<<<< TUI AUTO START
# <<<<< TUI AUTO END
{{ end }}
Important: We moved the TUI markers (# <<<<< TUI AUTO START/END) from the standard section to the presentation section. This tells the TUI which mode's configuration to update when you apply changes.
Understanding TUI markers:
The TUI markers tell hyprdynamicmonitors where to insert newly configured monitors. When you:
- Edit monitors in the TUI
- Press
ain the Profile pane to apply
The configuration gets inserted between these markers. By placing the markers in the presentation block, we're saying "when I apply from the TUI, update the presentation mode configuration."
Step 4: Configure the presentation mode using the TUI
Now let's set up a different configuration for presentation mode. The workflow is:
4a) Switch to presentation mode in your config:
Edit ~/.config/hyprdynamicmonitors/config.toml:
[profiles.home.static_template_values]
mode = "presentation" # Changed from "standard"
The daemon will detect this change and switch to presentation mode.
4b) Configure monitors in the TUI:
Open the TUI:
hyprdynamicmonitors tui
Edit your monitors as needed for presentation mode (e.g., mirror displays, different refresh rates, etc.).
4c) Apply the configuration:
Press a in the Profile pane. This writes your configuration between the TUI markers in the presentation block.
Result:
Your template now has different configurations for each mode:
{{ if eq .mode "standard" }}
monitor=desc:BOE NE135A1M-NY1,2880x1920@120.00000,0x0,2.00000000,transform,0,vrr,1
monitor=desc:LG Electronics LG SDQHD 301NTBKDU037,2560x2880@59.96700,-1800x0,1.60000000,transform,3,vrr,0
{{ end }}
{{ if eq .mode "presentation" }}
# <<<<< TUI AUTO START
# Mirror displays for presentation
monitor=desc:BOE NE135A1M-NY1,2880x1920@60.00000,0x0,1.60000000,transform,0,vrr,0
monitor=desc:LG Electronics LG SDQHD 301NTBKDU037,2560x2880@60.00000,0x0,1.60000000,transform,0,vrr,0
# <<<<< TUI AUTO END
{{ end }}
Note: The example above shows mirrored displays at 60Hz for presentation mode, while standard mode uses different positioning and 120Hz.
How it works
Here's what happens behind the scenes:
-
The daemon watches your config file - When running,
hyprdynamicmonitorsmonitors~/.config/hyprdynamicmonitors/config.tomlfor changes -
You change the mode variable - When you edit
mode = "presentation"in the config file, the daemon detects the change immediately -
Template is re-rendered - The daemon re-evaluates the template with the new mode value, so only the matching
{{ if eq .mode "presentation" }}block is rendered -
Hyprland config is updated - The rendered output is written to your Hyprland config destination (e.g.,
99_autogenerated-monitors.conf) -
Hyprland applies the changes - Hyprland automatically reloads the monitor configuration
All of this happens automatically without restarting anything!
Switching between modes
Now depending on the context, different configurations will be rendered by the daemon.
Manual switching
To switch modes, edit your config.toml and change the mode variable:
[profiles.home.static_template_values]
mode = "presentation"
The daemon will automatically detect the change and re-render the profile with the new mode. No need to restart anything!
Automated switching with scripts
You can create bash scripts to switch modes automatically. Here's an example:
Switch to presentation mode:
#!/bin/bash
# ~/scripts/presentation-mode.sh
CONFIG_FILE="$HOME/.config/hyprdynamicmonitors/config.toml"
# Use sed to change the mode value
sed -i 's/mode = ".*"/mode = "presentation"/' "$CONFIG_FILE"
echo "Switched to presentation mode"
Switch to standard mode:
#!/bin/bash
# ~/scripts/standard-mode.sh
CONFIG_FILE="$HOME/.config/hyprdynamicmonitors/config.toml"
sed -i 's/mode = ".*"/mode = "standard"/' "$CONFIG_FILE"
echo "Switched to standard mode"
Make them executable:
chmod +x ~/scripts/presentation-mode.sh
chmod +x ~/scripts/standard-mode.sh
Bind to Hyprland keybindings:
# ~/.config/hypr/hyprland.conf
bind = $mainMod SHIFT, P, exec, ~/scripts/presentation-mode.sh
bind = $mainMod SHIFT, S, exec, ~/scripts/standard-mode.sh
Advanced: Mode-specific variables
You can also use different template variables for each mode:
[profiles.home.static_template_values]
mode = "standard"
gaming_refresh_rate = "144"
standard_refresh_rate = "60"
Then in your template:
{{ if eq .mode "standard" }}
monitor=desc:BOE NE135A1M-NY1,2880x1920@{{ .standard_refresh_rate }},0x0,2.00000000
{{ end }}
{{ if eq .mode "gaming" }}
monitor=desc:BOE NE135A1M-NY1,2880x1920@{{ .gaming_refresh_rate }},0x0,2.00000000
{{ end }}
Complete workflow summary
Here's the full workflow for setting up and using dynamic modes:
-
Initial setup:
- Create a profile with a template
- Add
static_template_valueswith amodevariable - Wrap template sections in
{{ if eq .mode "..." }}conditionals
-
Adding a new mode:
- Add a new conditional block in the template (e.g.,
{{ if eq .mode "gaming" }}) - Place TUI markers in that block
- Change mode in
config.tomlto the new mode - Configure monitors in TUI and press
ato apply
- Add a new conditional block in the template (e.g.,
-
Switching modes:
- Edit
config.tomland change the mode value - Or run a script that modifies the mode value
- The daemon automatically detects and applies the change
- Edit
-
Editing an existing mode:
- Move TUI markers to the mode you want to edit
- Change mode in
config.tomlto that mode - Open TUI, make changes, press
ato apply
Dynamic modes vs. separate profiles
Use dynamic modes when:
- Same physical monitor setup (same monitors connected)
- Different configurations for different activities
- Want quick switching via scripts/keybindings
- Example: Home setup with gaming/work/presentation modes
Use separate profiles when:
- Different physical setups (different monitors connected)
- Different locations (home/office/mobile)
- Different hardware conditions (docked/undocked, AC/battery, lid open/closed)
- Example: Separate profiles for home (external monitor), office (dual monitors), and mobile (laptop only)
You can combine both approaches: Have separate profiles for different locations, and each profile can have dynamic modes for different activities at that location.
Tips
-
TUI marker placement: You can move the
<<<<< TUI AUTO START/ENDmarkers to any mode section. The TUI will update whichever section contains the markers when you apply changes. -
Multiple variables: Combine multiple variables (not just
mode) to create even more flexible configurations:~/.config/hyprdynamicmonitors/config.toml[profiles.home.static_template_values]
mode = "standard"
scaling = "2.0"
vrr_enabled = "1" -
Testing modes: Use
--dry-runto test mode changes without applying them:hyprdynamicmonitors run --run-once --dry-run -
Default mode: Always set a default mode in your config to ensure the profile works even if you forget to specify one.
-
Debugging: If a mode switch doesn't work, check the daemon logs with
--debugto see which template block is being rendered.
Practical example: Gaming vs. productivity
Here's a real-world example with three modes for a home setup:
config.toml:
[general]
destination = "$HOME/.config/hypr/config.d/99_autogenerated-monitors.conf"
[profiles.home]
config_file = "hyprconfigs/home.go.tmpl"
config_file_type = "template"
[profiles.home.static_template_values]
mode = "productivity" # Default mode
[[profiles.home.conditions.required_monitors]]
name = "eDP-1"
monitor_tag = "laptop"
[[profiles.home.conditions.required_monitors]]
name = "DP-11"
monitor_tag = "gaming_monitor"
hyprconfigs/home.go.tmpl:
{{ if eq .mode "productivity" }}
# Productivity: Extended displays, laptop on left, 60Hz for battery saving
monitor=desc:BOE NE135A1M-NY1,2880x1920@60,0x0,2.0,transform,0,vrr,0
monitor=desc:LG Electronics 27GL850,2560x1440@60,1440x0,1.0,transform,0,vrr,0
{{ end }}
{{ if eq .mode "gaming" }}
# Gaming: Disable laptop screen, gaming monitor only at 144Hz
monitor=desc:BOE NE135A1M-NY1,disable
monitor=desc:LG Electronics 27GL850,2560x1440@144,0x0,1.0,transform,0,vrr,1
{{ end }}
{{ if eq .mode "presentation" }}
# <<<<< TUI AUTO START
# Presentation: Mirror displays at same resolution
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 }}
Switching scripts:
# ~/scripts/hdm-gaming.sh
#!/bin/bash
sed -i 's/mode = ".*"/mode = "gaming"/' ~/.config/hyprdynamicmonitors/config.toml
notify-send "HDM" "Switched to gaming mode"
# ~/scripts/hdm-productivity.sh
#!/bin/bash
sed -i 's/mode = ".*"/mode = "productivity"/' ~/.config/hyprdynamicmonitors/config.toml
notify-send "HDM" "Switched to productivity mode"
# ~/scripts/hdm-presentation.sh
#!/bin/bash
sed -i 's/mode = ".*"/mode = "presentation"/' ~/.config/hyprdynamicmonitors/config.toml
notify-send "HDM" "Switched to presentation mode"
Hyprland keybindings:
bind = $mainMod SHIFT, G, exec, ~/scripts/hdm-gaming.sh
bind = $mainMod SHIFT, P, exec, ~/scripts/hdm-productivity.sh
bind = $mainMod SHIFT, M, exec, ~/scripts/hdm-presentation.sh
Now you can instantly switch between gaming (high refresh rate, single monitor), productivity (dual monitors, power saving), and presentation (mirrored displays) with a simple keybinding!