Os menus do meu sistema

Traduções: en
28/12/2021

Outro artigo falando sobre algo que eu configurei no meu ambiente de trabalho alguns anos atrás e que continuo usando até hoje 🙂. Dessa vez eu vou mostrar os menus que eu criei usando o rofi.

Então, o que é o rofi? É basicamente um programa para o qual você fornece uma lista de opções, e ele mostra uma janela onde o usuário pode filtrar e escolher uma opção. Então basicamente pode-se dizer que é um menu de seleção simples mas universal.

O rofi também tem alguns menus padrões, como um para abrir aplicações e outro para alternar entre janelas, que provavelmente são o seu uso mais comum. Eu também uso esses menus, mas como eles não são algo que eu mesmo customizei, eu não vou falar sobre eles.

Meus menus

Os menus que eu criei usando o rofi são: power, screenshot, unicode e music.

Power

{image}/power.png

Esse é provavelmente o menu mais importante de se ter quando seu ambiente de trabalho não oferece o próprio menu (por exemplo, no meu caso eu uso sway que é apenas um gerenciador de janelas e não tem nenhum menu próprio). Esse menu fica mapeado em Super+Shift+P.

As opções são auto-explicativas. Elas são ordenadas de menos "danosa" no topo até mais "danosa" em baixo, para que eu não desligue e perca meu trabalho acidentalmente quando eu apenas quero bloquear a tela, por exemplo, já que não tem nenhum pop-up de confirmação.

Já que lock é a primeira opção, simplesmente abrir o menu e apertar Enter já bloqueia a tela. A outra opção que eu mais uso é hibernate, que apenas requer pressionar h para ser selecionada, seguido de Enter para hibernar. Nos casos raros que eu realmente preciso desligar eu uso w, e para reiniciar, eu uso re. Claro que eu sempre posso circular pelas opções usando Ctrl+N e Ctrl+P também, mas as letras geralmente são mais rápidas.

O motivo de ter muito espaço entre cada ícone e o texto é que cada ícone tem uma largura diferente, então para que o texto de todas as entradas fique alinhado, eu precisei colocar um caractere de tab depois de cada ícone. O mesmo é feito nos outros menus.

Screenshot

{image}/screenshot.png

O menu screenshot fica mapeado em Super+Shift+S.

A opção screen tira uma foto da tela inteira (incluindo monitores externos). Ela chama o grim por baixo dos panos para tirar as fotos.

region disponibiliza um cursor que me permite selecionar a região retangular que será capturada na foto. Isso é feito chamando o slurp, que obtém a seleção do usuário, e fornece as coordenadas resultantes para o grim através do seu parâmetro -g.

window também disponibiliza um cursor, mas ele é usado para selecionar uma única janela que será capturada. Isso é feito extraindo as dimensões das janelas do sway e as passando como opções para o slurp que então permite que apenas um desses retângulos seja selecionado. O comando que faz isso, disponível no README do slurp, é:

swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | .rect | \"\(.x),\(.y) \(.width)x\(.height)\"' | slurp

colorpicker disponibiliza um cursor também, mas não tira nenhuma foto, o que ele faz é copiar o valor RGB do pixel que for clicado para o clipboard.

Unicode

{image}/unicode.png

O menu unicode fica mapeado em Super+Shift+U.

O propósito desse menu é facilitar o acesso a caracteres que eu normalmente não tenho mapeado no meu teclado. Ele mostra cada caractere e seu nome. Já que há muitos caracteres, eu uso duas colunas no rofi para conseguir ver mais ao mesmo tempo.

Para usar esse menu eu escrevo o nome do caractere que eu quero e, com ele selecionado, pressiono Enter para copiá-lo para o clipboard. Então eu posso colá-lo onde eu estava precisando.

Um exemplo de uso é para pegar os caracteres ordinais usados em português: ª e º (chamados Indicador Ordinal Feminino e Masculino, respectivamente). Esses caracteres estão mapeados no layout português do teclado, mas para mim é mais fácil encontrar buscando no menu do que achar no teclado.

Esse menu é gerado em python usando a função unicodedata.name() para obter o nome Unicode para cada caractere e chr() para obter o caractere em si. wl-copy é usado para copiar o caractere para o clipboard.

Music

{image}/music.png

O menu de música fica mapeado em Super+Shift+M e é o meu favorito! Cada opção abre seu próprio sub-menu. Ele tem tudo que eu preciso para sempre poder rapidamente tocar a música que eu quero.

Um detalhe legal é que se uma música já está tocando, o que você escolher vai tocar apenas depois que a música atual terminar. Caso contrário, se nenhuma música está tocando, a escolha é tocada imediatamente. Desse jeito, a música atual nunca é parada no meio, o que é ótimo.

Além disso, diferentemente dos outros menus, os sub-menus de música permitem (quando fizer sentido) que múltiplas opções sejam selecionadas usando Shift+Enter ao invés de Enter, apesar de eu raramente usar isso.

Vamos ver cada um dos sub-menus.

Playlist

{image}/music-playlist.png

O menu playlist me permite tocar qualquer uma das minhas listas de reprodução. A randomização é ligada automaticamente quando eu seleciono uma lista de reprodução, para que a ordem das músicas na lista não seja sempre a mesma.

