Create a Custom Display Switch Option by Xrandr and Pactl

From WikiMLT
Figure 1. NVIDIA Set­tings – X Serv­er Dis­play Con­fig­u­ra­tion Ex­am­ple.

The Gnome's built-in mon­i­tor switch op­tion – Sup­per+P – is too lim­it­ed and al­so doesn't al­low you to switch the au­dio out­put. So here is short man­u­al how to im­ple­ment a Cus­tom Dis­play Switch Op­tion by Xran­dr and Pactl.

Note xran­dr is not avail­able for Way­land, al­so some dis­tri­b­u­tions as the lat­est PopOS! doesn't sup­port Pulseau­dio (pactl) naive­ly ant prob­a­bly some ad­di­tion­al set­tings must be passed to its PipeWire's Pulseau­dio wrap­per. This set­up per­fect­ly works with Kali Lin­ux 2022 and Ubun­tu 22.04 with Xorg.

Gen­er­ate Dis­play Pro­files

You can use xran­dr to switch the dis­play set­tings via the com­mand line while X11/​​​Xorg is in use. Al­so there is a tool named au­toran­dr, that al­lows you to eas­i­ly save and re­store the xran­dr's pro­files – I would pre­fer to use it with a com­bi­na­tion of NVIDIA Set­tings…

To in­stall the lat­est ver­sion of au­toran­dr use the com­mand shown be­low. Al­ter­na­tive­ly you may in­stall a lit­tle bit old­er ver­sion from the Kali's repos­i­to­ry.

# sudo apt install autorandr  # the package is outdated
# sudo pip install autorandr  # the latest Ubuntu requires using of "virtual env"
sudo apt install pip python3.11-venv
mkdir .pip-venv
python3 -m venv ~/.pip-venv
~/.pip-venv/bin/pip install autorandr
ln -s "/home/$USER/.pip-venv/bin/autorandr" "/home/$USER/bin"
autorandr

Then use NVIDIA Set­tings con­trol pan­el to ad­just the dif­fer­ent dis­play pro­files and save them, one by one – see Fig­ure 1, by the fol­low­ing com­mand.

autorandr --save LGUW_ACER_LGTV

In ad­di­tion you can set a de­fault pro­file by the com­mand:

autorandr --default LGUW

You can en­force the above by cre­at­ing the fol­low­ing file.

nano ~/.xprofile
/usr/local/bin/autorandr LGUW

If the above doesn't take an ef­fect, you can cre­ate an en­tri in­to the Au­tostart Application's di­rec­to­ry.

nano ~/.config/autostart/default-display.desktop
[Desktop Entry]
Encoding=UTF-8
Type=Application
Name=Set LG UW as defailt Display
Exec=/bin/bash -c '/usr/local/bin/autorandr LGUW'
StartupNotify=false
Terminal=false
Icon=xfce4-display

PipeWire Sinks Switch

Switch­ing the Sinks (au­dio out­puts) with PipeWire gram­mat­i­cal­ly, with­out in­stalling ad­di­tion­al pack­ages, is a bit wired. And I'm not sure we need that be­cause when switch­ing the dis­plays with Autorandr/​​​Xrandr PipeWire suc­cess­ful­ly re­stores the pre­vi­ous used au­dio out­put for the cer­tain dis­play con­fig­u­ra­tion. How­ev­er here are few script­ing ideas.

wpctl status | sed -nE 's/^.*\s+([0-9]+).*HDA NVidia.*alsa.*$/\1/p'
#!/bin/bash

DEVICE_ID=$(wpctl status | sed -nE 's/^.*\s+([0-9]+).*HDA NVidia.*alsa.*$/\1/p')
wpctl set-profile "$DEVICE_ID" 1

PulseAu­dio: Dep­re­cat­ed Sec­tions

Gen­er­ate Au­dio Pro­files

Fol­low the guide How do I switch the au­dio out­puts of an au­dio de­vice from CLI? and com­pose the com­mand-lines that you need to switch your au­dio out­puts. In my case I'm hav­ing two dis­plays with built-in au­dio con­nect­ed to my NVIDIA Quadro T600 and the com­mands to switch these two out­puts are the fol­low­ing.

pactl set-card-profile alsa_card.pci-0000_09_00.1 output:hdmi-stereo
pactl  set-card-profile alsa_card.pci-0000_09_00.1 output:hdmi-stereo-extra2

Cre­ate a script to tog­gle the dis­plays

nano ~/bin/toggle-displays.sh && chmod +x ~/bin/toggle-displays.sh
#!/bin/bash

# autorandr profiles: LGUW, LGTV, LGUW_LGTV, LGUW_LGTV_ACER, LGUW_ACER_LGTV, LGUW_ACER

STATE="/tmp/toggle-displays.sh.state"
CURRENT=$(cat "$STATE")
[[ -z ${CURRENT} ]] && CURRENT=0

if [[ CURRENT -eq 1 ]]; then
	/usr/local/bin/autorandr LGUW_LGTV
	/usr/bin/pactl set-card-profile alsa_card.pci-0000_09_00.1 output:hdmi-stereo
	echo $((CURRENT+=1)) > "$STATE"
elif [[ CURRENT -eq 2 ]]; then
	/usr/local/bin/autorandr LGUW_LGTV
	/usr/bin/pactl set-card-profile alsa_card.pci-0000_09_00.1 output:hdmi-stereo-extra2
	echo $((CURRENT+=1)) > "$STATE"
elif [[ CURRENT -eq 3 ]]; then
	/usr/local/bin/autorandr LGTV
	/usr/bin/pactl set-card-profile alsa_card.pci-0000_09_00.1 output:hdmi-stereo-extra2
	echo $((CURRENT+=1)) > "$STATE"
elif [[ CURRENT -eq 4 ]]; then
	/usr/local/bin/autorandr LGUW_LGTV_ACER
	/usr/bin/pactl set-card-profile alsa_card.pci-0000_09_00.1 output:hdmi-stereo-extra2
	echo $((CURRENT+=1)) > "$STATE"
elif [[ CURRENT -eq 5 ]]; then
	/usr/local/bin/autorandr LGUW_ACER_LGTV
	/usr/bin/pactl set-card-profile alsa_card.pci-0000_09_00.1 output:hdmi-stereo-extra2
	echo $((CURRENT+=1)) > "$STATE"
else
	/usr/local/bin/autorandr LGUW
	/usr/bin/pactl set-card-profile alsa_card.pci-0000_09_00.1 output:hdmi-stereo
	echo 1 > "$STATE"
fi
  • Note you need to tweak the script ac­cord­ing your en­vi­ron­ment!
  • Test the script with­in the com­mand line.
Figure 2. Cre­ate Cus­tom Key­board Short­cuts via Gnome Set­tings.

Cre­ate Cus­tom Key­board Short­cut

First dis­able the Gnome's (3.26+) built-in Sup­per+P short­cut. You can do it by search­ing for switch-mon­i­tor with­in Dconf Ed­i­tor tool, or via the com­mand line by the fol­low­ing com­mand.

gsettings set org.gnome.mutter.keybindings switch-monitor "[]"
gsettings set org.gnome.mutter.keybindings switch-monitor "['<Super>p', 'XF86Display']" # Restore

Then cre­ate your Cus­tom Short­cut as it is shown at Fig­ure 2.

Ref­er­ences