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:
- 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.
- 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.
- 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:
/usr/local/bin/external_monitor_wake
. Using it in/usr/lib/pm-utils/sleep.d/
seems confusing as that is a special directory for pm-utils, which we aren't using. – AdamS Feb 19 '23 at 17:20