46

How to set custom keyboard shortcuts from terminal for different Linux versions?

Basically I want to know where Linux stores the keyboard shortcut files and how it can be edited.

On my research I found a file ~/.config/compiz-1/compizconfig but it was more or like encrypted when I tried to open it with nano.

  • Note, XFCE/Xubuntu systems already have an answer here – Ulad Kasach Apr 30 '16 at 2:14
55

Adding shortcut keybindings in two steps from the command line (14.04+)

Adding custom shortcuts from the command line can be done, but is a bit complicated; it needs to be done in a few steps per keybinding. On the other hand, it is pretty straightforward and can very well be scripted if you somehow want to do it from the command line (that was the question, right?).

Just like in your interface (System Settings > "Keyboard" > "Shortcuts" > "Custom Shortcuts"), Custom keyboard shortcuts are made from command line in two steps:

  1. create the keybinding by editing (adding to-) the list that is returned by the command:

    gsettings get org.gnome.settings-daemon.plugins.media-keys custom-keybindings
    

    The returned list looks like (if it were only one shortcut currently):

    ['/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/']
    

    Apply the edited list by the command:

    gsettings set org.gnome.settings-daemon.plugins.media-keys custom-keybindings "[<altered_list>]"
    

    (mind the double quotes)

    N.B. No need to say that the mention in the list (e.g. custom1, custom2) should be a unique one. If you script it, the script should prevent duplicates. In this case the edited list should look like e.g.:

    ['/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/', '/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/']
    

    to add one keybinding: custom1

  2. set its properties:

    • name:

      gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/ name '<newname>'
      
    • command:

      gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/ command '<newcommand>'
      
    • Key combination (for example <Primary><Alt>g):

      gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/ binding '<key_combination>'
      

Useful information can be found here

Example script to set a new custom shortcut

The script below can be used to set a new shortcut key combination from the command line. It can be used with the command (assuming the key combination is available):

python3 /path/to/script.py '<name>' '<command>' '<key_combination>'

An example:

To set a shortcut key combination to open gedit with the key combination Alt+7:

python3 /path/to/script.py 'open gedit' 'gedit' '<Alt>7'

The script:

#!/usr/bin/env python3
import subprocess
import sys

# defining keys & strings to be used
key = "org.gnome.settings-daemon.plugins.media-keys custom-keybindings"
subkey1 = key.replace(" ", ".")[:-1]+":"
item_s = "/"+key.replace(" ", "/").replace(".", "/")+"/"
firstname = "custom"
# get the current list of custom shortcuts
get = lambda cmd: subprocess.check_output(["/bin/bash", "-c", cmd]).decode("utf-8")
array_str = get("gsettings get "+key)
# in case the array was empty, remove the annotation hints
command_result = array_str.lstrip("@as")
current = eval(command_result)
# make sure the additional keybinding mention is no duplicate
n = 1
while True:
    new = item_s+firstname+str(n)+"/"
    if new in current:
        n = n+1
    else:
        break
# add the new keybinding to the list
current.append(new)
# create the shortcut, set the name, command and shortcut key
cmd0 = 'gsettings set '+key+' "'+str(current)+'"'
cmd1 = 'gsettings set '+subkey1+new+" name '"+sys.argv[1]+"'"
cmd2 = 'gsettings set '+subkey1+new+" command '"+sys.argv[2]+"'"
cmd3 = 'gsettings set '+subkey1+new+" binding '"+sys.argv[3]+"'"

for cmd in [cmd0, cmd1, cmd2, cmd3]:
    subprocess.call(["/bin/bash", "-c", cmd])

How to use:

Paste the script into an empty file, save it as set_customshortcut.py, run it as explained above.

Some of the mostly used key mentions (found experimentally, looking into the changes the GUI way made into the binding value):

Super key:                 <Super>
Control key:               <Primary> or <Control>
Alt key:                   <Alt>
Shift key:                 <Shift>
numbers:                   1 (just the number)
Spacebar:                  space
Slash key:                 slash
Asterisk key:              asterisk (so it would need `<Shift>` as well)
Ampersand key:             ampersand (so it would need <Shift> as well)

a few numpad keys:
Numpad divide key (`/`):   KP_Divide
Numpad multiply (Asterisk):KP_Multiply
Numpad number key(s):      KP_1
Numpad `-`:                KP_Subtract

