Onde estão armazenados os atalhos de teclado do GNOME?

53

Normalmente, carrego uma nova versão para cada versão para manter meu sistema operacional atualizado, preservando a última versão em outra partição como backup. Também emprego muitos mapeamentos de teclas personalizados.

Eu descobri como transferir a maioria da minha configuração entre sistemas até agora, mas não consigo descobrir onde os mapeamentos de atalhos de teclado personalizados estão armazenados.

Alguém sabe onde o gnome os coloca? Existem arquivos de configuração do usuário separados (por exemplo, ~ /) e de configuração do sistema (por exemplo / etc)?

Evan Plaice
fonte
2
Como você alterou as configurações? Você está usando o GConf Editor? Acho que você quer gconftool-2 --dump /apps/metacityou algo assim.
Mikel
11
@ Mikel Muito obrigado por esse comentário. Pelo que posso dizer no gconf-editor, a maioria das combinações de teclas é armazenada em / apps / metacity enquanto o restante está espalhado. Atualmente, estou escrevendo scripts python para Importar / Exportar para tornar as combinações de teclas de backup / restauração uma operação com um clique.
Evan Plaice
Relacionado: askubuntu.com/questions/17626/…
Ciro Santilli escreveu

Respostas:

45

O Ubuntu mudou desde que outras respostas a essa pergunta foram escritas.

As combinações de teclas passaram do gconf para o dconf. O Gconf armazena seus dados em arquivos xml e foi acessado por gconf-editore gconf-tool2. O Dconf armazena seus dados em um formato binário e é acessado por dconf-editore gsettings.

O número de locais em que as combinações de teclas são armazenadas é reduzido. Agora existe um caminho dconf centralizado para armazenar as combinações de teclas do gerenciador de janelas ( org.gnome.desktop.wm.keybindings). Existem arquivos de mapeamento no diretório /usr/share/gnome-control-center/keybindings/que mostram como eles são aplicados com base no gerenciador de janelas que você está realmente usando (compiz ou metacidade).

Um segundo conjunto de ligações de teclas não relacionadas ao gerenciador de janelas é armazenado no caminho dconf org.gnome.settings-daemon.plugins.media-keys

Há um terceiro conjunto de combinações de teclas relacionadas aos botões liga / desliga que são armazenados no caminho do dconf org.gnome.settings-daemon.plugins.power. Atualmente, existe um bug na GUI que permite configurar as combinações de teclas. Não conhece essas configurações. Eu tenho um botão "dormir" no meu teclado. Se eu quiser reatribuí-lo para outra funcionalidade, tenho que desativar a configuração org.gnome.settings-daemon.plugins.powermanualmente. A GUI não faz isso por mim (embora atribua a nova funcionalidade muito bem).

A outra ruga é a ligação de teclas personalizadas. Eles são armazenados no dconf usando o esquema realocável. É feito dessa maneira porque há um número arbitrário deles. Uma abordagem razoável, mas torna mais difícil listá-las ou modificá-las por meio da linha de comando.

Também descobri que a GUI que permite atribuir combinações de teclas é limitada de uma maneira que me incomoda. A GUI permite que exatamente UMA combinação de teclas seja atribuída a cada ação. No dconf, você pode definir uma matriz de ligações para uma única ação. Isso é útil para mim. Por exemplo, eu gosto de ter a ação "fechar a janela" atribuída ao traditonal Alt-F4, bem como a um botão mais fácil de pressionar no meu teclado.

Eu escrevi um script Perl para despejar todas as combinações de teclas em um arquivo csv ou restaurá-las a partir do arquivo csv. Por exemplo, para despejar as combinações de teclas que você pode usar:

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

e para restaurá-los, você pode usar:

./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;
        $command =~ s/\"/\\\"/g;
        $command =~ s/^'(.*)'$/$1/g;
        $command =~ s/\'/\'\\\'\'/g;
        $command = "\'$command\'";
        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);
}

Isso inclui a correção do user2589537 para permitir comandos personalizados com aspas.

Stephen Ostermiller
fonte
2
Eu arquivei dois bugs nos atalhos de teclado do ubuntu gnome-control-center. Eu os encontrei ao criar este script. bugs.launchpad.net/ubuntu/+source/gnome-control-center/+bug/… e bugs.launchpad.net/ubuntu/+source/gnome-control-center/+bug/…
Stephen Ostermiller
11
Obrigado pelo script @Stephen, tentei no Ubuntu 13.10 e funcionou! Criado uma essência para fácil compartilhamento: gist.github.com/elgalu/8511861#file-keybindings-pl
Leo Gallucci
Trabalho incrível e bom trabalho, documentando os detalhes.
Evan Plaice
2
Ainda funciona no Ubuntu GNOME 3.2 - Obrigado!
klequis
11
"obras" tecnicamente para mim, mas provavelmente seria necessário para assistir diferentes seções dconf para Ubuntu-MATE (ou seja [org/mate/marco/global-keybindings], [org/mate/marco/window-keybindings]...)
Frank Nocke
17

Como fazer backup das configurações do dconf, como atalhos de teclado

  1. Coloque todos eles em um arquivo:

    dconf dump / >~/.config/dconf/user.conf
    
  2. Abra esse arquivo em um editor de texto e selecione as configurações importantes:

    editor ~/.config/dconf/user.conf
    

    Se você usa o Vim, desejará esse destaque de sintaxe .

    Você logo se perguntará o que é<Primary> .

  3. Se você não sabe o nome da configuração, mas sabe como modificá-la a partir de uma GUI unity-control-center, execute:

    dconf watch /
    

    e modifique-os. A configuração exata aparecerá no terminal.

  4. Quando você deseja restaurar essas configurações, execute:

    dconf load / <~/.config/dconf/user.conf
    
  5. O Git rastreia o arquivo de configuração para nunca perdê-lo. https://github.com/andsens/homeshick é o meu método favorito atual.

