X11 Special Keyboard Keys for Window Managers
Tags: x11, volumekeys, specialkeys, windowmanager
Published: 2021-05-15 01:48:33

---
title: X11 Special Keyboard Keys for Window Managers
published: true
description: How to use and find X11 Media, Special Keys, like Volume and Brightness.
tags: x11, volumekeys, specialkeys, windowmanager
//cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bqe8mbn5kpr5twd1eu5q.png
---

# Keyboard Media Keys for Unix X11
**AKA XF86keysym**

Not knowing what the name of a key is, is a pain, so [here](https://cgit.freedesktop.org/xorg/proto/x11proto/tree/XF86keysym.h) 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](https://cgit.freedesktop.org/xorg/proto/x11proto/tree/XF86keysym.h). 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
```
### 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"}),
```

### 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   } },
};
```
### 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](https://git.sr.ht/~djorborn/acpi_volume_brightness). 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
	;;
```
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
 ```
 
 ```
 #!/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
 ```
 
 ___

## 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
 
 ```
### 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"}),
 ```
 
### 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   } },
};
 
 ```
 
## xbacklight Alternative
 This is from [here](https://gist.github.com/djorborn/02363a376f25b4147de06e5a53647bcd)
 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
```
 
 
 ## Trackpad
 Also form [here](https://faq.i3wm.org/question/3747/enabling-multimedia-keys.1.html)
 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
 ```
 
 ### awesome wm
 ```
     awful.key({            }, " XF86TouchpadToggle" , function () awful.spawn("/some/path/toggletouchpad.sh") end,
              {description = "Prev Track", group = "awesome"}),

```
 
 - 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
```
----

## 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
```

### 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"}),
```

 ____
## 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.