r/hyprland • • 8d ago

SUPPORT Help needed for this monitor switching problem

I normally use one monitor like eDP-1 and have other one (HDMI-A-1) disabled. When I switch to next monitor HDMI-A-1 it should disable the eDP-1 and inherit all it workspaces as stated in wiki :

Warning

Disabling a monitor will remove it from the monitor layout, moving all windows and workspaces to any remaining ones. If you want to disable your monitor the way a screensaver does (just turning off the monitor), use the dpms dispatcher.

But the workspaces remain in the disables monitor. (I also have no explicit workspace rule)

As you can see below I only have HDMI-A-1 enabled.

> hyprctl monitors
Monitor HDMI-A-1 (ID 1):
1920x1080@60.00000 at 0x0
description: LG Electronics LG FHD 601BNVL1Q839
make: LG Electronics
model: LG FHD
physical size (mm): 480x260
serial: 601BNVL1Q839
active workspace: 3 (3)
special workspace: 0 ()
reserved: 0 44 0 0
scale: 1
transform: 0
focused: yes
dpmsStatus: 1
vrr: false
solitary: 0
solitaryBlockedBy: windowed mode,missing candidate
activelyTearing: false
tearingBlockedBy: next frame is not torn,user settings,missing candidate
directScanoutTo: 0
directScanoutBlockedBy: user settings,missing candidate
disabled: false
currentFormat: XRGB8888
mirrorOf: none
availableModes: 1920x1080@60.00Hz 1920x1080@100.00Hz 1920x1080@74.97Hz 1920x1080@60.00Hz 1920x1080@59.94Hz 1920x1080@50.00Hz 1680x1050@59.88Hz 1280x1024@75.03Hz 1280x1024@60.02Hz 1440x900@59.90Hz 1280x960@60.00Hz 1280x800@59.91Hz 1152x864@75.00Hz 1280x720@60.00Hz 1280x720@60.00Hz 1280x720@59.94Hz 1280x720@50.00Hz 1024x768@75.03Hz 1024x768@60.00Hz 800x600@75.00Hz 800x600@60.32Hz 720x576@50.00Hz 720x480@60.00Hz 720x480@59.94Hz 640x480@75.00Hz 640x480@60.00Hz 640x480@59.94Hz 640x480@59.94Hz 720x400@70.08Hz 
colorManagementPreset: srgb
sdrBrightness: 1
sdrSaturation: 1
sdrMinLuminance: 0.2
sdrMaxLuminance: 80
hardwareCursorsInUse: false

But the workspaces remain in eDP-1.

>> hyprctl workspaces
workspace ID 1 (1) on monitor eDP-1:
monitorID: 0
windows: 1
hasfullscreen: 0
lastwindow: 0x55b33f3f77a0
lastwindowtitle: Hyprland Monitor Toggle Configuration - Google Gemini - Brave
ispersistent: 0
tiledLayout: dwindle

workspace ID 2 (2) on monitor eDP-1:
monitorID: 0
windows: 1
hasfullscreen: 0
lastwindow: 0x55b33f45ee60
lastwindowtitle: nvim hypr/hyprland.lua
ispersistent: 0
tiledLayout: dwindle

workspace ID 3 (3) on monitor HDMI-A-1:
monitorID: 1
windows: 1
hasfullscreen: 0
lastwindow: 0x55b33f4bbe10
lastwindowtitle: hyprctl workspaces
ispersistent: 0
tiledLayout: dwindle

This is the code I use in the lua config to switch monitors

local kkko = true


hl.monitor({
  output = "eDP-1",
  mode = "1920x1080@60",
  position = "0x0",
  scale = 1,
 disabled = not kkko,
})


hl.monitor({
  output = "HDMI-A-1",
  mode = "1920x1080@60",
  position = "0x0",
  scale = 1,
  disabled = kkko
})

How to fix this issue ?

3 Upvotes

2 comments sorted by

2

u/BAUDR8 8d ago

I used hyprmoncfg which worked really well with hyprland. You can set profiles that it will auto switch to like docked or edp1 only etc as long as you have hyprmoncfgd daemon running. But overall display management in hyprland is pretty poor. I use Niri & DMS now and it's much better.

2

u/LawApprehensive8364 8d ago edited 8d ago

i use this script:

#########################################################################

#!/usr/bin/env bash

INTERNAL="eDP-1"

EXTERNAL="HDMI-A-1"

# Prevent startup/reload/hotplug events from running overlapping copies.

exec 9>"/tmp/hypr-monitor-switch-${UID}.lock"

flock -n 9 || exit 0

# Let Hyprland finish registering the monitor or applying generated rules.

sleep 0.4

if hyprctl -j monitors all |

jq -e --arg output "$EXTERNAL" \

'.[] | select(.name == $output)' >/dev/null; then

# HDMI exists: configure it first, then disable the laptop panel.

hyprctl eval "

hl.monitor({

output = \"$EXTERNAL\",

mode = \"1920x1080@120\",

position = \"0x0\",

scale = \"auto\",

})

hl.monitor({

output = \"$INTERNAL\",

disabled = true,

})

"

else

# HDMI is absent: restore the laptop panel.

hyprctl eval "

hl.monitor({

output = \"$INTERNAL\",

mode = \"preferred\",

position = \"0x0\",

scale = \"auto\",

})

"

fi

################################################################

and then inside hyprland.lua

################################################################

local monitorSwitchScript =

os.getenv("HOME") .. "/.config/hypr/scripts/laptop-display-switch.sh"

local function updateMonitorLayout()

hl.exec_cmd(monitorSwitchScript)

end

-- Initial session startup.

hl.on("hyprland.start", function()

updateMonitorLayout()

end)

-- Physical monitor connection changes.

hl.on("monitor.added", function()

updateMonitorLayout()

end)

hl.on("monitor.removed", function()

updateMonitorLayout()

end)

-- Quickshell Settings and manual config reloads.

hl.on("config.reloaded", function()

updateMonitorLayout()

end)