etc.

  • 4
    Excellent answer. I need 100 buttons of upvotes for that script. ;) – Anandu M Das Mar 17 '15 at 8:48
  • @AnanduMDas Thanks! Glad you like it :) – Jacob Vlijm Mar 17 '15 at 8:57
  • @JacobVlijm Could you please explain a little on the Key combination part? What does that <primary> tag indicate? And instead of letter g I can replace any letter I think,ryt? – Anonymous Platypus Mar 17 '15 at 9:53
  • 1
    @VladK ai, xubuntu, could be that xubuntu's shortcuts are (still) set in an xml file. I will have to look. If so, we need to reopen your question, tagged as xubuntu- specific. – Jacob Vlijm Apr 22 '16 at 19:54
  • 1
    Thank you, @JacobVlijm, I've tried it out. And i just find out that my fix was a mistake. There is some really tricky here. custom-keybinding shouldn't contain "s" at the end when inside a schema. But, it should contain "s" when act as key or in path. Otherwise, the "set" command will throw exception. So, please remove the "s" of custom-keybinding in schema. Besides, your python script should update too. – e-cloud Jul 1 '16 at 7:53
10

All the custom keyboard shortcuts settings are stored in the dconf database.

You can easily access them with dconf-editor:

sudo apt-get install dconf-editor

Then go to the following dconf path in the editor:

/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/