Testado no Ubuntu 15.10. Dica adaptada de: http://catern.com/2014/12/21/plain-text-configuration-gnome.html

Infelizmente, o terminal Gnome é resistente a essas edições devido aos IDs imprevisíveis do perfil: Edite o perfil do Gnome-Terminal na linha de comando em 18.04

Ciro Santilli adicionou uma nova foto
fonte
15

Os atalhos de teclado não são armazenados em um único local

Dependendo da versão da sua distribuição, o aplicativo de atalhos de teclado pode ser chamado de coisas diferentes na GUI, mas na linha de comando deve ser chamado de 'gnome-keybinding-properties'. Acontece que esse pequeno aplicativo limpo reúne todos os atalhos em um local conveniente para os usuários editarem.

Como não existe uma ferramenta de exportação / importação com um clique para combinações de teclas no Ubuntu, escrevi uma em python:

Aqui está um link para o script

Uma exportação extrai as configurações do sistema. Essencialmente, ele contém uma lista de todos os locais de ligação de teclas que são codificados em um dicionário no script. O script enumera a lista e executa o comando "gconftool-2 --get [location]" para cada chave e armazena o valor no dicionário junto com a chave. Quando você especifica o local para salvar as configurações, ele salva o dicionário no arquivo no formato json.

Um script de importação reverte esse processo. Carrega o dicionário do arquivo json. Em seguida, ele enumera essas opções e executa o comando "gconftool-2 --type string --set [location] [value]" para restaurar todas as configurações salvas.

Um disparo em cada extremidade e salva / restaura cada atalho de teclado sem tocar em nenhuma das outras configurações do sistema.

As únicas dependências para esses scripts são:

  • python (testado e funcionando em 2.6, 2.7 e 3.1)
  • gconftool-2 (vem de fábrica com uma instalação do Ubuntu)
  • zenity (vem de fábrica com uma instalação do Ubuntu)

O Python é necessário para executar o script, o gconftool-2 é usado para obter / definir as configurações, o zenity é necessário para os diálogos de carregamento / gravação da GUI do arquivo.

Criei uma entrada no Ubuntu Brainstorm e estou progredindo para que esse recurso seja introduzido no menu da GUI 'gnome-keybinding-properties'.

Atualizar:

Atualizei os scripts de importação e exportação combinados em um, adicionei a funcionalidade completa da linha de comando (incluindo --help info) e o tornei compatível para python2x e python3k. Além disso, adicionou o link à ideia do Ubuntu Brainstorm.

Evan Plaice
fonte
O brainstorm dificilmente é um bom lugar para melhorias reais do Ubuntu - apenas os 10 principais problemas chamam a atenção do desenvolvedor. Sugiro que você encontre a página do Launchpad gnome-keybinding-propertiese publique um patch com seu script.
Oxwivi 11/03/11
Seu script é bom para atalhos listados em / manipulados por gconftool-2 / gconf-editor ... e suponho que depende do que se chama atalho de teclado GNOME ... mas não está pegando atalhos de usuário em todo o sistema adicionados por Keyboard Shortcutsie. gnome-keybinding-properties... nem outras combinações de teclas adicionadas por, por exemplo Xbindkeys... então eu suspeito que o gconf 'não é onde os atalhos de todo o sistema são "armazenados", mas que é uma interface para algo / em algum lugar mais profundo ... (I estive procurando por esse lugar .. :). talvez eu só precisa manter 3 'exportada' listas por agora ...
Peter.O
@ fred.bear Tenho certeza de que todos eles estão armazenados no gconf, mas estou descobrindo que novas combinações de teclas são adicionadas às propriedades do gnome-keybinding-properties quando você muda dos padrões no painel de controle. O script atual fará os atalhos padrão encontrados na GUI, mas não poderá suportar todos os atalhos sem uma integração mais rigorosa na GUI. Atualmente, já existe um plano aberto para isso, então estou tentando entrar em contato com o outro desenvolvedor que propôs isso para descobrir os detalhes na barra de lançamento. Por enquanto ... isso funciona.
Evan Solha
3

Na 11.10, executando o Gnome classic, encontrei um conjunto de diretórios (Custom0, Custom1 ...) em

$HOME/.gconf/desktop/gnome/keybindings

Copiei esses diretórios para a mesma pasta em uma instalação 12.04 limpa (novamente executando com o fallback do Gnome), desconectado e conectado novamente. As combinações de teclas ficaram um pouco confusas na transição (algo engraçado aconteceu com o modificador SUPER), mas, do contrário, elas estavam lá.

EntropyReduction
fonte
2

Há um pequeno problema com a resposta aceita, pois ela não pode manipular comandos personalizados com aspas. Alterei apenas o processamento de comandos personalizados para gerar a saída correta.

#!/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;
        $command =~ s/\"/\\\"/g;
        $command =~ s/^'(.*)'$/$1/g;
        $command =~ s/\'/\'\\\'\'/g;
        $command = "\'$command\'";
        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);
}
Jordan Weitz
fonte
Excelente primeira resposta no AskUbuntu! Parabéns!
Fabby
Integrei suas alterações na resposta aceita.
Stephen Ostermiller