How to add custom shortcut key bindings on Ubuntu 20.04?

2020年07月03日 4693Browse 0Like 0Comments

Remider: I found another handier way to manage multiple custom shortcuts after this article was written and I put it here: manage shortcuts keybindings via files and dconf commands.

Create new custom key bindings via Gnome Ctronl Cetner

Key bindings can be customized using the Gnome Control Center. It can be found as "System Settings" in the menu or accessed on the command line using gnome-control-center.
All the key bindings are in the Keyboard Shortcuts section, and the Custom Shortcuts is the last category at the bottom.

gnome-control-center

Gnome Control Center

  • You can change the default key bindings from other categories, but you cannot remove or disable them here;

  • You can add, remove or modify your own key bindings for applications in Custom Shortcuts category. However, the new custom key bindings cannot override the already defined keybindings in other categories. For example, if you want to set up another shortcut to do screenshot via Print key, that's not applicable here, as this shortcut is aready defined in the Screenshots category and the key is not released.


To create your own application keyboard shortcut in the Keyboard Shortcut panel:

  1. Click the + button(in previous image). The Add Custom Shortcut window will appear:

    Add a costom shortcut
  2. Type a Name to identify the shortcut, and a Command to run an application.

  3. Click the Set Shortcut .... When the Set Custom Shortcut window opens, hold down the desired shortcut key combination.

  4. Click Add.

Note: The command should work properly in your terminal otherwise your shortcut will not work. So you have to test it before you put it there.

Ubuntu Gnome key bindings in dconf Registry

Key bindings are now stored in the dconf database registry, the shortcut added/changed via Gnome Control Center tool will change the registry in the background eventually.

There are three categories of keybindings in the registry:

  1. org.gnome.desktop.wm.keybindings section stores keybindings that are handled by the window manager;
  2. org.gnome.settings-daemon.plugins.power section stores buttons keybindings like "button-hibernate", "button-power", "button-sleep", and "button-suspend". Possible values are "suspend", "sleep", "hibernate", "interactive", and "nothing".
  3. org.gnome.settings-daemon.plugins.media-keys section stores shortcuts from the "launchers", "screenshots", "sound and media", "system", and "custom shortcuts" , these shortcuts are stored in the registry using a "relocatable schema"

The "relocatable schema" name is "org.gnome.settings-daemon.plugins.media-keys.custom-keybinding" is related to Custom Shortcuts, and each custom key binding has three properties: name, command, and binding.

dconf schemas, keys, path related to custom shortcuts keybindings

There are two schemas involved to create a new custom shortcut keybinding.

  1. The first schema uses the key custom-keybindings to store the created custom shortcut folders. Each custom shortcut holds a sub folder(filename convention is customX in path /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/, which is used store the specific definition of each custom shortcut. X is a number starting from 0 for the first added shortcut and it will increase by one , and a new path string is added into custom-keybindings key each time a new shortcut is added.

    • schema name: org.gnome.settings-daemon.plugins.media-keys
    • key: custom-keybindings
    • value: a string array storing all custom shortcut keys' sub-folder paths, e.g: ['/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/', /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/']
  2. The second schema is used to store the three properties of a custom shortcut. The path is required as this schema is relocatable.

    • schema name: gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding
    • path: e.g: /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0, folder used to store the three key-value pairs
    • key: the key should be one of name, command or binding, a complete shortcut should assign value to these three keys.
      1. name: name of the custom binding
      2. command: command to run when the binding is invoked
      3. binding: key(s) binding for the custom binding
    • value: string value of the key

Knowledge about gsettings command

The gsettings command is an essential back end tool to read and write the dconf storage system. Basically, we will use it to get or set the related key in the registry schema.

The differences between gsettings get and gsettings set can be shown by help command:

$ gsettings get --help
Usage:
  gsettings [--schemadir SCHEMADIR] get SCHEMA[:PATH] KEY

Get the value of KEY

Arguments:
  SCHEMADIR A directory to search for additional schemas
  SCHEMA    The name of the schema
  PATH      The path, for relocatable schemas
  KEY       The key within the schema

$ gsettings set --help
Usage:
  gsettings [--schemadir SCHEMADIR] set SCHEMA[:PATH] KEY VALUE

Set the value of KEY to VALUE

Arguments:
  SCHEMADIR A directory to search for additional schemas
  SCHEMA    The name of the schema
  PATH      The path, for relocatable schemas
  KEY       The key within the schema
  VALUE     The value to set 

Examples:

  1. To get or set a key value in the path of the relocatable schema for a custom shortcut by using the property (name, command or binding) as key name:

       $ gsettings get org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/ name
       $ gsettings get org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/ name shortcutNamevalue
       

  2. To get how many shortcuts you've already defined in the Custom Shortcuts category:

       $ gsettings get org.gnome.settings-daemon.plugins.media-keys custom-keybindings | grep -oE \/org.{1,100\}custom[0-9]\{0,2\}
       $ dconf list /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/
       $ gsettings get org.gnome.settings-daemon.plugins.media-keys custom-keybindings | grep -oE \/org.{1,100\}custom[0-9]\{0,2\} |wc -l
       

  3. Check the definition of the first added custom shortcut via sub-folder name custom0 in the custom shortcuts directory path:

       $ gsettings list-recursively  org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/
       org.gnome.settings-daemon.plugins.media-keys.custom-keybinding command 'flameshot gui'
       org.gnome.settings-daemon.plugins.media-keys.custom-keybinding name 'Flameshot Selection Screenshot'
       org.gnome.settings-daemon.plugins.media-keys.custom-keybinding binding 'F1'
       

