- Figure out how to set up 1 global hotkey in your chosen desktop environment,
- Assign to it some simple dummy target ommand. Which you know always works. And is easily verified
That will ensure you can check and test that a specific hotkey assignment is actually definately working independantly of the specific desired action. This is important because the desktop environment can also occupy pre-configured 'system keys' and if they are already being mapped to something other default system wide actions then (likely) will silently be ignored.
So being independant here from the subsequent specific desired target actions in some special app or whatever. Which themselves definately might have other own different issues or not behave correctly. And especially when being invoked from the compositor via this method (rather than a logged in user terminal etc.)
- A global hotkey can only be bound to always execute 1 specific program binary executable or cmdline string of your choosing
- Therefore it can be launching any cli app or a gui app on your system
- Providing also that the command (which runs as your own username) also has any necessary login privileges to execute properly on the system
- The global hotkey assignment should also let you pass in any fixed strings of program arguments after the command
- But they will be invariant and mapped directly just unique only for that specific particular key binding
- So not any wildcard substitution etc. and 1 command per individual key combination etc.
- Triggered only on keydown (not keyup), and not possible to do fancy things like press and hold for long keypress, etc.
- In the case of the CLI program, if it's something not already running in the background then that's usually no problem
- Just directly execute it from the hotkey assignment keybinding. And you're done
- However in the case of the GUI program (or a background task). Then things might be easy. Or they might turn out to be a lot more complicated
This could go variety of different ways, depending entirely on the specific target program which you want to interact with. Some examples:
- If the GUI program (or other background task) is
- single-instance
- does not relaunch any new instance once it is already running
- instead supports being sent control signals with subsequent invocations on the cmdline
- Great! --> then check for messaging flags / controls for the app in it's
--help
terminal output
- Great! --> then check for messaging flags / controls for the app in it's
- If the program exposes a dbus messaging interface
- Great! ---> that can be probed with the GUI helper utility known as
d-feet
- After launching
d-feet
---> BE SURE to click theSession Bus
tab- Because
Session Bus
= the USER dbus session infos (rather than System Bus, the default shown)
- Because
- After launching
- While the app is running, it may expose actions on it's D-Bus control interface
- but only if it specifically supports and implements them on D-Bus protocol
- not all programs support D-Bus or expose all of the controls you might require
- but some programs (for example OBS), might have 3rd party plugins or helper service etc.
- Great! ---> that can be probed with the GUI helper utility known as
- With the
d-feet
program you can directly test those exposed d-bus interface commands api- And also discover what the d-bus address endpoint name is, which command names to use, etc.
- After gathering these necessary info, Then you can bind your global hotkey to run a
dbus-send ...
command
Example:
dbus-send --print-reply=literal --session --dest=org.mpris.MediaPlayer2.audacious /org/mpris/MediaPlayer2 org.freedesktop.DBus.Properties.Get string:org.mpris.MediaPlayer2.Player string:Volume
- if the program has other interface to control it by, for example:
- an optional localhost http web interface, or http API endpoint for json / rest etc.
- a shared background daemon etc. if the gui program is just a client side interface
- piping to a unix socket file in
/tmp/
folder, or writing other files to disk - using the
inotify
command to watch for local file or folder changes on the disk - in memory message passing via other message passing protocol (which isnt dbus), eg POSIX SHM semaphores, etc.
- writing things or sending messages to the kernel, via some system wide exposed kernel api or interface
- directly writing to a block of shared memory, or other types of debugging interface (like
adb
for android)
- if the GUI program is a DAW you can
- map a global hotkey to execute a cmdline
send midi ...
- then use
send-midi
command to send midi commands to it - then seperately map and match up those midi commands to execute specific actions within the DAW
- map a global hotkey to execute a cmdline
- if the GUI program
- exposes no reasonable way to interface with it
- then you will need to use some general system privelidge level of cmdline tool(s)
- wrap them into a more complex shell script to
- find the app window, from the list of currently running GUI apps
- activate the found app
- change window focus. so the app is in foreground and currently focussed
- simulate the necessary keypress events and mouse movements, mouse clicks etc.
- unfocus the targeted app, and switch back focus to the original app
- exposes no reasonable way to interface with it
To achieve this ^^ above tasks for wayland (gnome) requires some different set of tools. Withing the exact features supported by specific tools there is sometimes a bit of overlap between xorg/x11 and wayland. And sometimes no overlap. And it's complicated! You will need to cobble together a variety of lower level stuff. And the actual names of these tools, and functionally what they exactly can support - that will also change over time too.
Right now (as of oct-2021), the best solutions can all be found by browsing the following link tree: