X11 Special Keyboard Keys for Window Managers

wallclocks

WallClocks

Posted on May 15, 2021

X11 Special Keyboard Keys for Window Managers

Keyboard Media Keys for Unix X11

AKA XF86keysym

Not knowing what the name of a key is, is a pain, so here is a list of them and some useful ways to implement them. Original sources listed at bottom and wherever they show up.

You can also control volume, brightness and maybe some others with acpi event handlers.

For a list of all available X11 media key names, look here. This file comes with x11 development files. In Ubuntu it is obtained in the xorg-dev package and lives in /usr/include/X11/XF86keysym.h.
For i3wm and awesome you remove the "XK_" part. so instead of XF86XK_MonBrightnessUp, it would be XF86MonBrightnessUp.

Control Volume

Using Pulseaudio

i3wm

# Pulse Audio controls
bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume 0 +5% #increase sound volume
bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume 0 -5% #decrease sound volume
bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute 0 toggle # mute sound
Enter fullscreen mode Exit fullscreen mode

awesome wm

    awful.key({            }, "XF86AudioRaiseVolume" , function () awful.spawn("pactl set-sink-volume 0 +5%") end,
              {description = "Volume Up",      group = "awesome"}),
    awful.key({            }, "XF86AudioLowerVolume" , function () awful.spawn("pactl set-sink-volume 0 -5%") end,
              {description = "Volume Down", group = "awesome"}),
    awful.key({            }, "XF86AudioMute" , function () awful.spawn("pactl set-sink-mute 0 toggle") end,
              {description = "Volume Mute",  group = "awesome"}),
Enter fullscreen mode Exit fullscreen mode

dwm

#include <X11/XF86keysym.h>

/* Add somewhere in your constants definition section */

static const char *upvol[]   = { "/usr/bin/pactl", "set-sink-volume", "0", "+5%",     NULL };
static const char *downvol[] = { "/usr/bin/pactl", "set-sink-volume", "0", "-5%",     NULL };
static const char *mutevol[] = { "/usr/bin/pactl", "set-sink-mute",   "0", "toggle",  NULL };

/* Add to keys[] array. With 0 as modifier, you are able to use the keys directly. */
static Key keys[] = {
    { 0,                       XF86XK_AudioLowerVolume, spawn, {.v = downvol } },
    { 0,                       XF86XK_AudioMute, spawn, {.v = mutevol } },
    { 0,                       XF86XK_AudioRaiseVolume, spawn, {.v = upvol   } },
};

/* If you have a small laptop keyboard or don't want to spring your fingers too far away. */

static Key keys[] = {
    { MODKEY,                       XK_F11, spawn, {.v = downvol } },
    { MODKEY,                       XK_F9,  spawn, {.v = mutevol } },
    { MODKEY,                       XK_F12, spawn, {.v = upvol   } },
};
Enter fullscreen mode Exit fullscreen mode

ALSA

If you want to use alsa instead of pulse audio, you can use the amixer command. Here are the commands for volume up, down and mute toggle. Make sure to get the alsa-tools and alsa-utils packages.

  • amixer sset Master 5%+
  • amixer sset Master 5%-
  • amixer sset Master toggle

ACPI

Brightness and Volume

This is from here. If you use acpid and would rather use it then your window manager to control your volume and brightness, you can like this.

/etc/acpi/handler.sh

#!/bin/bash
# Default acpi script that takes an entry for all actions
#jack/headphone HEADPHONE unplug
#jack/headphone HEADPHONE plug

case "$1" in
    jack/headphone)
        case $3 in
            plug)
                echo "in" > /var/tmp/headphones.log
            ;;
            unplug)
                echo "out" > /var/tmp/headphones.log
            ;;
        esac
        ;;
    button/mute)
        /usr/local/bin/volume mute 
    ;;
button/volumedown)
        /usr/local/bin/volume vdown
    ;;
