Usando scratchpads no i3wm/sway

Sempre achei os scratchpads meio esquecidos pela galera. confesso, não sei o motivo. são úteis e podem ser utilizados em vários cenários diferentes. além do i3wm/sway outros twm também trazem opções muito parecidas com os scratchpads, se seu twm tem, dê uma chance a ele. as dicas desse post serão apenas para o i3wm (x11) e sway (wayland).

Ao longo do texto ensinarei três formas de se trabalhar com eles: 1) o uso mais básico, fazendo um toggle da janela; 2) definindo configurações específicas para determinados programas e 3) scratchpads “dinâmicos” usando o i3/sway marks.

O que são scratchpads?

Falando de forma resumida e meio tosca, é uma área de trabalho invisível. Porque invisível? Simples, não é possível acessa-lá como se faz com as área de trabalho comuns do seu twm. Não existe um atalho que abra o scrachtpad, você acessa (exibi ou esconde) uma janela que já estava lá ou que foi mandada para lá.

Eu gosto da definição que existe no arquivo padrão de config do sway (/etc/sway/config):

Sway has a “scratchpad”, which is a bag of holding for windows.
You can send windows there and get them back later.

Lembre-se, mandar uma janela para o scratchpad não é minimizar. O conceito de minizar não existe nos tiling window manager, é uma forma de gerenciar janelas que é propia dos stacking ou similares.

Os atalhos que usarei no texto foram os de minha preferência. Para ver os atalhos padrão, confira os exemplos de arquivo de configuração do i3wm (/etc/i3/config) e do sway (/etc/sway/config) ou na documentação online.

Exemplos de uso

Agora vamos a alguns exemplos práticos. Nas próximas sessões tentarei explicar mais calmamente como chegar a esses resultados.

A forma mais básica de se utilizar um scratchpad é apenas enviando/“levantando” uma janela de lá. Para isso existem as opções: move scrathcpad e show scratchpad.

Exemplo básico:

# move para o scratchpad
bindsym $mod+Shift+y move scratchpad
# exibi a janela do scrachpad
bindsym $mod+y scratchpad show

Por padrão o atalho scrachpad show “levanta” a primeira janela que foi enviada para lá. Se só existir uma janela isso não será um problema. Se existirem várias, a primeira será exibida e, cada vez que o atalho é usado sucessivamente, é exibida a próxima janela. Sempre que você fecha ou retorna uma janela, a contagem reinicia.

Exemplo mais completo:

# Nesse exemplo inicio o psensor no scratchpad e defino um atalho exclusivo para ele
exec --no-startup-id psensor
for_window [app_id="psensor"] move scratchpad
bindsym $mod+Shift+y move scratchpad
bindsym $mod+y scratchpad show
bindsym $mod+i [app_id="psensor"] scratchpad show; resize set 1000 590; move position center

Exemplo usando o i3/sway marks ou o que chamei de scratchpads dinâmicos:

bindsym $mod+Shift+j mark "scratch1", move scratchpad
bindsym $mod+h [con_mark="scratch1"] scratchpad show
show_marks yes
Iniciando um programa direto no scratchpad

Fazer isso é bem simples. Para que um programa ou script inicie junto com a sessão do seu i3/sway, use a opção exec + nome_do_programa:

exec --no-startup-id psensor
ou
exec --no-startup-id alacritty

Se por algum motivo o programa não iniciar só com o nome, utilize o caminho completo. Para achar o caminho completo do binário você pode recorrer ao comando type, apenas digite type + nome do programa no terminal.

É aconselhável após o exec utilizar a opção –no-startup-id para evitar aquele cursor chato de carregamento. Isso normalmente acontece porque o i3/sway fica esperando concluir o processo de inicialização do ID do programa.

Se você for uma pessoa distraída, pode usar o exec_always. A diferença entre o exec e o exec_always é que o segundo executa toda vez que o i3/sway é recarregado. Já o exec, só executa na primeira vez que a sessão do i3/sway é iniciada. Para que ele funcione novamente, só reiniciando a sessão (deslogando e (re)logando). Dessa forma, se fechar o programa sem querer, basta um $mod+shift+r e ele abrirá no scratchpad novamente.

Agora que o programa já inicia automaticamente, vamos mandá-lo para o scrachpad:

# i3wm
for_window [class="psensor"] move scratchpad
# sway
for_window [app_id="psensor"] move scratchpad

É necessário saber a classe (i3wm) ou o app_id (sway) de um programa para que isso seja possível:

xprop | grep CLASS # para o xorg
e
waymsg -t get_tree | grep app_did # para wayland

Lembre-se que, em caso de estar usand o wayland (sway) podem ocorrer alguns problemas com o app_id. Programas que não tem suporte nativo ao wayland recorrem ao xwaylad para compatibilidade. Pode acontecer de ao tentar pegar o app_id de um programa o swaymsg retornar como null. Nesse caso, use a opção class ao invês de app_id. Se não souber classe, abra o programa que você quer e entre em modo tabeado, na grande maioria das vezes o nome que aparece na aba de títulos funciona.

