Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

I usually load a new version for every release to keep my OS fresh while preserving the last version on another partition as backup. I also employ a lot of custom key mappings.

I've figured out how to transfer the majority of my configuration across systems so far but I can't figure out where the custom keyboard shortcut mappings are stored.

Does anybody know where gnome puts these? Are there separate user config (i.e., ~/) and system config (i.e. /etc) files?

share|improve this question
    
How did you change the settings? Using GConf Editor? I'm guessing you want gconftool-2 --dump /apps/metacity or something like that. –  Mikel Feb 13 '11 at 6:51
    
@Mikel Thanks a bunch for that comment. From what I can tell in gconf-editor, most of the keybindings are stored under /apps/metacity while the rest are spread around. I'm currently writing Import/Export python scripts to make backup/restore keybindings a one-click operation. –  Evan Plaice Feb 16 '11 at 5:09

3 Answers 3

Ubuntu has changed since Evan Plaice's answer was accepted.

Keybindings have moved from gconf to dconf. Gconf stores its data in xml files and was accessed by gconf-editor and gconf-tool2. Dconf stores its data in a binary format and is accessed by dconf-editor and gsettings.

The number of places that keybindings are stored is reduced. There is now a centralized dconf path to store window manager keybindings (org.gnome.desktop.wm.keybindings). There are mapping files in the directory /usr/share/gnome-control-center/keybindings/that show how these are applied based on the window manager you are actually using (compiz or metacity).

A second set of non-window-manager related key bindings is stored in the dconf path org.gnome.settings-daemon.plugins.media-keys

There is a third set of keybindings related to power buttons that is stored in the dconf path org.gnome.settings-daemon.plugins.power. There is currently a bug in the GUI that lets you configure keybindings. It doesn't know about these settings. I have a "sleep" button on my keyboard. If I want to reassign it to other functionality, I have to disable the setting in org.gnome.settings-daemon.plugins.power manually. The GUI doesn't do it for me (although it assigns the new functionality just fine).

The other wrinkle is custom key bindings. These are stored in dconf using relocatable schema. Its done this way because there are an arbitrary number of them. A reasonable approach, but it makes listing or modifying them via the command line harder than it should be.

I also found out that the GUI that allows you to assign keybindings is limited in a way that annoys me. The GUI allows exactly ONE keybinding to be assigned to each action. In dconf, you can set an array of bindings for a single action. This is useful to me. For example, I like to have the "close-window" action assigned to the traditonal Alt-F4 as well as to an easier to hit single button on my keybord.

I have written a Perl script to dump all the keybindings to a csv file, or restore them from the csv file. For example to dump the keybindings you might use:

./keybindings.pl -e /tmp/keys.csv

and to restore them you might use:

./keybindings.pl -i /tmp/keys.csv

#!/usr/bin/perl

use strict;

my $action = '';
my $filename = '-';

for my $arg (@ARGV){
    if ($arg eq "-e" or $arg eq "--export"){
        $action = 'export';
    } elsif ($arg eq "-i" or $arg eq "--import"){
        $action = 'import';
    } elsif ($arg eq "-h" or $arg eq "--help"){
        print "Import and export keybindings\n";
        print " -e, --export <filename>\n";
        print " -i, --import <filename>\n";
        print " -h, --help\n";
        exit;
    } elsif ($arg =~ /^\-/){
        die "Unknown argument $arg";
    } else {
        $filename = $arg;
        if (!$action){
            if ( -e $filename){
                $action='import';
            } else {
                $action='export';
            }
        }
    }
}

$action='export' if (!$action);
if ($action eq 'export'){
    &export();
} else {
    &import();
}

