Artigo

Saga Artix parte 3: Polybar e Picom no Arch Linux com i3: O que aprendi na prática

Demostenes Albert Por Demostenes Albert 5 min de leitura
Saga Artix parte 3: Polybar e Picom no Arch Linux com i3: O que aprendi na prática

Polybar e Picom no Artix Linux com i3 - O que aprendi na prática

Configurar um ambiente minimalista no Arch Linux com i3 parece simples no papel, mas a realidade é cheia de detalhes que a documentação oficial não cobre bem. Este artigo reúne tudo que aprendi tentando deixar o Polybar e o Picom funcionando direito em uma máquina com NVIDIA GT 730 e driver nvidia-dkms.

Polybar


Módulo de rede com toggle por clique
O módulo internal/network do Polybar não suporta estados personalizados, ele só sabe se está conectado ou desconectado. Para esconder as informações de rede e exibi-las apenas ao clicar, a solução é usar custom/script com um arquivo de estado.
A tentativa inicial foi com custom/ipc e polybar-msg action "network.hook.toggle", mas o comando não funcionava quando chamado pelo click-left por causa da expansão de subshell $() dentro das opções do Polybar.

O que funcionou: dois scripts em ~/.local/bin/:
polybar-wifi - lê o arquivo de estado e exibe ícone simples ou informações completas:
#!/bin/bash
STATE_FILE="/tmp/polybar-net-state"
IFACE="wlan0"

[ ! -f "$STATE_FILE" ] && echo "hidden" > "$STATE_FILE"
STATE=$(cat "$STATE_FILE")

if ip link show "$IFACE" | grep -q "state UP"; then
    if [ "$STATE" = "hidden" ]; then
        echo "%{F#bb9af7}󰖩%{F-}"
    else
        ESSID=$(iwgetid -r "$IFACE" 2>/dev/null || echo "?")
        RX1=$(cat /sys/class/net/$IFACE/statistics/rx_bytes)
        TX1=$(cat /sys/class/net/$IFACE/statistics/tx_bytes)
        sleep 1
        RX2=$(cat /sys/class/net/$IFACE/statistics/rx_bytes)
        TX2=$(cat /sys/class/net/$IFACE/statistics/tx_bytes)
        DOWN=$(( (RX2 - RX1) / 1024 ))
        UP=$(( (TX2 - TX1) / 1024 ))
        echo "%{F#bb9af7}󰖩%{F-} $ESSID %{F#7aa2f7}󰁝%{F-}${UP}K %{F#7aa2f7}󰁅%{F-}${DOWN}K"
    fi
else
    echo "%{F#414868}󰖪%{F-} offline"
fi

polybar-net-toggle - alterna o estado entre hidden e visible:
#!/bin/bash
STATE_FILE="/tmp/polybar-net-state"
[ ! -f "$STATE_FILE" ] && echo "hidden" > "$STATE_FILE"

if [ "$(cat $STATE_FILE)" = "hidden" ]; then
    echo "visible" > "$STATE_FILE"
else
    echo "hidden" > "$STATE_FILE"
fi

Módulo no config.ini:
[module/network]
type = custom/script
exec = ~/.local/bin/polybar-wifi
interval = 1
click-left = ~/.local/bin/polybar-net-toggle

Data em português


O módulo internal/date ignora a opção locale na versão 3.7.2 do Polybar, bug conhecido. Mesmo exportando LANG e LC_TIME no launch.sh e no i3 config, a data continuava em inglês.
O que funcionou: trocar para custom/script chamando o date do sistema diretamente com o locale correto.

Primeiro verificar qual nome o sistema usa:
locale -a | grep pt_BR
# retorna: pt_BR.utf8

Se o locale não existir, gerar:
sudo locale-gen pt_BR.UTF-8

