Gerenciamento alternativo de janelas no Linux

Sou um daqueles que configuro o Caps Lock para mudar de layout porque tenho preguiça de pressionar 2 teclas quando posso pressionar uma. Gostaria até de 2 teclas desnecessárias: usaria uma para ativar o layout em inglês e a segunda para o russo. Mas a segunda chave desnecessária é acessar o menu de contexto, que é tão desnecessário que é cortado por muitos fabricantes de laptop. Então você tem que se contentar com o que tem.

E também não quero procurar seus ícones na barra de tarefas ao alternar entre janelas ou capturar os nomes ao rolar Alt + Tab, percorrer as áreas de trabalho, etc. Quero pressionar uma combinação de teclas (de preferência apenas uma, mas não há mais teclas desnecessárias gratuitas) e chegar imediatamente à janela que preciso. Por exemplo assim:

  • Alt+F: Firefox
  • Alt+D: Firefox (navegação privada)
  • Alt+T: Terminal
  • Alt+M: Calculadora
  • Alt + E: ideia do IntelliJ
  • etc.

Além disso, ao pressionar, por exemplo, Alt + M Quero ver a calculadora independentemente de este programa estar em execução. Se estiver em execução, então sua janela precisa receber foco e, caso contrário, execute o programa desejado e transfira o foco quando ele carregar.

Para casos que não são cobertos pelo script anterior, quero ter combinações de teclas universais que possam ser facilmente atribuídas a qualquer uma das janelas abertas. Por exemplo, tenho 10 combinações atribuídas de Alt + 1 para Alt + 0, que não estão vinculados a nenhum programa. Posso apenas clicar Alt + 1 e a janela que está atualmente em foco ficará em foco quando clicada Alt + 1.

Abaixo do corte há uma descrição de mais alguns recursos e uma resposta sobre como isso pode ser feito. Mas vou avisar imediatamente que tal customização “para você” pode causar vício severo e até mesmo abstinência caso você precise usar Windows, Mac OS ou até mesmo o computador de outra pessoa com Linux.

Na verdade, se você pensar bem, não usamos tantos programas diariamente. Um navegador, um terminal, um IDE, algum tipo de mensageiro, um gerenciador de arquivos, uma calculadora e, talvez, isso seja quase tudo. Não são necessárias muitas combinações de teclas para cobrir 95% das tarefas diárias.

Para programas que possuem várias janelas abertas, uma delas pode ser designada como principal. Por exemplo, você tem várias janelas do IntelliJ Idea abertas e atribuídas a Alt + E. Em condições normais, quando você pressiona Alt + E alguma janela deste programa será aberta, provavelmente aquela que foi aberta primeiro. No entanto, se você clicar em Alt + E quando uma das janelas deste programa já estiver em foco, então esta janela específica será atribuída como a principal e será aquela que receberá o foco quando as combinações subsequentes forem pressionadas.

A janela principal pode ser reatribuída. Para fazer isso, você deve primeiro redefinir a combinação e, em seguida, atribuir outra janela a ela como janela principal. Para redefinir uma combinação, você precisa pressionar a própria combinação e, em seguida, uma combinação de redefinição especial, eu a atribuí a Alt + Backspace. Isso chamará um script que cancelará a atribuição da janela principal da combinação anterior. E então você pode atribuir uma nova janela principal conforme descrito no parágrafo anterior. A redefinição de uma janela vinculada para combinações universais ocorre da mesma maneira.

A introdução acabou sendo longa, mas eu queria primeiro contar o que faremos e depois explicar como fazer.

Para quem está cansado de ler

Resumindo, o link para os scripts está no final do artigo.

Mas você ainda não conseguirá instalá-lo e usá-lo imediatamente. Primeiro você terá que descobrir como o script encontra a janela desejada. Sem isso, não será possível dizer ao script para onde exatamente o foco precisa ser transferido. E você precisa entender o que fazer se de repente uma janela adequada não for encontrada.

E não vou me concentrar em como configurar a execução de scripts pressionando combinações de teclas. Por exemplo, no KDE está em Configurações do sistema → Atalhos → Atalhos personalizados. Este também deve ser o caso em outros gerenciadores de janelas.