button/volumeup)
    /usr/local/bin/volume vup
    ;;
video/brightnessup)
    /usr/local/bin/brightness_push up
    ;;
video/brightnessdown)
    /usr/local/bin/brightness_push down
    ;;
Enter fullscreen mode Exit fullscreen mode

In the above file I use the event handlers to call custom scripts in my $PATH. The first case is watching the headphone jack, when headphones get plugged in, a log file is made, if the files contents is in, headphones are plugged in, out means unplugged. My volume script them looks at that file when I press the volume keys, it will choose to control the headphone volume instead of master. This was to resolve an issue on my hp stream when running alpine as a full blown desktop.
Anyway, here are the scripts in $PATH(like /usr/local/bin/) that get called.

 #!/bin/bash

refresh_i3status="killall -SIGUSR1 py3status"
headphone=$(cat /var/tmp/headphones.log)

case "$1" in
    up)
        #sudo -g audio pactl set-sink-volume @DEFAULT_SINK@ +10%;
        amixer sset Master 5%+
        $refresh_i3status

    ;;
    down)
        #sudo -g audio pactl set-sink-volume @DEFAULT_SINK@ -10%; 
        amixer sset Master 5%-
        $refresh_i3status
    ;;
    mute)
        #sudo -g audio pactl set-sink-mute @DEFAULT_SINK@ toggle; 
        amixer sset Master toggle
        if [[ $headphone == "in" ]]; then
            amixer sset Headphone unmute
        else
            amixer sset Speaker unmute
        fi
        $refresh_i3status
    ;;
    esac
Enter fullscreen mode Exit fullscreen mode
 #!/bin/bash

# Variables

brightness_dir=/sys/class/backlight/intel_backlight
brightness_file=$brightness_dir/brightness
brightness=$(cat $brightness_file)
actual_brightness=$(cat $brightness_dir/actual_brightness)
max_brightness=$(cat $brightness_dir/max_brightness)
min_brightness=50
n=50


if [[ "$1" == "up" ]]; then
    if (( $actual_brightness < $max_brightness )); then
        echo  $(dc -e "$actual_brightness $n + p") >> $brightness_file;
    fi
else
    if (( $actual_brightness > $min_brightness )); then
        echo  $(dc -e "$actual_brightness $n - p") >> $brightness_file;
    fi

fi
Enter fullscreen mode Exit fullscreen mode

Brightness Control

With xbacklight

Controling Brightness is a lot like contorling volume.

i3wm

 # Screen Brightness controls
bindsym XF86MonBrightnessUp exec xbacklight -inc 20 # increase screen brightness
bindsym XF86MonBrightnessDown exec xbacklight -dec 20 # decrease screen brightness

Enter fullscreen mode Exit fullscreen mode

awesome wm

    awful.key({            }, "XF86MonBrightnessUp" , function () awful.spawn("xbacklight inc 5%") end,
              {description = "Brighness Up",      group = "awesome"}),
    awful.key({            }, "XF86MonBrightnessDown" , function () awful.spawn("xbacklight dec 5%") end,
              {description = "Brighness Down",      group = "awesome"}),
Enter fullscreen mode Exit fullscreen mode

dwm

 #include <X11/XF86keysym.h>

/* Add somewhere in your constants definition section */

static const char *upbrightness[]      = { "xbacklight", "inc", "5%",     NULL };
static const char *downbrightness[] = { "xbacklight", "dec", "5%",     NULL };

/* Add to keys[] array. With 0 as modifier, you are able to use the keys directly. */
static Key keys[] = {
    { 0,                       XF86XK_MonBrightnessDown, spawn, {.v = downbrightness } },
    { 0,                       XF86XK_MonBrightnessUp, spawn, {.v = upbrightness   } },
};

Enter fullscreen mode Exit fullscreen mode

xbacklight Alternative

