Skip to content

Multi Monitor

NullString1 edited this page Jan 13, 2026 · 1 revision

Multi-Monitor Setup

Configuring multiple displays in NullOS with Hyprland.

Overview

Hyprland supports multi-monitor setups with per-monitor configuration for:

  • Resolution and refresh rate
  • Position and rotation
  • Scale and transform
  • Wallpapers
  • Workspaces

Quick Start

Automatic Configuration

Hyprland auto-detects monitors:

# List connected monitors
hyprctl monitors
# Sample output:# Monitor eDP-1 (ID 0):# 1920x1080@60Hz at 0x0# scale: 1.00# ...

Basic Configuration

In home/hyprland/settings.nix:

monitor=["eDP-1,1920x1080@60,0x0,1""HDMI-A-1,1920x1080@60,1920x0,1"];

Format:name,resolution@rate,position,scale


Monitor Naming

Find Monitor Names

# While displays are connected
hyprctl monitors
# Shows:# Monitor HDMI-A-1 (ID 1):# ...

Common Names

Laptops:

  • eDP-1 - Internal laptop display
  • eDP-2 - Less common second internal display

External:

  • HDMI-A-1, HDMI-A-2 - HDMI ports
  • DP-1, DP-2, DP-3 - DisplayPort
  • DVI-D-1 - DVI port
  • VGA-1 - VGA port (rare)

NVIDIA: When using NVIDIA, names may include HDMI-1-0 format.


Resolution & Refresh Rate

Standard Resolution

monitor=["HDMI-A-1,1920x1080@60,auto,1"];

High Refresh Rate

monitor=["DP-1,2560x1440@144,auto,1"];

4K Display