Apresentando wmctrl

Wmctrl — utilitário de console para interagir com o X Window Manager. Este é o programa chave para o script. Vamos dar uma olhada rápida em como você pode usá-lo.

Primeiro, vamos exibir uma lista de janelas abertas:

$ wmctrl -lx
0x01e0000e -1 plasmashell.plasmashell             N/A Desktop — Plasma
0x01e0001e -1 plasmashell.plasmashell             N/A Plasma
0x03a00001  0 skype.Skype                         N/A Skype
0x04400003  0 Navigator.Firefox                   N/A Google Переводчик - Mozilla Firefox
0x04400218  0 Navigator.Firefox                   N/A Лучшие публикации за сутки / Хабр - Mozilla Firefox (Private Browsing)
...

Opção -l exibe uma lista de todas as janelas abertas e -x anexa o nome da classe à saída (skype.Skype, Navegador.Firefox etc). Aqui precisamos do id da janela (coluna 1), nome da classe (coluna 3) e nome da janela (última coluna).

Você pode tentar ativar alguma janela usando a opção -a:

$ wmctrl -a skype.Skype -x

Se tudo correr conforme o planejado, a janela do Skype deverá aparecer na tela. Se em vez da opção -x opção de uso -i, então, em vez do nome da classe, você pode especificar o ID da janela. O problema com o id é que o id da janela muda toda vez que o aplicativo é iniciado e não podemos saber disso com antecedência. Por outro lado, este atributo identifica exclusivamente uma janela, o que pode ser importante quando uma aplicação abre mais de uma janela. Mais sobre isso um pouco mais adiante.

Nesta fase precisamos lembrar que iremos procurar a janela desejada usando regex por saída wmctrl -lx. Mas isso não significa que tenhamos que usar algo complicado. Normalmente, o nome da classe ou da janela é suficiente.

Basicamente, a ideia principal já deve estar clara. Nas configurações globais de teclas de atalho/atalhos do seu gerenciador de janelas, configure a combinação necessária para executar o script.

Como usar scripts

Primeiro você precisa instalar utilitários de console wmctrl и xdotool:

$ sudo apt-get install wmctrl xdotool

Em seguida, você precisa baixar os scripts e adicioná-los ao $ PATH. Eu costumo colocá-los ~ / bin:

$ cd ~/bin
$ git clone https://github.com/masyamandev/Showwin-script.git
$ ln -s ./Showwin-script/showwin showwin
$ ln -s ./Showwin-script/showwinDetach showwinDetach

Se o diretório ~ / bin não estava lá, então você precisa criá-lo e reinicializar (ou fazer login novamente), caso contrário ~ / bin não vai bater $ PATH. Se tudo for feito corretamente, os scripts deverão estar acessíveis no console e o preenchimento da guia deverá funcionar.

Roteiro principal showwin leva 2 parâmetros: o primeiro é um regex, pelo qual procuraremos a janela desejada, e o segundo parâmetro é um comando que precisa ser executado caso a janela desejada não seja encontrada.

Você pode tentar executar um script, por exemplo:

$ showwin "Mozilla Firefox$" firefox

Se o Firefox estiver instalado, sua janela deverá receber foco. Mesmo que o Firefox não estivesse em execução, ele deveria ter iniciado.

Se funcionar, você pode tentar configurar a execução de comandos em combinações. Nas configurações globais de teclas de atalho/atalhos, adicione:

  • Alt+F: mostrar “Mozilla Firefox$” firefox
  • Alt+D: showwin "Mozilla Firefox (navegação privada)$" "firefox -janela privada"
  • Alt + C: showwin "navegador cromo. Navegador cromo N *" navegador cromo
  • Alt + X: showwin "navegador cromo. Navegador cromo I *" "navegador cromo -incógnito"
  • Alt + S: mostrar “skype.Skype” skypeforlinux
  • Alt + E: showwin “jetbrains-idea” idea.sh

Etc. Todos podem configurar combinações de teclas e software como acharem adequado.
Se tudo deu certo, então usando as combinações acima poderemos alternar entre as janelas simplesmente pressionando as teclas.

