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"
fipolybar-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"
fiMó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