monitor=["HDMI-A-1,3840x2160@60,auto,1.5"# With scaling];

List Available Modes

# Get supported resolutions/rates
hyprctl monitors | grep -A 20 "Monitor HDMI-A-1"

Or use GUI tool:

nwg-displays

Positioning

Automatic Positioning

monitor=["eDP-1,1920x1080@60,auto,1""HDMI-A-1,1920x1080@60,auto,1"];

Hyprland arranges monitors automatically.

Manual Positioning

monitor=[# Laptop screen at 0,0"eDP-1,1920x1080@60,0x0,1"# External monitor to the right"HDMI-A-1,1920x1080@60,1920x0,1"];

Coordinates:

  • 0x0 - Top-left corner
  • 1920x0 - 1920 pixels to the right
  • 0x1080 - 1080 pixels down

Vertical Stacking

monitor=[# Top monitor"HDMI-A-1,1920x1080@60,0x0,1"# Bottom monitor"HDMI-A-2,1920x1080@60,0x1080,1"];

Complex Layout

monitor=[# Center main display"DP-1,2560x1440@144,0x0,1"# Left vertical display"HDMI-A-1,1920x1080@60,-1080x0,1,transform,1"# Right display"HDMI-A-2,1920x1080@60,2560x0,1"];

Scaling

Fractional Scaling

monitor=[# 1.5x scaling for 4K"HDMI-A-1,3840x2160@60,auto,1.5"# 2x scaling for very high DPI"eDP-1,2880x1800@60,auto,2"];

Common scales:

  • 1 - No scaling (1080p, 1440p)
  • 1.25 - Small increase (2K on 24")
  • 1.5 - Recommended for 4K 27"
  • 2 - Apple Retina style (4K 24")

Per-Monitor DPI

Different monitors can have different scales:

monitor=["eDP-1,1920x1080@60,0x0,1"# Laptop: no scaling"HDMI-A-1,3840x2160@60,1920x0,1.5"# 4K: scaled];

Rotation & Transform

Rotate Display

monitor=["HDMI-A-1,1920x1080@60,auto,1,transform,1"];

Transform values:

  • 0 - Normal
  • 1 - 90° clockwise
  • 2 - 180°
  • 3 - 270° clockwise
  • 4 - Flipped
  • 5 - Flipped + 90°
  • 6 - Flipped + 180°
  • 7 - Flipped + 270°

Vertical Monitor

monitor=[# Main horizontal"DP-1,2560x1440@144,0x0,1"# Side vertical"HDMI-A-1,1920x1080@60,2560x0,1,transform,1"];

Note: Position uses rotated dimensions.


Mirroring

Mirror Displays

monitor=["eDP-1,1920x1080@60,0x0,1""HDMI-A-1,1920x1080@60,0x0,1,mirror,eDP-1"];

Clone with Different Scaling

monitor=["eDP-1,1920x1080@60,0x0,1""HDMI-A-1,3840x2160@60,0x0,2,mirror,eDP-1"];

Disabling Monitors

Disable Specific Monitor

monitor=["eDP-1,disable"# Turn off laptop screen"HDMI-A-1,1920x1080@60,0x0,1"];

Conditional Disable

# When lid closed, disable laptop screenbindl=[",switch:on:Lid Switch,exec,hyprctl keyword monitor eDP-1,disable"",switch:off:Lid Switch,exec,hyprctl keyword monitor eDP-1,1920x1080@60,0x0,1"];

Per-Monitor Configuration

Wallpapers

With hyprpaper:

# hyprpaper.confpreload = ~/wallpapers/wall1.png
preload = ~/wallpapers/wall2.png
wallpaper = eDP-1,~/wallpapers/wall1.png
wallpaper = HDMI-A-1,~/wallpapers/wall2.png

Workspaces

Bind workspaces to specific monitors:

workspace=["1, monitor:eDP-1""2, monitor:eDP-1""3, monitor:HDMI-A-1""4, monitor:HDMI-A-1"];

Or default monitor per workspace:

workspace=["1, monitor:eDP-1, default:true""3, monitor:HDMI-A-1, default:true"];

Dynamic Configuration

Runtime Changes

# Change resolution
hyprctl keyword monitor HDMI-A-1,1920x1080@60,auto,1
# Disable monitor
hyprctl keyword monitor eDP-1,disable
# Enable monitor
hyprctl keyword monitor eDP-1,preferred,auto,1

Monitor Hotplug

Hyprland automatically handles monitor connection/disconnection.

Auto-enable:

monitor=[",preferred,auto,1"# Catch-all for unknown monitors];

Laptop Configurations

Docked Mode

monitor=[# Disable laptop screen when docked"eDP-1,disable"# Use external monitors"HDMI-A-1,2560x1440@144,0x0,1""HDMI-A-2,1920x1080@60,2560x0,1"];

Portable Mode

monitor=[# Only laptop screen"eDP-1,1920x1080@60,0x0,1"];

Presentation Mode

monitor=[# Mirror to projector"eDP-1,1920x1080@60,0x0,1""HDMI-A-1,1920x1080@60,0x0,1,mirror,eDP-1"];

Gaming Monitor

Optimized for Gaming

monitor=["DP-1,2560x1440@165,0x0,1"];# In Hyprland configmisc{vrr=1# Variable refresh rate (G-Sync/FreeSync)}env=["WLR_DRM_NO_ATOMIC,1"# If screen tearing];

GUI Configuration Tools

nwg-displays

Install via home/nwg-displays.nix:

nwg-displays

Features:

  • Visual monitor positioning
  • Resolution/refresh rate selection
  • Generates Hyprland config
  • Test before applying

wdisplays

Alternative tool:

nix-shell -p wdisplays --run wdisplays

Configuration Examples

Dual Monitor Setup

monitor=[# Left monitor (vertical)"DP-1,1920x1080@60,0x180,1,transform,3"# Center main monitor"HDMI-A-1,2560x1440@144,1080x0,1"# Right monitor"DP-2,1920x1080@60,3640x180,1"];workspace=["1, monitor:HDMI-A-1, default:true"# Main on center"2, monitor:HDMI-A-1""3, monitor:DP-1"# Code on left"4, monitor:DP-2"# Chat on right];

Triple Monitor Gaming

monitor=[# Left"HDMI-A-1,1920x1080@60,0x0,1"# Center (main gaming)"DP-1,2560x1440@165,1920x0,1"# Right"HDMI-A-2,1920x1080@60,4480x0,1"];workspace=["1, monitor:DP-1, default:true"# Game"2, monitor:HDMI-A-1, default:true"# Discord"3, monitor:HDMI-A-2, default:true"# Music/Browser];

Ultrawide + Laptop

monitor=[# Ultrawide main"DP-1,3440x1440@144,0x0,1"# Laptop below"eDP-1,1920x1080@60,760x1440,1"];workspace=["1, monitor:DP-1""2, monitor:DP-1""3, monitor:DP-1""9, monitor:eDP-1"# Monitoring workspace"10, monitor:eDP-1"# Music];

Waybar Integration

Per-Monitor Waybar

# In waybar config{"output": "HDMI-A-1","layer": "top",
...
}

Multiple configs:

# waybar-main.json for DP-1# waybar-secondary.json for HDMI-A-1# Launch bothexec-once=["waybar -c ~/.config/waybar/main.json""waybar -c ~/.config/waybar/secondary.json"];

Environment Variables

Monitor-Specific

env=[# Force monitor for specific apps"WLR_DRM_DEVICES,/dev/dri/card1:/dev/dri/card0"];

NVIDIA Multi-Monitor

env=["WLR_DRM_NO_ATOMIC,1""LIBVA_DRIVER_NAME,nvidia""GBM_BACKEND,nvidia-drm""__GLX_VENDOR_LIBRARY_NAME,nvidia"];

See NVIDIA for complete NVIDIA setup.


Troubleshooting

Monitor Not Detected

# Check available outputs
hyprctl monitors all
# Force detect
hyprctl reload
# Check kernel detection
ls /sys/class/drm/

Wrong Resolution

# List supported modes
hyprctl monitors | grep "available modes" -A 20
# Try preferred mode
monitor = HDMI-A-1,preferred,auto,1
# Force specific mode
monitor = HDMI-A-1,1920x1080@60,auto,1

Screen Tearing

# Enable VRRmisc{vrr=1}# Or disable atomic (NVIDIA)env=WLR_DRM_NO_ATOMIC,1

Positioning Issues

# Use GUI to visualize
nwg-displays
# Check current positions
hyprctl monitors | grep -E "(Monitor|at)"

Scaling Problems

# Try integer scaling firstmonitor=HDMI-A-1,3840x2160@60,auto,2# If blurry, disable fractionalrender{explicit_sync=1}

Black Screen

# Boot to terminal (Ctrl+Alt+F2)# Check monitors
DISPLAY=:0 hyprctl monitors
# Try safe mode
monitor = ,preferred,auto,1

Advanced Configuration

Per-Monitor Input

# Different mouse sensitivity per monitorinput{# Not directly supported, but workaround:}# Use scripts to change on workspace focusworkspace=["1, monitor:eDP-1, on-created-empty:set-high-sens""3, monitor:HDMI-A-1, on-created-empty:set-low-sens"];

Monitor Profiles

Create scripts for different setups:

# ~/.config/hypr/scripts/monitor-laptop.sh
hyprctl keyword monitor eDP-1,1920x1080@60,0x0,1
hyprctl keyword monitor HDMI-A-1,disable
# ~/.config/hypr/scripts/monitor-desk.sh
hyprctl keyword monitor eDP-1,disable
hyprctl keyword monitor HDMI-A-1,2560x1440@144,0x0,1
hyprctl keyword monitor HDMI-A-2,1920x1080@60,2560x0,1

Bind to keys:

bind=["$mod SHIFT, F7, exec, ~/.config/hypr/scripts/monitor-laptop.sh""$mod SHIFT, F8, exec, ~/.config/hypr/scripts/monitor-desk.sh"];

Best Practices

  1. Use Preferred Mode - Let Hyprland auto-detect when possible
  2. Integer Scaling - Avoid fractional scaling if possible for clarity
  3. Consistent Refresh Rates - Mixing can cause issues
  4. Test Before Committing - Use hyprctl runtime commands first
  5. Document Layout - Comment your monitor positions

Complete Example

# home/hyprland/monitors.nix{config,pkgs,vars, ... }:
{wayland.windowManager.hyprland.settings={monitor=[# Primary 1440p gaming monitor"DP-1,2560x1440@165,1080x0,1"# Left vertical coding monitor"HDMI-A-1,1920x1080@60,0x180,1,transform,3"# Right communication monitor"HDMI-A-2,1920x1080@60,3640x180,1"# Laptop screen (disabled when docked)"eDP-1,disable"# Catch-all for unknown monitors",preferred,auto,1"];workspace=[# Main monitor - gaming/primary work"1, monitor:DP-1, default:true""2, monitor:DP-1"# Left monitor - code/terminals"3, monitor:HDMI-A-1, default:true""4, monitor:HDMI-A-1"# Right monitor - communication"5, monitor:HDMI-A-2, default:true""6, monitor:HDMI-A-2"];# Enable VRR for gamingmisc={vrr=1;};};}

Next Steps

Clone this wiki locally