A lista de reprodução que eu mais ouço, Saved, é a primeira propositalmente. Assim, quando eu simplesmente quero escutar qualquer coisa, basta apertar Super+Shift+M, Enter, Enter. Escutar música de fundo quando eu preciso me concentrar também é bem fácil: Super+Shift+M, Enter, Ctrl+N, Enter.

Caso você esteja curioso sobre como as listas de reprodução são criadas, eu já escrevi sobre no artigo "Geração de listas de reprodução de música com o MPD".

Song

{image}/music-song.png

O menu song é para quando eu quero ouvir alguma música específica. Cada entrada mostra o nome da música, artista e álbum. O rofi não suporta mostrar múltiplas strings na mesma entrada desse jeito por padrão, então para conseguir isso eu preciso construir uma string com a mesma largura da janela do rofi, com cada campo ocupando uma parcela igual.

Para ter uma largura mais ou menos previsível eu fixo a largura do rofi em termos de caracteres colocando width: -100; no seu config. Então eu disponibilizo esse valor dentro do script python simplesmente lendo o valor desse arquivo de config (nada elegante, mas funciona). Por fim eu calculo a largura de cada campo, e adiciono espaçamento e/ou trunco cada um dos campos individualmente para mantê-los na largura desejada.

Já que a fonte que eu uso no rofi não é monoespaçada, a largura que eu configuro no config é apenas um estimativa e não é precisa de forma alguma. Então pode ter um pouco de folga, mas funciona bem o suficiente.

Queue

{image}/music-queue.png

O menu queue mostra a fila de músicas atual que está tocando. Eu uso ele quando quero ver as próximas músicas que vão tocar ou tocar uma outra música da fila atual.

Quando esse menu é aberto o cursor começa já selecionando a música que está tocando no momento.

Album

{image}/music-album.png

O menu album me permite tocar um álbum inteiro. Uma diferença importante dos outros menus é que tocar um álbum desliga a randomização, para que as músicas do álbum sejam tocadas na ordem correta.

Cada entrada mostra o nome do álbum e do artista. Na frente também tem um % para marcar o que eu chamo de "álbum completo". O critério é que quando eu gosto de pelo menos 80% das músicas de um álbum, eu marco ele com um %, e passo a escutá-lo por completo, mesmo as músicas que eu não gostei tanto. Por outro lado, se eu gosto de menos de 80% das músicas no álbum, eu só ouço as músicas que eu gostei.

A ideia por trás desse conceito de "álbum completo" é que eu acho que existe um certo valor em escutar um álbum por completo, mas ao mesmo tempo não acho que faz sentido ouvir um álbum completo quando você não gosta de muitas das músicas. Então eu inventei essa folga de 20% para que os álbuns não precisem ser perfeitos para que eu esteja disposto a escutá-los por completo.

Artist

{image}/music-artist.png

O menu artist é o que eu uso para tocar todas as músicas e álbuns de um único artista, em uma ordem qualquer.

Current

{image}/music-current.png

O menu current é uma adição bem nova! Eu percebi que às vezes estou ouvindo uma lista de reprodução e uma música toca que me faz querer ouvir o álbum dela inteiro ou todas as músicas desse artista. Esse menu me permite fazer exatamente isso.

Options

{image}/music-options.png

O menu options dá acesso a mais algumas funcionalidades extras. update faz o MPD atualizar seu banco de dados de música, o que às vezes é útil se acabei de editar um arquivo. random liga ou desliga a randomização de músicas. Eu raramente uso isso já que meus menus já são configurados para ligar ou desligar a randomização com base no contexto. update playlists roda meu script de geração de listas de reprodução para que elas sejam atualizadas.

Outras considerações

Esses são meus menus e o que eu queria compartilhar nesse artigo, mas vale mencionar alguns outros pontos.

Primeiro, tem um outro menu rofi que eu uso e gosto, mas ele não é um que eu mesmo criei. Ele se chama rofimoji e permite que você muito facilmente pesquise e copie emojis.

Em segundo lugar, vale mencionar que o rofi oficialmente só funciona no X11, então eu na verdade uso o fork do rofi para wayland, como eu mencionei no artigo "Mudando para o Wayland".

E finalmente, para tornar a criação de menus rofi mais fácil nos meus scripts em python, eu abstraí a execução do rofi em uma função python com o seguinte protótipo:

def select(prompt, options, multi=False, args=[]):

onde prompt é a string que aparece no prompt, options é a lista de opções que podem ser escolhidas, multi representa se múltiplas opções podem ser escolhidas ou não, e args permite passar argumentos adicionais ao rofi. O retorno da função é a/as opção/opções que foi/foram selecionada(s) (apenas a opção se multi era falso, ou a lista de opções se era verdadeiro). Se a seleção foi abortada uma exceção é lançada. Eu considerei usar o python-rofi ao invés de criar meu próprio módulo, mas esse módulo retorna o índice do que foi escolhido ao invés da string em si, o que apenas tornaria o uso mais complicado. Já que era bem fácil criar meu próprio módulo, foi o que eu fiz.

E é isso. Eu realmente gosto do quão fácil é criar menus usando o rofi em python 🙂.