Create a Custom Display Switch Option by Xrandr and Pactl
The Gnome's built-in monitor switch option – Supper+P – is too limited and also doesn't allow you to switch the audio output. So here is short manual how to implement a Custom Display Switch Option by Xrandr and Pactl.
Note xrandr
is not available for Wayland, also some distributions as the latest PopOS! doesn't support Pulseaudio (pactl) naively ant probably some additional settings must be passed to its PipeWire's Pulseaudio wrapper. This setup perfectly works with Kali Linux 2022 and Ubuntu 22.04 with Xorg.
Generate Display Profiles
You can use xrandr
to switch the display settings via the command line while X11/Xorg is in use. Also there is a tool named autorandr
, that allows you to easily save and restore the xrandr
's profiles – I would prefer to use it with a combination of NVIDIA Settings…
To install the latest version of autorandr
use the command shown below. Alternatively you may install a little bit older version from the Kali's repository.
# 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 Settings control panel to adjust the different display profiles and save them, one by one – see Figure 1, by the following command.
autorandr --save LGUW_ACER_LGTV
In addition you can set a default profile by the command:
autorandr --default LGUW
You can enforce the above by creating the following file.
nano ~/.xprofile
/usr/local/bin/autorandr LGUW
If the above doesn't take an effect, you can create an entri into the Autostart Application's directory.
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
Switching the Sinks (audio outputs) with PipeWire grammatically, without installing additional packages, is a bit wired. And I'm not sure we need that because when switching the displays with Autorandr/Xrandr PipeWire successfully restores the previous used audio output for the certain display configuration. However here are few scripting 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
PulseAudio: Deprecated Sections
Generate Audio Profiles
Follow the guide How do I switch the audio outputs of an audio device from CLI? and compose the command-lines that you need to switch your audio outputs. In my case I'm having two displays with built-in audio connected to my NVIDIA Quadro T600 and the commands to switch these two outputs are the following.
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
Create a script to toggle the displays
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 according your environment!
- Test the script within the command line.
Create Custom Keyboard Shortcut
First disable the Gnome's (3.26+) built-in Supper+P shortcut. You can do it by searching for switch-monitor
within Dconf Editor
tool, or via the command line by the following command.
gsettings set org.gnome.mutter.keybindings switch-monitor "[]"
gsettings set org.gnome.mutter.keybindings switch-monitor "['<Super>p', 'XF86Display']" # Restore
Then create your Custom Shortcut as it is shown at Figure 2.
References
- GitHub: Autorandr
- Ask Ubuntu: How do I save my new resolution setting with xrandr?
- Ubuntu Wiki: Resolution > Setting xrandr changes persistently
- Ask Ubuntu: How do I switch the audio outputs of an audio device from CLI?
- [PipeWire]:
- Arch Wiki: PipeWire
- Jorge Castro: Headphone/Speaker fast switching with Pipewire
- GitHub Gist: pipewire-out-default-switch.sh
- EndeavourOS Forum: Setting up a default audio sink help:
/usr/share/pipewire/pipewire.conf
- Ask Ubuntu: How to disable global <Super>P shortcut?