15

Problem:
On an Ubuntu based laptop, when I sleep or disconnect power to my external monitor then power up the system or reconnect the monitor again, the display doesn't come on.

Poor man's solution:
The only way I've found to get the external display to work (aside from reboot) is to switch from Joined Display to Mirror Display. As soon as the monitor comes alive I can simply cancel the change to Mirror Displays, monitor settings revert, and the external monitor works as usual.

Grievance:
Unfortunately this causes windows that were on my external monitor to be misarranged across desktop workspaces (PopOS here, Ubuntu 20.10). It's a fair bit of effort to re-arrange workspaces after the mirror/cancel process.

Hopeful question:
Are there any command line utilities that might force the external monitor to reset without the need to change from Joined Display to Mirror?

David Parks
  • 2,586

3 Answers3

11

I was having a similar issue with PopOS 22.04 (jammy) on my laptop, and an external HDMI display. Here is a solution that works automatically once implemented.

0. Figure out some useful constants:

  1. Your username: this should be self-explanatory. You can run whoami in a non-privileged shell terminal to find out. In the commands below, when I specify USERNAME, replace it with your username.
  2. The display identifiers of your screens: when your displays are working correctly, you can run xrandr | grep ' connected' (keep the space inside quotes) and look at the output. The first column contains the display identifiers. For example, my internal display is eDP-1, and my external display is HDMI-1-0. Below I will use these values in my scripts, please replace them with your values if they are different.
  3. The DISPLAY environment variable: run echo $DISPLAY in a non-privileged shell terminal to find out. Mine says :1, so I will use it below. If your value is different, please replace :1 with your own value.

1. Create the following script at /usr/lib/pm-utils/sleep.d/99_external_monitor_wake:

#!/bin/bash

DISPLAY=:1; export DISPLAY

case "$1" in suspend | hibernate | pre) # no operation : ;; resume | thaw | post) # wakes the external monitor connected to the HDMI port xrandr --output HDMI-1-0 --auto --left-of eDP-1 --primary sleep 3 xrandr --output HDMI-1-0 --auto --left-of eDP-1 --primary ;; esac

exit 0

You will need to tweak this script according to your setup.

The first thing to change is DISPLAY=:1. This sets the DISPLAY environment variable we found in section 0.2. above. Replace it with your own value if different.

The second thing to change are the two xrandr --output HDMI-1-0 --auto --left-of eDP-1 --primary lines. First you need to replace the display identifiers we found above in section 0.1. with your own values. I am also setting my HDMI display to the left of my internal display, and making my external display primary. You may want to replace --left-of with --right-of, and you may want to omit the --primary flag. Read the man page for xrandr by typing man xrandr for more details. Remember to make the same changes to both lines of command.

You can also experiment with the sleep time if the 3 seconds I specified above doesn't work for you. It's kind of like using AED (idk I'm not an EMT): you give it a jolt first, and sneak in a second command when it's in a state to be able to receive it.

2. Change the script's owner to your user, and make it executable:

sudo chown USERNAME:USERNAME /usr/lib/pm-utils/sleep.d/99_external_monitor_wake
sudo chmod +x /usr/lib/pm-utils/sleep.d/99_external_monitor_wake

You want to replace the user USERNAME with your own login user name found in section 0.0. above.

3. Create a systemd service unit file at /etc/systemd/system/wake-monitor.service to trigger this script upon resuming from sleep:

[Unit]
Description=Wake external monitor connected to HDMI after resuming from sleep, and when entering a display manager
After=sleep.target display-manager.service
StopWhenUnneeded=yes

[Service] User=USERNAME Type=oneshot RemainAfterExit=no ExecStart=/usr/lib/pm-utils/sleep.d/99_external_monitor_wake resume

[Install] WantedBy=sleep.target display-manager.service

You want to replace the user USERNAME with your own login user name found in section 0.0. above.

I included display-manager.service in my After and WantedBy, because I have the same issue when the screen locks after no activity. You can remove it if you only need to fix resuming from sleep.

4. Enable the newly created systemd service:

sudo systemctl daemon-reload
sudo systemctl enable wake-monitor.service

That's it! You should be able to suspend your computer, and wake up with a functioning external display!

If something is not working right, you can debug the service by running sudo systemctl status wake-monitor.service and looking at the output.

References:

Jeremy
  • 2,926
Samm
  • 113
6

Two things to try:

Sometimes running xrandr with no options will cause the display to be probed and start working.

I've had problems with power saving mode to wake up one screen and not the other, especially when one was disconnected for a while. When this happens, make sure the external monitor is plugged in and powered on and then run

xset dpms force off

and wait a few seconds and then hit a key to unblank the screen. This may wake up the external monitor.

It may be necessary to cycle things completely, and a delay is needed to let things settle:

xset dpms force off; sleep 2; xset dpms force on

An automatic wait may not work, watching it manually may be more effective. If the monitor alternates between states such as blue/blank screen you may need to run the command with the monitor in one of these states (such as when it's a blank screen and not blue).

user10489
  • 5,533
0

I noticed something in Ubuntu 24 with Nvidia. Open Settings -> Display menu. There will be Join and Mirror buttons in "Multiple Displays" section. Click to "Mirror" and after that click to "Join". Then the second monitor will be there. Actually ubuntu detecting hdmi because that result:

emir@ubuntu-semruk bin $ xrandr | grep ' connected'
HDMI-0 connected primary (normal left inverted right x axis y axis)
eDP-1-1 connected 3408x2130+5120+0 (normal left inverted right x axis y axis) 366mm x 228mm

Ubuntu knows the hdmi connected but not activating Join feature in Multiple Displays section. This means this problem is not about Nvidia driver, probably gnome has bug. Interesting thing.

kodmanyagha
  • 148
  • 11