enter image description here

  • Is the location same for all versions of Linux? Or atleast all the versions of Ubuntu? – Anonymous Platypus Mar 16 '15 at 11:42
  • 1
    @AnonymousPlatypus: this is the location of the settings since 14.04 (I can't tell for other distro) – Sylvain Pineau Mar 16 '15 at 11:47
  • 2
    This is graphical method, and not from terminal – Anandu M Das Mar 17 '15 at 8:56
  • 1
    What do I do if my media-keys key does not have a custom-keybindings subkey? – Brandon Kuczenski Jun 27 '15 at 20:53
  • The question was about terminal, not GUI, so answer is irrelevant – Alexei Martianov Jan 15 at 4:10
9

There is plain a simple way of doing that using dconf :

dconf write /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/command "'move-window.sh'"
dconf write /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/binding "'<Primary><Alt>Page_Down'"
dconf write /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/name "'move-window'"

Using gsettings :

gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/ name "'move-window'"
gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/ binding "'<Primary><Alt>Page_Down'"
gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/ command "'/usr/local/bin/move-window.sh'"

You need to increase number in the custom0part for adding more bindings, ie. custom1, custom2, etc.

To make it permanent, just add it to .bash_profile or a similar script that is ran by login shells. Just don't do it for non-login shells .bashrc because from my experience these dconf and gsettings slow it down significantly. Changing/Adding 30 bindings takes a second ! You don't want this in non-login shell (.bashrc)!

  • 1
    Both fail in Ubuntu 18.04. Following @Jacob Vlijm's answer and this community wiki, you need to add custom0 to the custom shortcut list, e.g. with gsettings set org.gnome.settings-daemon.plugins.media-keys custom-keybindings "['.../custom1/']". I don't know about dconf. – mmorin Oct 4 '18 at 15:02
6

Adding shortcut keybindings from the command line in 12.04

To prevent the accepted answer to become too extensive, posting a separate solution for 12.04.

Until (and including) 12.04, custom keybindings are not stored in the dconf database, but in ~/.gconf/desktop/gnome/keybindings (in an xml file, in subfolders like custom0 etc).

The script below creates the xml file and its containg folder, automatically named correctly.

How to use

  1. Paste the script into an empty file, save it as set_customshortcuts_12.py
  2. Run it with the command:

    python /path/to/set_customshortcuts_12.py <name> <command> <key1> <key2> <key3>
    

    key3 is optional, commands can be for example:

    python /path/to/set_customshortcuts_12.py run_browser firefox Primary 7 
    

    or

    python /path/to/set_customshortcuts_12.py run_texteditor gedit Primary Alt 3 
    

Notes

  • note that the naming of the keys is different from editing gsettings. The keys are named like they show in System Settings > "Keyboard" > "Shortcuts" > "Custom Shortcuts", as far as I can see.
  • I tested the script on 12.04 under VirtualBox; it needed a log out/in for the changes to take place.
#!/usr/bin/env python
import os
import sys

home = os.environ["HOME"]
name = sys.argv[1]
command = sys.argv[2]
keys = sys.argv[3:]

keyfile = [
    '<?xml version="1.0"?>',
    '<gconf>',
    '\t<entry name="action" mtime="1427791732" type="string">',
    '\t\t<stringvalue>'+command+'</stringvalue>',
    '\t</entry>',
    '\t<entry name="name" mtime="1427791732" type="string">',
    '\t\t<stringvalue>'+name+'</stringvalue>',
    '\t</entry>',
    '\t<entry name="binding" mtime="1427791736" type="string">',
    '\t</entry>',
    '</gconf>',
    ]

if len(keys) == 2:
    keyfile.insert(9, '\t\t<stringvalue>&lt;'+keys[0]+'&gt;'+keys[1]+'</stringvalue>')
else:
    keyfile.insert(9, '\t\t<stringvalue>&lt;'+keys[0]+'&gt;&lt;'+keys[1]+'&gt;'+keys[2]+'</stringvalue>')

n = 0
while True:
    check = home+"/"+".gconf/desktop/gnome/keybindings/custom"+str(n)
    if os.path.exists(check):
        n = n+1
    else:
        newdir = check
        newfile = check+"/"+"%gconf.xml"
        break

os.makedirs(newdir)
with open(newfile, "wt") as shortcut:
    for l in keyfile:
        shortcut.write(l+"\n")
1

You can set a new custom shortcut without a python script, by using sed. You just have to set name, binding and action to your choice in the following script:

name="myaction"
binding="<CTRL><ALT>v"
action="/usr/local/bin/myaction"

media_keys=org.gnome.settings-daemon.plugins.media-keys
custom_kbd=org.gnome.settings-daemon.plugins.media-keys.custom-keybinding
kbd_path=/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/$name/
new_bindings=`gsettings get $media_keys custom-keybindings | sed -e"s>'\]>','$kbd_path']>"| sed -e"s>@as \[\]>['$kbd_path']>"`
gsettings set $media_keys custom-keybindings "$new_bindings"
gsettings set $custom_kbd:$kbd_path name $name
gsettings set $custom_kbd:$kbd_path binding $binding
gsettings set $custom_kbd:$kbd_path command $action
1

Wrote a script for that. See below.

See the usage in the creatShortcut invocation.

export nextShortcutId=0
function creatShortcut() {
    name="$1"
    commandToRun="$2"
    binding="$3"
    path="/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom${nextShortcutId}"
    nextShortcutId=$nextShortcutId+1
    dconf write "$path/name" "'""$name""'"
    dconf write "$path/command" "'""$commandToRun""'"
    dconf write "$path/binding" "'""$binding""'"
}

# dconf write /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/binding '"<Primary><Shift>exclam"'
creatShortcut 'copyq show' 'copyq show' '<Primary><Shift>exclam'
creatShortcut 'System Monitor' 'gnome-system-monitor' '<Primary><Alt>m'
creatShortcut 'Suspend' 'systemctl suspend -i' '<Super>d'
creatShortcut 'Volume Up' 'amixer -D pulse sset Master 5%+' '<Super>Page_Up'
creatShortcut 'Volume Down' 'amixer -D pulse sset Master 5%-' '<Super>Page_Down'

overallbindings=""
for ((i = 0 ; i < $nextShortcutId ; i++ ));
do
    overallbindings="$overallbindings, '$customindingPathPrefix$i/'"
done
overallbindings="[${overallbindings:2}]" # Delete the first 2 chars: " ," - space and comma
# echo $overallbindings

# Update the list of bindings for the shortcuts to work
dconf write /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings "$overallbindings"
# dconf write /org/gnome/settings-daemon/plugins/media-keys/custom-keybindings "['/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/', '/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/', '/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom2/', '/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom3/', '/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom4/', '/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom5/']"
  • It would be perfect if nextShortcutId could auto-detect if old keys are already there (already created by other programs) just to make certain that there are no conflicts. Also, check to see if anything else is bound to the entered keys. – Jack Giffin Jan 19 at 1:19

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.