Vou decepcionar os amantes do Chrome: ele pode distinguir incógnito uma janela normal por sua saída wmctrl Você não pode, eles têm os mesmos nomes de classes e títulos de janelas. Na regex proposta, os caracteres N* e I* são necessários apenas para que essas expressões regulares sejam diferentes umas das outras e possam ser atribuídas como janelas principais.

Para redefinir a janela principal da combinação anterior (na verdade para regex, que showwin chamado da última vez) você precisa chamar o script showwinDetach. Eu tenho este script atribuído a uma combinação de teclas Alt + Backspace.

No roteiro showwin existe mais uma função. Quando é chamado com um parâmetro (neste caso o parâmetro é apenas um identificador), ele não verifica a regex, mas considera todas as janelas adequadas. Por si só, isso parece inútil, mas desta forma podemos designar qualquer janela como principal e mudar rapidamente para essa janela específica.

Tenho as seguintes combinações configuradas:

  • Alt+1: showwin "CustomKey1"
  • Alt+2: showwin "CustomKey2"
  • ...
  • Alt+0: showwin "CustomKey0"
  • Alt+Backspace: showwinDetach

Desta forma posso vincular qualquer janela a combinações Alt + 1...Alt + 0. Basta clicar Alt + 1 Vinculo a janela atual a esta combinação. Posso cancelar a vinculação clicando em Alt + 1e depois Alt + Backspace. Ou feche a janela, isso também funciona.

A seguir contarei alguns detalhes técnicos. Você não precisa lê-los, apenas tente configurá-los e ver. Mas eu ainda recomendaria entender os scripts de outras pessoas antes de executá-los no seu computador :).

Como distinguir entre diferentes janelas do mesmo aplicativo

Em princípio, o primeiro exemplo “wmctrl -a skype.Skype -x” estava funcionando e pode ser usado. Mas vejamos novamente o exemplo do Firefox, no qual 2 janelas estão abertas:

0x04400003  0 Navigator.Firefox                   N/A Google Переводчик - Mozilla Firefox
0x04400218  0 Navigator.Firefox                   N/A Лучшие публикации за сутки / Хабр - Mozilla Firefox (Private Browsing)

A primeira janela é o modo normal e a segunda é a Navegação Privada. Gostaria de considerar essas janelas como aplicativos diferentes e alternar para elas usando diferentes combinações de teclas.

É preciso complicar o script que alterna janelas. Eu usei esta solução: exiba uma lista de todas as janelas, faça grep por regex, pegue a primeira linha com cabeça, obtenha a primeira coluna (este será o ID da janela) usando corte, mude para janela por id.

Deveria haver uma piada sobre expressões regulares e dois problemas, mas na verdade não estou usando nada complicado. Preciso de expressões regulares para poder indicar o final da linha (o símbolo “$”) e distinguir “Mozilla Firefox$” de “Mozilla Firefox (navegação privada)$”.

O comando é mais ou menos assim:

$ wmctrl -i -a `wmctrl -lx | grep -i "Mozilla Firefox$" | head -1 | cut -d" " -f1`

Aqui você já pode adivinhar a segunda característica do script: se grep não retornar nada, então o aplicativo desejado não está aberto e você precisa iniciá-lo executando o comando do segundo parâmetro. E então verifique periodicamente se a janela necessária foi aberta para transferir o foco para ela. Não vou me concentrar nisso; quem precisar vai olhar as fontes.

Quando as janelas do aplicativo não são distinguíveis

Assim, aprendemos como transferir o foco para a janela do aplicativo desejado. Mas e se um aplicativo tiver mais de uma janela aberta? Em qual devo dar foco? O script acima provavelmente será transferido para a primeira janela aberta. No entanto, gostaríamos de mais flexibilidade. Gostaria de poder lembrar de qual janela precisamos e mudar para essa janela específica.

A ideia era esta: se quisermos lembrar uma janela específica para uma combinação de teclas, precisamos pressionar essa combinação quando a janela desejada estiver em foco. Futuramente, ao pressionar esta combinação, o foco será dado a esta janela. Até que a janela feche ou façamos um reset para esta combinação de scripts showwinDetach.

