Often, special function keys (e.g. for controlling volume, brightness, sleep etc.) will not be automatically configured in many Linux distros. Luckily, in most cases it is easy to manually set this up. As with most other settings, Openbox allows custom key bindings to be added via entries in ~/.config/openbox/rc.xml. This way, functionality can be assigned to Fn keys not recognized out-of-the-box.
This is especially easy for standard functions (like volume-up and down, mute, sleep, brightness-up and down etc.) as these already have special key-codes assigned to them. For example, brightness-up button will be detected as XF86MonBrightnessUp allowing functionality to be directly bound to this code.
Discovering the key code to use
The best way to discover what happens when a key is pressed is using xev. Fire it from the terminal, and it will give you a window that captures events and logs them to the console. There, you'll be able to see the code for each button or button combination you press. Later on, you can use these codes to bind commands to them.
Configure keys using a graphical interface
Instead of editing Openbox's rc.xml manually, you can use obkey (Openbox Key Editor), which can automate the procedure of capturing the key codes for you and binding commands to them. See below for example commands you can bind to keys.
List of common function keys and example configurations
Increase/decrease brightnessBrightness can be controlled using xbacklight, so assigning the following bindings will make the brightness function keys work:
<keybind key="XF86MonBrightnessUp"> <action name="Execute"> <command>xbacklight -inc 40</command> </action> </keybind> <keybind key="XF86MonBrightnessDown"> <action name="Execute"> <command>xbacklight -dec 40</command> </action> </keybind>
Sleep and HibernateAssuming a SystemD setup, systemctl can be used to suspend the system to RAM (a.k.a. sleep), to disk (a.k.a hibernate) or both (a.k.a. hybrid sleep). Add the following to make the sleep function key work:
<keybind key="XF86Sleep"> <action name="Execute"> <command>systemctl suspend</command> </action> </keybind>If you have additional keys (apart from sleep), you can try the following binding (make sure hibernation is properly configured and working on your system, and your user has the permissions to use it first):
<keybind key="XF86Standby"> <action name="Execute"> <command>systemctl hibernate</command> <!-- "systemctl hybrid-sleep" could be used instead --> </action> </keybind>
SearchMany keyboards have a dedicated search key. To bind a command appropriate for your system (exemplified using SpaceFM) use the following:
<keybind key="XF86Search"> <action name="Execute"> <command>spacefm --find-files %F</command> </action> </keybind>
Screen lockBind any screen-locking (screensaver) utility, like slock or gnome-screensaver-command, as exemplified below to make the lock-screen button work:
<keybind key="XF86ScreenSaver"> <action name="Execute"> <command>slock</command> <!-- Replace with "gnome-screensaver-command -l" or "xscreensaver-command -lock" if you wish --> </action> </keybind>
Volume up/down/muteThere's a few options for dealing with volume keys.
Let volumeicon manage the function keysvolumeicon is often used with Openbox and can be configured to manage volume buttons. Additionally, it can display OSD notifications nicely, and it supports multiple back-ends (GTK+ popups, libnotify, and possibly more). If you want to go this route, edit your ~/.config/volumeicon/volumeicon to contain the following:
[Hotkeys] up_enabled=true down_enabled=true mute_enabled=true up=XF86AudioRaiseVolume down=XF86AudioLowerVolume mute=XF86AudioMute
Bind volume buttons to amixer commandsamixer can be called directly to control the volume. If you're using Alsa only, you may have to first find out the name of the mixer control your sound card exposes by using amixer scontrols. It is usually called Master, but not always. With PulseAudio, it is always called Master.
<keybind key="XF86AudioRaiseVolume"> <action name="Execute"> <!-- Increase volume by 5& --> <command>amixer set Master 5%+ unmute</command> <!-- If needed, replace "Master" with whatever "amixer scontrols" has given you as the control name --> </action> </keybind> <keybind key="XF86AudioLowerVolume"> <action name="Execute"> <command>amixer set Master 5%- unmute</command> </action> </keybind> <keybind key="XF86AudioMute"> <action name="Execute"> <command>amixer set Master toggle</command> </action> </keybind>
Projector/Presentation modeThe projector/presentation mode button will most often simply be understood as Super (Windows key) + P, and not as a separate key code, so you can bind it as such.
<keybind key="XF86Search"> <action name="Execute"> <command>xrandr --auto</command> <!-- A more sophisticated xrandr command (to setup extended display etc) can be used here --> </action> </keybind>
Adding OSD notifications to commands
Most DEs come with a notification server you can use to display on-screen messages. Find out which one your DE/distro uses and simply wrap the commands used above in a script that also fires notifications. notify-send is a simple utility that comes with libnotify itself and can be used in most setups. It should be noted though that it doesn't offer a universal way to re-draw or replace a notification, making it hard to display a progress bar (e.g. for displaying volume or brightness level) and will keep creating new notifications each time it is called.
Some back-ends, like notify-osd, implement an extension supporting this scenario, but you'll have to know what you have in your distro. A back-end-agnostic drop-in replacement called notify-send.sh can also be used to work around the issue with back-ends that don't support this feature themselves.
Simple notify-send exampleFor back-ends supporting the extension, a commands similar to the following could be used to increment the volume and show the level on screen:
notify-send " " -i notification-audio-volume-medium -h int:value:$(amixer set Master 5%+ unmute | grep -m 1 "%]" | cut -d "[" -f2|cut -d "%" -f1) -h string:synchronous:volumeThis, of course, could be enriched to choose the correct icon based on the volume level etc.
Using notify-send.shFor back-ends without the extension, notify-send.sh can be used with a command similar to the above, but with adding --print-id as an argument. This will make the command return the notification ID that can later to be used to replace the notification with a new one by providing --replace=$ID. Of course, the ID would have to persisted somewhere between the calls, like a global variable of a file.