Oh...no, look at the commands! In example 1 & 3, the CLI are tooooooo long when reading or writing a key from a relocatable schema. The main reason is that path string is required to when querying the relocatable schema org.gnome.settings-daemon.plugins.media-keys.custom-keybinding , which makes it even harder to use gsettings processing one custom shortcuts holding three keys(properties).

If we do want to take a chance to add custom shortcuts via commands, I recommend to use Bash or Python scripts.

Using a Bash script to add custom shortcuts

The following Bash script uses gsetting get and gsettings set to create custom shortcut in dconf database, it hides the long and heavy command arguments.

```
#!/bin/bash

CMD_BEGINNING="gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding"
KEY_PATH_BASE="/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings"

# get exsited shortcut sub folders
EXISTED_PATHS=$(gsettings get org.gnome.settings-daemon.plugins.media-keys custom-keybindings)

# find how many shorcut keybindings already defined, and the value will be used as the new shortcut index
NEW_KEY_INDEX=$(dconf list /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/ | wc -l)

NEW_KEY_PATH=$KEY_PATH_BASE/custom$NEW_KEY_INDEX/

if [ $NEW_KEY_INDEX -gt 0 ] 
then
  NEW_PATHS=${EXISTED_PATHS%]},\ \'${NEW_KEY_PATH}\'\]  # Add the new custom folder into `custom-keybindings` key
else
  NEW_PATHS="['$NEW_KEY_PATH']"
fi

#########################################################################################
# Four steps to create a new shortcut keybinding

# Step 1: Add one custom shortcut folder in the "Custom Shortcuts" category 
gsettings set org.gnome.settings-daemon.plugins.media-keys custom-keybindings "${NEW_PATHS}"

# Step 2-4: Set name, command, and binding properties of the shortcut
if [ $# -eq 3]
then
  $CMD_BEGINNING:$NEW_KEY_PATH name $1
  $CMD_BEGINNING:$NEW_KEY_PATH command $2
  $CMD_BEGINNING:$NEW_KEY_PATH binding $3
fi

#########################################################################################
# Alternatively, you can put the gsetting key value to set literally to avoid parameters typing errors.
# $CMD_BEGINNING:$NEW_KEY_PATH name "Select an area to screenshot"
# $CMD_BEGINNING:$NEW_KEY_PATH command "flameshot gui"
# $CMD_BEGINNING:$NEW_KEY_PATH binding "F1"

Save the code into create-shortcuts.sh, then put your shortcut's name, command, key binding as arguments in the command line to create a new shortcut:

 $ chmod +x create-shortcut.sh
$ ./create-shortcut.sh "Select an area to screenshot" "flameshot gui" "F1"

You should be aware of the following things:

  1. binding key value rule: the frequently used GNOME control or functions keys are <Super>, <Ctrl>,<Alt>, <Shift>, <Esc>, <Print>, <Fn>, etc. However, the key should be quoted by angle brackets if the key is not the last one.

    • Valid key(s) strings examples: <Ctrl><Shift>Print, <Alt>Print, Print, <Super>R, F1
    • Invalid key(s) strings examples: <F5>, <Print>, ...
  2. Test the command before passing into script

  3. Do not overide the already defined system shortcuts

  4. If you have multiple shortcuts to create, you should modify the NEW_PATHS variable and assign name, command, binding value literally in the script rather than passing them when running the script.

Related commands you may need

  • You can reset the broken dconf registry to recover a normal desktop when you get an errors message due to erroneuos script commands:

    "Oh no! Something has gone wrong. A problem has occurred and the system can’t recover. Please log out and try again."

    Press CRTL + ALT + F3 switch to login to another terminal, then run the following command to clear custom shortcuts:

       $ dconf reset /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings
       $ gsettings set org.gnome.settings-daemon.plugins.media-keys custom-keybindings "['']"
       

    if it doesn't work, use dconf reset -f to let dconf force reset/clear all the keybindings.

  • List, backup, restore all the custoum shortcuts keybindings:

       $ dconf dump /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/
       $ dconf dump /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/ > shortcuts.bakcup
       $ dconf load /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/ < shortcuts.bakcup
       

  • You may need this gui tool to explore or modify dconf registry key values as well:

    $ sudo apt install -y dconf-editor 

Because of the relocatable schema, it is harder to use "gsettings" with custom shortcuts, as we have to operate all the properties by gsettings commands instead of a single command line.

That's the reason why we need script to create custom keybindings if we don't want to do it mannualy from the Gnome Control Center.

Afterwords

The way using command or script to create custom shortcuts may be not as handy as using the GUI tool, and it might harm to GNOME application if you set the wrong schema or key values. You should be cautious to run the script. However, it provides us opportunity to explore and better understand GNOME desktop system.

References

 1. https://wiki.ubuntu.com/Keybindings
 2. https://developer.gnome.org/gio/stable/gsettings-tool.html
 3. https://developer.gnome.org/dconf/unstable/dconf-overview.html
 4. https://askubuntu.com/questions/22313/what-is-dconf-what-is-its-function-and-how-do-i-use-it

Sunflower

Stay hungry stay foolish

Comments