Algoritmo de script showwin algo assim:

  • Verifique se lembramos previamente do id da janela para a qual o foco deve ser transferido.
    Se você se lembra e essa janela ainda existe, transferimos o foco para ela e saímos.
  • Observamos qual janela está em foco no momento e, se ela corresponder à nossa solicitação, lembramos de seu ID para acessá-la no futuro e sair.
  • Vamos para pelo menos alguma janela adequada, se existir, ou abrimos o aplicativo desejado.

Você pode descobrir qual janela está em foco no momento usando o utilitário de console xdotool convertendo sua saída para o formato hexadecimal:

$ printf "0x%08x" `xdotool getwindowfocus`

A maneira mais fácil de lembrar algo no bash é criar arquivos em um sistema de arquivos virtual localizado na memória. No Ubuntu, isso está habilitado por padrão em /dev/shm/. Não posso falar nada sobre outras distribuições, espero que haja algo semelhante também. Você pode olhar com o comando:

$ mount -l | grep tmpfs

O script criará diretórios vazios nesta pasta, assim: /dev/shm/$USER/showwin/$SEARCH_REGEX/$WINDOW_ID. Além disso, cada vez que for chamado, criará um link simbólico /dev/shm/$USER/showwin/showwin_last em /dev/shm/$USER/showwin/$SEARCH_REGEX. Isso será necessário para, se necessário, remover o ID da janela de uma determinada combinação usando um script showwinDetach.

O que pode ser melhorado

Primeiramente, os scripts devem ser configurados manualmente. Certamente, pela necessidade de se aprofundar e fazer muito com as mãos, muitos de vocês nem tentarão configurar o sistema. Se fosse possível simplesmente instalar o pacote e configurar tudo com mais facilidade, talvez ele ganhasse alguma popularidade. E então veja, o aplicativo seria lançado em distribuições padrão.

E talvez isso possa ser feito mais facilmente. Se pelo id de uma janela você descobrir o id do processo que a criou, e pelo id do processo você descobrir qual comando a criou, então seria possível automatizar a configuração. Na verdade, não entendi se o que escrevi neste parágrafo era possível. O facto é que pessoalmente estou satisfeito com a forma como funciona agora. Mas se alguém além de mim achar toda a abordagem conveniente e alguém a melhorar, ficarei feliz em usar uma solução melhor.

Outro problema, como já escrevi, é que em alguns casos as janelas não podem ser distinguidas umas das outras. Até agora, só observei isso com navegação anônima em chrome/chromium, mas talvez haja algo semelhante em outro lugar. Como último recurso, existe sempre a opção de combinações universais Alt + 1...Alt + 0. Novamente, eu uso o Firefox e para mim pessoalmente esse problema não é significativo.

Mas o problema significativo para mim é que uso o Mac OS para trabalhar e não consegui configurar nada parecido lá. Utilitário wmctrl Acho que consegui instalá-lo, mas realmente não funciona no Mac OS. Algo pode ser feito com o aplicativo Automator, mas é tão lento que não é conveniente usá-lo mesmo quando está funcionando. Também não consegui configurar combinações de teclas para que funcionassem em todos os programas. Se alguém de repente encontrar uma solução, ficarei feliz em usá-la.

Em vez de uma conclusão

Acabou sendo um número inesperadamente grande de palavras para uma funcionalidade aparentemente tão simples. Queria transmitir a ideia e não sobrecarregar o texto, mas ainda não descobri como contá-la de forma mais simples. Talvez fosse melhor em formato de vídeo, mas as pessoas não gostam assim aqui.

Falei um pouco sobre o que está por trás do script e como configurá-lo. Não entrei em detalhes do roteiro em si, mas ele tem apenas 50 linhas, então não é difícil de entender.

Espero que outra pessoa experimente esta ideia e talvez até a aprecie. Posso dizer sobre mim que o roteiro foi escrito há cerca de 3 anos e é MUITO conveniente para mim. Tão conveniente que causa grande desconforto ao trabalhar com computadores de outras pessoas. E com um MacBook funcional.

Link para scripts

Fonte: habr.com

Adicionar um comentário