I am using an application (VMWare Workstation) which hijacks the media keys on my keyboard, so I want to use another input device (Elgato Stream Deck) to send generic media commands like 'volume up' or 'pause'. I am able to use the stream deck to send shell commands like xdotool key XF86AudioLowerVolume, and this works as long as I'm in the gnome shell, but VMWare still hijacks those messages if I'm in a VM. Lower-level commands using tools like wmctrl or dbus-send, on the other hand, work fine. So, what would be the dbus-send equivalent to xdotool key XF86Audio* commands?

I can use dbus-monitor to view events when pressing the media keys and see, for example:

signal time=1599582032.226007 sender=:1.66 -> destination=:1.96 serial=18241 path=/org/gnome/Shell; interface=org.gnome.Shell; member=AcceleratorActivated
   uint32 140
   array [
      dict entry(
         string "device-id"
         variant             uint32 12
      dict entry(
         string "timestamp"
         variant             uint32 504924437
      dict entry(
         string "action-mode"
         variant             uint32 1
      dict entry(
         string "device-node"
         variant             string "/dev/input/event7"

for volume-up. How can I translate this into a dbus-send message?

I found this question from long-ago, but it appears to be obsolete. At least, it does not work on my system (Ubuntu 20.04): https://stackoverflow.com/questions/2830858/controlling-gnome-volume-using-dbus

1 Answer 1


pulsemixer ended up doing what I needed. pactl can set the volume, but won't report a level back for the OSD to display. This script raises/lowers volume or toggles mute, and shows the appropriate OSD:

#!/usr/bin/env bash

# must be set correctly for pactl to connect
uid=$(id -u)
export XDG_RUNTIME_DIR=/run/user/$uid

case "$1" in
    up )
        pulsemixer --change-volume +5 --max-volume 100
    down )
        pulsemixer --change-volume -5
    mute )
        pulsemixer --toggle-mute

# get active levels
sink=$(pulsemixer --list-sinks | grep -e "Default$" | cut -d',' -f2 | cut -c8-)
vol=$(pulsemixer --get-volume | cut -d' ' -f1)
mute=$(pulsemixer --get-mute)

# set osd icon
if [ $mute -eq 1 ]; then
elif [ $vol -lt 33 ]; then
elif [ $vol -lt 66 ]; then

# format as decimal
if [ $vol -eq 100 ]; then

gdbus call --session --dest 'org.gnome.Shell' --object-path '/org/gnome/Shell' --method 'org.gnome.Shell.ShowOSD' "{'icon': <'$icon'>, 'label': <'$sink'>, 'level': <$vol>}"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.