NOTA : nesta resposta existem duas soluções, cada uma com seus próprios benefícios. Os usuários são encorajados a descobrir qual deles funciona melhor para seu caso específico.
Introdução
O Nautilus por si só não oferece uma maneira de definir atalhos de teclado personalizados e suas ações. Esta é a principal razão pela qual os scripts que você tentou falharam. $NAUTILUS_SCRIPT_SELECTED_FILE_PATHS
só pode ser usado via submenu de clique direito. Mas podemos explorar outra coisa para alcançar o resultado desejado - atalhos definidos nas configurações e na área de transferência do sistema.
O Nautilus é construído em algo conhecido como kit de ferramentas Gtk. É uma extensa biblioteca para criação de aplicativos gráficos e, entre outras coisas, possui utilitários para fazer interface com a área de transferência do sistema. O Nautilus, sendo um gerenciador de arquivos, é especial no fato de gerar uma lista de URIs (na forma file:///home/user/Pictures/encoded%image%name.png
) para a área de transferência (o que não é um fato bem conhecido para a maioria dos usuários, e eu aprendi bem recentemente . Aparentemente, é assim que os gerenciadores de arquivos da GUI copiam arquivos.
Podemos explorar esse fato copiando o URI do arquivo (ou, para ser exato, a lista de URIs; mesmo se houver apenas um, o padrão é uma lista). Então podemos passar essa lista para gimp
. As duas soluções apresentadas abaixo operam exatamente nessa ideia.
Raciocínio para 2 soluções:
Eu pessoalmente considero a solução # 1 como a preferida. Ele depende de pressionar primeiro o atalho de cópia e, em seguida, o atalho do script - que são dois atalhos de teclado -, mas tem vantagem em ter menos dependências. É uma abordagem mais manual, mas bastante decente. Ele usa os.execlp
call, que substituirá o processo do script pelo Gimp, agindo como meramente um trampolim para Gimp
. É uma prática frequente em scripts e programação de sistema usar exec
family of functions
A segunda solução foi escrita porque Jacob Vlijm mencionou nos comentários que para ele a função execlp
não funcionava, por qualquer motivo. Acho isso muito estranho porque o execlp
pertence ao módulo padrão os
para python, que é um dos módulos instalados padrão. Além disso, subprocess.Popen()
padroniza para exec()
família de funções; da documentação de subprocess
:
On POSIX, with shell=False (default): In this case, the Popen class uses os.execvp() to execute the child program. args should normally be a sequence. A string will be treated as a sequence with the string as the only item (the program to execute).
(Nota "No POSIX" significa "SO compatível com POSIX"; o Ubuntu é compatível com POSIX)
Assim, não parece um problema com uma função em si, mas com o sistema do usuário. No entanto, eu escrevi segundo roteiro. Esse usa o módulo subprocess
e depende de xdotool
, que basicamente automatiza pressionando o atalho Ctrl + C para você e, em seguida, inicia o Gimp. Eu pessoalmente não gosto muito deste, já que ele requer um item adicional para ser instalado, mas tem a vantagem de precisar apenas de um atalho de teclado.
A ideia, no entanto, é a mesma. Ainda usamos ferramentas Gtk para consultar o conteúdo da área de transferência e, em cada caso, os scripts devem estar vinculados a um atalho.
Solução # 1, dois atalhos, dependências mínimas
Uso: selecione o arquivo e pressione Ctrl + C para copiar primeiro o arquivo, depois pressione o atalho que você atribuiu a este script. A função execlp
substituirá o processo do script por gimp
.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from gi.repository import Gtk, Gdk
from os import execlp
from time import sleep
from urllib.parse import unquote
import signal
import threading
import subprocess
uris = None
def autoquit():
global uris
#sleep(0.5)
while not uris:
# allow sufficient time to obtain uris
sleep(2)
pass
Gtk.main_quit()
def get_clipboard_contents():
global uris
clip = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
tr = threading.Thread(target=autoquit)
tr.daemon = True
tr.start()
uris = clip.wait_for_uris()
Gtk.main()
return [unquote(i).replace('file://','')
for i in uris]
def main():
signal.signal(signal.SIGINT,signal.SIG_DFL)
files = get_clipboard_contents()
print(files)
args = ['gimp'] + files
execlp('gimp',*args)
if __name__ == '__main__': main()
Solução # 2: atalho único, dependência xdotool
O uso deste script é mais simples: selecione o (s) arquivo (s) no Nautilus e pressione o atalho de teclado. OBSERVAÇÃO : você deve ter xdotool
instalado para que isso funcione, use sudo apt-get install xdotool
.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from gi.repository import Gtk, Gdk
from subprocess import Popen,STDOUT
from time import sleep
from urllib.parse import unquote
import sys
def unquote_uri(*args):
uris = args[-2]
unquoted_args = [ str(unquote(i).replace('file://',''))
for i in uris]
with open('/dev/null','w') as dev_null:
proc = Popen(['gimp',*unquoted_args],stdout=dev_null,stderr=STDOUT)
Gtk.main_quit()
def main():
# NOTE: xdotool is REQUIRED for this to work
Popen(['xdotool','key','Ctrl+c'])
sleep(0.5)
clip = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
clip.request_uris(unquote_uri, None)
Gtk.main()
if __name__ == '__main__': main()
Configurando o atalho
Em ambos os casos, você precisa ter um script vinculado a um atalho. Abrir configurações do sistema - > Teclado - > Atalhos - > Personalizadas. Clique no botão + . Dê caminho completo (!) Para arquivar como comando. Por exemplo, /home/User_Name/bin/clipboard_launch.py
Atribua o atalho para ser algo sensato. Por exemplo, como estamos chamando o Gimp, eu atribuí meu script a Ctrl + Super + G .