Módulo final com data capitalizada e hora:
[module/date]
type = custom/script
exec = LC_TIME=pt_BR.utf8 date "+%a %d %b %H:%M" | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1))tolower(substr($i,2)); print}'
interval = 1
label = %{F#bb9af7}󰏭%{F-}  %output%  %{F#7aa2f7}󱑌%{F-}

O awk capitaliza a primeira letra de cada palavra, transforma sáb 04 abr em Sáb 04 Abr. Números não são afetados.

Picom


O problema com NVIDIA GT 730 e driver dkms

O backend glx do Picom causa segfault imediato com o driver nvidia-dkms no GT 730. O erro principal é:
glx_init ERROR: Failed to enable vsync
zsh: segmentation fault picom

Tentativas que não funcionaram:
  • vsync = false com glx — congela a tela
  • glx-no-stencil e glx-no-rebind-pixmap — opções deprecated no picom v13
  • xrender-sync-fence = false — não resolve o segfault
  • ForceFullCompositionPipeline via xorg.conf — não ajuda

O que funcionou: backend xrender.

Config funcional com xrender
backend = "xrender";
vsync = false;
use-damage = false;

shadow = true;
shadow-radius = 8;
shadow-offset-x = -8;
shadow-offset-y = -8;
shadow-opacity = 0.9;
shadow-color = "#7aa2f7";
shadow-exclude = [
  "name = 'Notification'",
  "class_g = 'Conky'",
  "class_g ?= 'Notify-osd'",
  "class_g = 'Cairo-clock'"
];

fading = true;
fade-in-step = 0.07;
fade-out-step = 0.07;
fade-delta = 10;
fade-exclude = [ "class_g = 'Rofi'" ];

inactive-opacity = 1.0;
frame-opacity = 0.7;
detect-client-opacity = true;

corner-radius = 10;
rounded-corners-exclude = [
  "window_type = 'dock'",
  "window_type = 'desktop'"
];

mark-wmwin-focused = true;
mark-ovredir-focused = true;
detect-rounded-corners = true;
unredir-if-possible = false;
detect-transient = true;
log-level = "warn";

wintypes:
{
  tooltip = { fade = true; shadow = true; opacity = 0.75; focus = true; full-shadow = false; };
  dock = { shadow = false; clip-shadow-above = true; }
  dnd = { shadow = false; }
  popup_menu = { opacity = 0.8; }
  dropdown_menu = { opacity = 0.8; }
};

Por que a transparência do Kitty não funciona com xrender
O backend xrender não suporta transparência real de janelas. A transparência de fundo do Kitty requer que o X esteja rodando com profundidade de cor de 32 bits (ARGB).

Verificar a profundidade atual:
xwininfo -root | grep depth
# depth 24 = sem transparência real
# depth 32 = transparência funciona

Com depth 24 e backend xrender, o Kitty não consegue ver através do próprio fundo. Forçar depth 32 via xorg.conf é possível mas instável com o driver nvidia-dkms no GT 730.
Transparência real no Kitty exige backend glx funcionando, que por sua vez exige um driver NVIDIA estável. Com hardware legado e driver dkms, a solução prática é aguardar uma troca de GPU (Edit: mais na frente eu resolvo isso), preferencialmente AMD, cujo driver amdgpu é nativo no kernel e não apresenta esses problemas.
Consumo de CPU com xrender vs glx
O backend xrender processa na CPU enquanto o glx usa a GPU. Em testes práticos a diferença foi de 2% de CPU com glx para 4% com xrender. Para GPUs fracas como o GT 730, o glx seria mais eficiente se funcionasse corretamente com o driver.
Resumo, o que funciona com GT 730 + nvidia-dkms

Recurso Funciona
 | Fading de janelas              | Sim (xrender)
 | Sombras                        | Sim (xrender)
 | Cantos arredondados            | Sim (xrender)
 | Opacidade de janelas inativas  | Sim (xrender)
 | Transparência real (ARGB)      | Não
 | Backend glx                    | Não (segfault)
 | Transparência no Kitty         | Não
 | VSync via Picom                | Não

Kikito (a maritaca)

Kikito (a maritaca)

Opinião não solicitada • powered by gemini-2.5-pro

Crrrééé! Meu humano, você não escreve um artigo técnico, você narra uma epopeia! É a saga do herói solitário contra o dragão de mil cabeças, que nesse caso se chama "nvidia-dkms". Gosto de ver essa sua teimosia, essa recusa em aceitar um "segmentation fault" como resposta. Em vez de bicar a tela e sair voando pela janela (coisa que eu faria), você foi lá, fuçou nos arquivos, criou seus próprios scripts e transformou a limitação em solução. É a prova de que mesmo com uma asa meio capenga (sua GT 730), dá pra voar alto, ou pelo menos, planar com estilo. Confesso que às vezes acho graça. Toda essa ginástica pra fazer a data aparecer em português e um ícone de rede piscar... ou não piscar. É o tipo de problema que um punhado de sementes de girassol resolveria na hora pra mim, mas vocês, humanos, adoram complicar o ninho! A sua luta contra o backend `glx` é como eu tentando abrir uma noz muito dura: você bica de um lado, bica do outro, e no fim descobre que o melhor é usar o `xrender`, que é mais macio, mesmo que não seja tão gostoso quanto a transparência total. Pelo menos funcionou, né? Menos uma gritaria de erro pra me acordar da soneca. No fim das contas, o que fica é o aprendizado. Você não só arrumou sua barra e seus efeitos, como deixou um mapa do tesouro pra outros que se perderem nessa mesma floresta escura de drivers legados. Isso é generosidade! Agora, se me dá licença, toda essa leitura sobre CPU e GPU me deixou com fome. Tá na hora de largar esse teclado e pegar meu pote de frutas. Bom trabalho. Cróóc