sub export(){
    my $gsettingsFolders = [
        ['org.gnome.desktop.wm.keybindings','.'],
        ['org.gnome.settings-daemon.plugins.power','button'],
        ['org.gnome.settings-daemon.plugins.media-keys','.'],
    ];

    my $customBindings = [
    ];

    $filename = ">$filename";
    open (my $fh, $filename) || die "Can't open file $filename: $!";

    for my $folder (@$gsettingsFolders){
        my @keylist = split(/\n/, `gsettings list-recursively $folder->[0]`);
        foreach my $line (@keylist){
            if ($line =~ /^([^ ]+) ([^ ]+)(?: \@[a-z]+)? (.*)/){
                my ($path, $name, $value) = ($1,$2,$3);
                if ($name eq "custom-keybindings"){
                    $value =~ s/[\[\]\' ]//g;
                    my @c = split(/,/, $value);
                    $customBindings = \@c;
                } elsif ($name =~ /$folder->[1]/){
                    if ($value =~ /^\[|\'/){
                        if ($value =~ /^\[\'(?:disabled)?\'\]$/){
                            $value = '[]';
                        } 
                        print $fh "$path\t$name\t$value\n";
                    }
                }        
            } else {
                die "Could note parse $line";
            }
        }
    }   

    for my $folder (@$customBindings){
        my $gs = `gsettings list-recursively org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:$folder`;
        my ($binding) = $gs =~ /org.gnome.settings-daemon.plugins.media-keys.custom-keybinding binding (\'[^\n]+\')/g;
        my ($command) = $gs =~ /org.gnome.settings-daemon.plugins.media-keys.custom-keybinding command (\'[^\n]+\')/g;
        my ($name) = $gs =~ /org.gnome.settings-daemon.plugins.media-keys.custom-keybinding name (\'[^\n]+\')/g;
        print $fh "custom\t$name\t$command\t$binding\n"    
    }

    close($fh);
}

sub import(){

    $filename = "<$filename";
    open (my $fh, $filename) || die "Can't open file $filename: $!";

    my $customcount=0;

    while (my $line = <$fh>){
        chomp $line;
        if ($line){
            my @v = split(/\t/, $line);
            if (@v[0] eq 'custom'){
                my ($custom, $name, $command, $binding) = @v;
                print "Installing custom keybinding: $name\n";
                print `gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom$customcount/ name \"$name\"`;
                print `gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom$customcount/ command \"$command\"`;
                print `gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom$customcount/ binding \"$binding\"`;
                $customcount++;
            } else {
                my ($path, $name, $value) = @v;
                print "Importing $path $name\n";
                print `gsettings set \"$path\" \"$name\" \"$value\"`;
            }
        }       
    }
    if ($customcount > 0){
        my $customlist = "";
        for (my $i=0; $i<$customcount; $i++){
            $customlist .= "," if ($customlist);
            $customlist .= "'/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom$i/'";            
        }
        $customlist = "[$customlist]";
        print "Importing list of custom keybindings.\n";
        print `gsettings set org.gnome.settings-daemon.plugins.media-keys custom-keybindings \"$customlist\"`;
    }

    close($fh);
}
share|improve this answer
    
I filed two bugs against ubuntu gnome-control-center keyboard shortcuts. I found them while creating this script. bugs.launchpad.net/ubuntu/+source/gnome-control-center/+bug/… and bugs.launchpad.net/ubuntu/+source/gnome-control-center/+bug/… –  Stephen Ostermiller Nov 15 '12 at 13:57
    
Thanks for the script @Stephen, just tried on Ubuntu 13.10 and it just worked! Created a gist for easy sharing: gist.github.com/elgalu/8511861#file-keybindings-pl –  elgalu Jan 19 at 22:28
    
It worked for Fedora too! Thanks! –  Ilia Rostovtsev May 22 at 19:18
up vote 11 down vote accepted

The keyboard shortcuts are not stored in any one single place

Depending on your distro version, the keyboard shortcuts application may be called different things in the GUI but on the command line it should be called 'gnome-keybinding-properties'. It turns out that this neat little application brings all of the shortcuts into one convenient place for users to edit.

Since no one-click export/import tool exists for keybindings in Ubuntu, I wrote one in python:

Here's a link to the script

An export pulls the settings from the system. Essentially it contains a list of all the keybinding locations is hard-coded into a dictionary in the script. The script emumerates the list and runs the command "gconftool-2 --get [location]" for every key and stores the value in the dictionary along with the key. Then when you specify the location to save the settings, it saves the dictionary it to the file in json format.

An import script reverses this process. It loads the dictionary from the json file. Then it enumerates through these and runs the command "gconftool-2 --type string --set [location] [value]" to restore all of the saved settings.

One shot on either end and it saves/restores every single keyboard shortcut without touching any of the other system configuration settings.

The only dependencies for these scripts are:

  • python (tested and working in 2.6, 2.7, and 3.1)
  • gconftool-2 (comes standard with an Ubuntu install)
  • zenity (comes standard with an Ubuntu install)

Python is needed to execute the script, gconftool-2 is used to get/set the settings, zenity is needed for the file load/save gui dialogs.

I have created an entry on Ubuntu Brainstorm and am making progress on getting this feature introduced into the 'gnome-keybinding-properties' GUI menu.

Update:

I updated combined the import and export scripts into one, added full command line functionality (including --help info) and made it compatible for both python2x and python3k. Also, added the link to the Ubuntu Brainstorm idea.

share|improve this answer
    
Brainstorm is hardly a good place for actual improvements of Ubuntu - only the top 10 issues actually gets the developer attention. I'd suggest you find the Launchpad page for gnome-keybinding-properties and post a patch with your script. –  Oxwivi Mar 11 '11 at 5:43
    
Your script is good for shortcuts listed in/handled by gconftool-2/gconf-editor... and I suppose it depends on what one calls a GNOME keyboard shortcut... but it isn't picking up system-wide user shortcuts added by Keyboard Shortcuts ie. gnome-keybinding-properties ... nor other keybindings added by, for example Xbindkeys ... so I suspect that gconf' is not where the sysetem-wide shortcuts they are "stored", but that it is an interface to something/somewhere deeper ... (I've been looking for that place.. :) . maybe I just need to keep 3 'exported' lists for now... –  Peter.O Mar 11 '11 at 5:51
    
@fred.bear I'm pretty sure they're all stored in gconf but I'm finding that new keybindings are added to gnome-keybinding-properties when you change from the defaults in the control panel. The current script will do the default shortcuts found in the GUI but it won't be able to support all shortcuts without tighter integration into the GUI. There's currently already a blueprint open for this so I'm trying to get in touch with the other developer who proposed this to work out the details on launchpad. For now... this works. –  Evan Plaice Mar 14 '11 at 5:32

In 11.10 running Gnome classic I found a set of directories (Custom0, Custom1...) under

$HOME/.gconf/desktop/gnome/keybindings

I copied those directories to the same folder in a clean 12.04 installation (again running with Gnome fallback), logged out and logged in again. The keybindings got a bit messed up in transition (something funny happened to the SUPER modifier) but otherwise they were there.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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