This is from here
If you have trouble with xbacklight or just don't like it, you can use a simple script, it goes into /sys/class/backlight/{your screen}, gets the current brightness and changes it a set amount.
You have to change the intel_backlight part if you do not use intel. You can find out, ls /sys/class/backlight. Replace intel_backlight with what ever you have.

#!/bin/bash

## Very simple way to change brightness without a utility.
## I made this to use with acpi event handlers and my laptop keyboard
## GNU General Public License
## dosborn at vivaldi dot net

# Variables

# brightness_dir= Direcotry containing the backlight file
brightness_dir=/sys/class/backlight/intel_backlight
# brightness_file= the file named brightness in that dir
brightness_file=$brightness_dir/brightness
# brightness= The contents of that file
brightness=$(cat $brightness_file)
# actual_brightness= the actual_brightness file
actual_brightness=$(cat $brightness_dir/actual_brightness)
# max_brightness= the contents of max_brightness
max_brightness=$(cat $brightness_dir/max_brightness)
# min_brightness= how low you want it to get
min_brightness=50
# n= the change, how fast it goes up and down
n=50

## If `brightness_push.sh up` is called then it will go up "n". and 'down' for down.

if [[ "$1" == "up" ]]; then
    if (( $actual_brightness < $max_brightness )); then
        echo  $(dc -e "$actual_brightness $n + p") >> $brightness_file;
    fi
else
    if (( $actual_brightness > $min_brightness )); then
        echo  $(dc -e "$actual_brightness $n - p") >> $brightness_file;
    fi

fi
Enter fullscreen mode Exit fullscreen mode

## Trackpad
Also form here
I am leaving out the dwm from here, it is just like before but different keys.
### i3wm

--------
 # Touchpad controls
bindsym XF86TouchpadToggle exec /some/path/toggletouchpad.sh # toggle touchpad
Enter fullscreen mode Exit fullscreen mode

### awesome wm

     awful.key({            }, " XF86TouchpadToggle" , function () awful.spawn("/some/path/toggletouchpad.sh") end,
              {description = "Prev Track", group = "awesome"}),

Enter fullscreen mode Exit fullscreen mode
  • The script toggletouchpad.sh for toggling your touchpad should have following content:
#!/bin/bash
if synclient -l | grep "TouchpadOff .*=.*0" ; then
    synclient TouchpadOff=1 ;
else
    synclient TouchpadOff=0 ;
fi
Enter fullscreen mode Exit fullscreen mode

Media player controls

i3wm

bindsym XF86AudioPlay exec playerctl play
bindsym XF86AudioPause exec playerctl pause
#bindsym XF86AudioPlay exec playctl play-pause  # To toggle with a single key
bindsym XF86AudioNext exec playerctl next
bindsym XF86AudioPrev exec playerctl previous
Enter fullscreen mode Exit fullscreen mode

awesome wm

    awful.key({            }, "XF86AudioPlay" , function () awful.spawn("playerctl play-pause") end,
              {description = "Play Pause", group = "awesome"}),
    awful.key({            }, "XF86AudioNext" , function () awful.spawn("playerctl next") end,
              {description = "Next Track", group = "awesome"}),
    awful.key({            }, "XF86AudioPrev" , function () awful.spawn("playerctl previous") end,
              {description = "Prev Track", group = "awesome"}),
Enter fullscreen mode Exit fullscreen mode

Sources

  1. https://gist.github.com/palopezv/efd34059af6126ad970940bcc6a90f2e
  2. https://cgit.freedesktop.org/xorg/proto/x11proto/tree/XF86keysym.h
  3. https://git.sr.ht/~djorborn/acpi_volume_brightness
  4. https://gist.github.com/djorborn/02363a376f25b4147de06e5a53647bcd
  5. https://faq.i3wm.org/question/3747/enabling-multimedia-keys.1.html

Thank you everyone who has helped me learn a random thing here and there.

💖 💪 🙅 🚩
wallclocks
WallClocks

Posted on May 15, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related