Scrachpads personalizados
# Inicia o foot com a vimwiki junto da sessão do sway
exec --no-startup-id foot -a vwiki nvim ~/vimwiki/Index.md
# Abre o terminal com a vimwiki direto no scratchpad
for_window [app_id="vwiki"] move scratchpad
# Move a janela em foco para o scratchpad
bindsym $mod+Shift+y move scratchpad
# "Levanta" a primeira janela dentro do scratchpad
bindsym $mod+y scratchpad show
# "Levanta" diretamente a janela da vimwiki
bindsym $mod+i [app_id="vwiki"] scratchpad show; resize set 1000 590; move position center

Na última linha ainda adicionei duas configurações adicionais. O comando resize e o move. O primeiro serve para redefinir o tamanho da janela para as dimensões escolhidas (height x width) e o segundo centraliza a janela na tela. Alguns programas, e eu não sei o motivo, podem ficar, eventualmente, ligeiramente tortos em relação ao centro da tela. Eu corrijo isso com o comando move position center.

Se quiser abrir múltiplos programas, use da seguinte forma:

for_window [app_id="^psensor|KeePassXC|alacritty$"] move scratchpad    # Xorg (i3wm)
ou
for_window [class="^psensor|KeePassXC|alacritty$"] move scratchpad     # Wayland (Sway)

Separe os programas com um pipe e, obviamente, substitua pelos que você desejar. Repare que entre as duas aspas tem um acento circunflexo e um dólar, se for usar mais de um programa, é obrigatório seguir essa sintaxe, caso contrário não funcionará.

Scrachpads dinâmicos

Uma terceira forma de usar os scratchpads, é em conjunto com a opção marks. Alias, outro recurso meio esquecido do i3/sway. Nesse caso é compreensível, afinal é um recurso que não tem tantas possibilidades de uso. Usando os dois em conjunto, temos um uso mais dinâmico e não tão atrelado a programas e configs específicas.

Não entrarei em detalhes sobre os marks, que são simples por sinal. Se achou interessante, confira esse link. Quem usa o vim vai perceber que o funcionamento é o mesmo do vim marks.

Vamos a um exemplo:

bindsym $mod+shift+h mark “scratch1”, move scratchpad
bindsym $mod+shift+j mark “scratch2”, move scratchpad

bindsym $mod+h [con_mark=“scratch1”] scratchpad show
bindsym $mod+j [con_mark=“scratch2”] scratchpad show
show_marks yes

Nesse exemplo, usei apenas duas opções, você pode utilizar quantas forem necessárias. O que os comandos acima fazem é marcar uma janela e depois manda-la para o scratchpad. Assim você pode chamar essa mesma janela marcada de volta do scratchpad sem nenhuma configuração adicional e você precisará apenas de dois atalhos. Por isso chamei de scratchpads dinâmicos.

O show_marks é uma configuração opcional. Pode user usada como yes/no. Quando ativada (yes) essa opção deixa visível na barra de títulos se a janela está marcada e o nome da marca. Repare no exemplo que temos "scratch1" e scratch2, você pode pelo termo/palavra de sua preferência.

Definido título e classes

Se reparou nos exemplos acima, eu não citei nenhum programa CLI. Isso porque eles rodam como um processo dentro do seu emulador de terminal. E nem sempre eles vão alterar o título do terminal. Para evitar isso, se necessário, você pode definir manualmente o título ou a classe.

Para lançar o alacritty ou o foot rodando a vimwiki usamos:

alacritty -T vwiki -e nvim ~/vimwiki/Index.md
ou
foot -T vwiki nvim ~/vimwiki/Index.md

Dessa forma a janela será identificada com o título de vwiki e não nvim. O mesmo pode ser feito com a classe.:

alacritty --class vwiki -e nvim ~/vimwiki/Index.md
ou
foot -a vwiki nvim ~/vimwiki/Index.md

Isso faz com que apenas a janela contendo esse título ou classe, se comporte da forma que queremos. Evitando conflito com outros programas. Assim estamos livres para configurar um scratchpad com uma classe ou título específico.

No exemplo abaixo inicio a vim wiki dentro do scratchpad com uma classe específica para a sua janela. Com o atalho $mod+i eu trabalho apenas com a janela que contém a vim wiki.

exec --no-startup-id alacritty --class vwiki -e nvim ~/vimwiki/index.md
for_window [app_id="vwiki"] move scratchpad
bindsym $mod+i [app_id="vwiki"] scratchpad show; resize set 1000 590; move position center

Conclusão

É isso. Pode parecer trabalhoso, mas, de modo geral, rapidinho a gente configura os scratchpads para nosso uso. Eu particularmente gosto de deixar o psensor e minha página inicial da vimwiki no scratchpad e, quando preciso, mando alguma janela para lá.

Se faltou alguma coisa ou encontrou um erro no texto, avisa aí! Qualquer sugestão será bem-vinda.

Edit: esqueci de avisar uma coisa no texto. Por padrão, o i3/sway só permite janelas flutuantes (floating) no scratchpad. Então, para que a janela fique com um tamanho diferente, você terá que alterar manualmente. Ou você usa o comando resize set que tem nos exemplos acima, ou defini os tamanhos das janelas flutuantes de forma global (para todas as janelas flutuantes), com as opções:

floating_minimum_size 350 x 750
floating_maximum_size 1300 x 69

Apenas troque pelas dimensões de sua preferência.

5 curtidas