Beta · 1.0.0-beta.1
veil: Um daemon de papel de parede para compositores Wayland.
O veil mostra uma imagem ou um vídeo em loop em cada monitor, pode dar a cada monitor um papel de parede próprio, pausa um vídeo que ninguém consegue ver e restaura o que cada monitor exibia depois de uma reinicialização.
É escrito em Rust, reproduz vídeos com GStreamer e é controlado pela linha de comando, por um arquivo de configuração ou por um socket que scripts e barras de status podem usar.
- Versão
- 1.0.0-beta.1
- Licença
- PolyForm Strict
- Escrito em
- Rust
- Requer
- wlr-layer-shell
# draws on every monitor (black until a wallpaper is set)
veil daemon &
# a video or a picture; saved, and shown again after a restart
veil set --input ~/Videos/waves.mp4
# what each monitor shows
veil statusDepois de instalar o veil, na sua sessão Wayland. Para iniciá-lo junto com a sessão, use a unidade de usuário do systemd no lugar de veil daemon &.
Imagens e vídeo, em todos os monitores.
Suportado significa implementado, coberto por testes automatizados e verificado em um compositor. Experimental significa que funciona, com uma limitação que convém conhecer.
Imagens
SuportadoPNG, JPEG, WebP, BMP, TIFF, GIF e os demais formatos do crate image. Uma imagem é desenhada na resolução física do monitor, e a cópia decodificada é liberada em seguida.
Vídeo em loop
SuportadoSem áudio, em qualquer formato que os plugins GStreamer instalados reproduzam. Verificados: H.264, HEVC, VP8, VP9 e AV1, e dez contêineres.
Cada monitor com o seu
SuportadoTodos os monitores, ou os que forem indicados, cada um com um papel de parede próprio, e monitores conectados depois. Um monitor mantém o papel de parede pelo nome.
com vídeo, uma mudança de monitor é experimental
Pausa o que ninguém vê
SuportadoAtrás de uma janela em tela cheia, um vídeo mantém o quadro na tela e não decodifica nada. Uma tela bloqueada ou um monitor desligado o interrompe após dois segundos.
sway · experimental no Hyprland
Lembra
SuportadoO papel de parede de cada monitor é salvo e exibido de novo após uma reinicialização. veil set --no-persist evita isso.
Nunca uma tela em branco no meio
SuportadoUm novo papel de parede só substitui o anterior quando está pronto. Um vídeo assume quando o primeiro quadro está na tela; um arquivo que não pode ser exibido deixa o papel de parede anterior como está.
HiDPI e escala fracionária
SuportadoAs imagens são desenhadas na resolução física do monitor. Verificado pixel a pixel nas escalas 1; 1,25; 1,5 e 2.
Controlado de qualquer lugar
Suportadoset, clear, pause, resume, toggle, status, outputs, quit e ping, com códigos de saída estáveis, além de um socket de controle para scripts e barras de status.
Cinco maneiras de ajustar uma imagem a um monitor.
--mode define como um papel de parede é ajustado ao seu monitor, para imagens e vídeos. O --mode e o --bg-color do daemon também são os padrões de veil set.
--mode fillCobre o monitor inteiro, mantendo a proporção. O excesso é cortado por igual dos dois lados. O padrão.
--mode fitA imagem inteira fica visível, mantendo a proporção. Barras de --bg-color preenchem o resto.
--mode stretchAjustada exatamente ao tamanho do monitor; a proporção não é mantida.
--mode centerTamanho nativo, um pixel por pixel do dispositivo, centralizada. Cortada se for maior que o monitor, cercada por --bg-color se for menor.
--mode tileTamanho nativo, repetida a partir do canto superior esquerdo. Vídeos voltam para center.
Um comando para todos os monitores, ou para um só.
Execute os comandos em dois monitores de exemplo. O que os monitores mostram e o que veil status imprime são uma ilustração, no formato que o veil usa.
Exemplos: ~/Pictures/sunset.jpg, ~/Pictures/dawn.jpg e o vídeo ~/Videos/sunrise.mp4.
veil 1.0.0-beta.1 (pid 4218), running for 7s; videos pause on: fullscreen default: ~/Pictures/sunset.jpg (fill, #000000) DP-3: playing ~/Videos/sunrise.mp4 (fill, #000000); 1920x1080 at scale 1; video 1920x1080, 25 fps HDMI-A-1: showing ~/Pictures/sunset.jpg (fill, #000000); 2048x1152 at scale 1.25
Um vídeo que ninguém vê custa quase nada.
No Hyprland e no sway, o veil acompanha o IPC do compositor e pausa um vídeo que ninguém consegue ver. Em qualquer compositor, um vídeo cujos quadros o compositor não aceita é interrompido e seu pipeline é liberado.
- CPU do daemon
- 19,5 %
- veil status diz
- playing
O vídeo é reproduzido e decodifica todos os quadros.
- CPU do daemon
- ≈ 0 %
- veil status diz
- paused (hidden by a window)
Oculto por um segundo, o vídeo mantém o quadro na tela e não decodifica nada. Continua do mesmo quadro quando volta a ser visível.
- CPU do daemon
- ≈ 0 %
- veil status diz
- stopped while the compositor does not show it
O compositor não aceita quadros por 2 segundos, então o veil solta o vídeo. Ele recomeça do início.
CPU é a parcela do daemon em um núcleo, para um vídeo H.264 de 1080p a 30 fps decodificado em uma placa NVIDIA. Atrás de uma janela em tela cheia, mediu no máximo um tick de tempo de CPU em 5 segundos.
O que um papel de parede custa.
Medido na compilação de 2026-10-19 em um sway headless, uma saída de 1920x1080 em fill, 60 segundos após 5 segundos de aquecimento, em um Intel Core i5-11400F com uma NVIDIA GeForce RTX 3060 Ti. Ainda não se mediu nada em uma sessão real.
| Papel de parede | CPU, parcela de um núcleo | Quadros exibidos por segundo | Memória (RSS) | Threads |
|---|---|---|---|---|
| Um PNG de 1920x1080sem decodificador | 0,02 % | — | 20 MiB | 1 |
| H.264, 1080p, 30 fpsnvh264dec (GPU) | 19,5 % | 30,0 de 30 | 203 MiB | 15 |
| H.264, 1080p, 60 fpsnvh264dec (GPU) | 39,7 % | 59,8 de 60 | 203 MiB | 15 |
| VP9, 1080p, 60 fpsnvvp9dec (GPU) | 37,9 % | 59,9 de 60 | 251 MiB | 15 |
| H.264, 2160p, 60 fpsnvh264dec (GPU) | 136 % | 60,2 de 60 | 297 MiB | 15 |
| H.264, 1080p, 30 fpsavdec_h264 (software) | 24,5 % | 30,0 de 30 | 161 MiB | 22 |
| H.264, 2160p, 60 fpsavdec_h264 (software) | 174 % | 60,1 de 60 | 458 MiB | 22 |
- Uma imagem estática custa quase nada depois de desenhada: uma thread e um tick de tempo de CPU em um minuto.
- Um vídeo custa CPU em proporção aos seus pixels por segundo, seja qual for o codec. Na NVIDIA, o decodificador na GPU custa cerca de 1 %; o resto é converter cada quadro de NV12 para RGB na CPU.
- A meta de projeto do veil, menos de 1 % para um vídeo, não é atingida neste hardware. Em Intel e AMD, o VA-API poderia evitar essa conversão; isso não foi medido.
- Memória, threads e descritores de arquivo permanecem estáveis ao longo de dez minutos de loop e 500 trocas de papel de parede, com uma única arena do alocador (MALLOC_ARENA_MAX=1, definido pelo pacote Nix e pela unidade systemd).
A linha de comando, um arquivo ou um socket.
Todo comando do veil é um cliente do socket do daemon, e qualquer outra coisa também pode ser: uma barra de status, um atalho de teclado, um script em qualquer linguagem.
Linha de comando
Todo comando aceita --help e tem uma página de manual. veil set retorna quando o papel de parede está na tela e termina com código de saída 1, mantendo o anterior, se o arquivo não puder ser exibido.
# every monitor
veil set --input ~/Videos/waves.mp4
# one monitor; the others keep theirs
veil set --input ~/Pictures/photo.jpg --output DP-3
# pause videos until `veil resume`
veil pause
# what each monitor shows, as JSON for scripts
veil status --jsonArquivo de configuração
~/.config/veil/config.toml guarda as opções do daemon e o papel de parede de cada monitor. veil config check o lê como o daemon leria e informa uma chave incorreta com a linha e a coluna.
[defaults]
mode = "fill" # --mode
bg_color = "#000000" # --bg-color
pause_on = "covered" # --pause-on
[output."DP-3"]
input = "~/Videos/waves.mp4"
mode = "fit"
[output."*"] # every monitor without a section of its own
input = "~/Pictures/wallpaper.png"Socket de controle
Uma requisição JSON e uma resposta JSON por conexão, apenas para processos do mesmo usuário. Campos, comandos e códigos de erro só são acrescentados, nunca renomeados nem removidos.
sock="$XDG_RUNTIME_DIR/veil-${WAYLAND_DISPLAY##*/}.sock"
echo '{"cmd":"ping"}' | socat - UNIX-CONNECT:"$sock"
# {"version":1,"status":"ok"}
echo '{"cmd":"toggle"}' | socat - UNIX-CONNECT:"$sock"
# {"version":1,"status":"ok","result":{"paused":true}}O que foi executado, e por quem.
Da matriz de suporte do próprio veil. Não testado significa que ninguém tentou ainda, não que se saiba que falha.
Compositores
sway 1.12 (headless)
Todas as verificações dos testes headless e das medições, 2026-10-19.
VerificadoHyprland 0.56.2
Imagens, vídeo H.264 em dois monitores e a pausa automática, 2026-10-20. Fluidez, bloqueio, DPMS, logout e recuperação de falhas não foram testados.
Funcionamento relatadoriver, niri, Wayfire, labwc e outros compositores com wlr-layer-shell
Deve funcionar. Sem pausa automática: todo vídeo conta como visível.
Não testadoKDE Plasma (KWin)
Tem wlr-layer-shell; ninguém testou.
Não testadoGNOME (Mutter)
Sem wlr-layer-shell.
Sem suporte
Gráficos
NVIDIA (NVDEC)
RTX 3060 Ti, driver 595.91.07, sway e Hyprland. Todo quadro de vídeo é convertido na CPU.
Funcionamento relatadoIntel e AMD (VA-API)
O caminho de cópia zero não foi verificado em nenhum hardware.
Não testadoDecodificação por software
Nos testes, e removendo os decodificadores de hardware.
Funcionamento relatado
Arquiteturas
x86_64
O tarball em um contêiner de seis distribuições, 2026-10-19.
Funcionamento relatadoaarch64
O workflow de lançamento o compila e executa os testes nele; nunca foi executado com um compositor.
Não testado
Distribuições
Debian 12 e 13, Ubuntu 22.04 e 24.04, Fedora 44, Arch Linux
O tarball pré-compilado em um sway headless, 2026-10-19. GIFs animados exigem GStreamer 1.26 ou mais recente.
Funcionamento relatadoNixOS (o flake)
nix run e nix profile, com sway e Hyprland. 2026-10-20 e 2026-11-04.
Verificado
As arestas, declaradas de antemão.
O veil é um beta. Isto é o que se sabe estar errado hoje; os detalhes, as medições e as opções consideradas estão nos problemas conhecidos.
Uma mudança de monitor durante a reprodução de um vídeo derruba o daemon
O defeito está no waylandsink do GStreamer: ele sofre um segfault quando o compositor informa uma mudança em qualquer monitor. As imagens não são afetadas. Execute o veil pela sua unidade systemd: ele volta com os papéis de parede em cerca de três segundos.
Problema conhecido 1
Um vídeo consome CPU na NVIDIA
Cerca de 20 % de um núcleo para 1080p a 30 fps, porque cada quadro é convertido para RGB na CPU.
Problema conhecido 7
A memória cresce com as trocas de vídeo sem uma única arena do alocador
O pacote Nix e a unidade systemd definem MALLOC_ARENA_MAX=1; defina-o ao iniciar à mão um binário compilado a partir do código-fonte.
Problema conhecido 3
Binários pré-compilados, Nix ou código-fonte.
O veil precisa de um compositor Wayland com wlr-layer-shell e do GStreamer 1.x, com os conjuntos de plugins base, good, bad e libav, em tempo de execução. XDG_RUNTIME_DIR deve estar definido, como em qualquer sessão de desktop.
Pré-compilado
Cada lançamento tem um tarball para Linux x86_64 e outro para aarch64: o binário, a unidade de usuário do systemd, as páginas de manual, o autocompletar do shell e um script de instalação. Os binários pré-compilados ainda são experimentais.
version=1.0.0-beta.1
tarball=veil-$version-$(uname -m)-unknown-linux-gnu.tar.gz
curl -LO https://github.com/ordreth/veil/releases/download/v$version/$tarball
curl -LO https://github.com/ordreth/veil/releases/download/v$version/SHA256SUMS
sha256sum --check --ignore-missing SHA256SUMS
tar -xzf "$tarball" && cd "${tarball%.tar.gz}"
./install.sh --prefix ~/.localCada tarball tem uma atestação de proveniência de compilação: gh attestation verify "$tarball" --repo ordreth/veil.
Nix
O pacote do flake vem empacotado com seus próprios plugins do GStreamer e um registro do GStreamer próprio, e inclui a unidade de usuário do systemd, o autocompletar e as páginas de manual.
nix run github:ordreth/veil -- daemon # try it without installing
nix profile add github:ordreth/veil # install itPor causa da licença, o nixpkgs considera o veil unfree. Os pacotes do próprio flake já a permitem; com o overlay, permita-a na configuração.
Do código-fonte
São necessários Rust 1.89 ou mais recente, um compilador C e o pkg-config, e os arquivos de desenvolvimento do Wayland, do libxkbcommon e do GStreamer. O guia de instalação lista os pacotes para Arch, Debian, Ubuntu e Fedora.
git clone https://github.com/ordreth/veil && cd veil
cargo build --release --locked
install -Dm755 target/release/veil ~/.local/bin/veilAo iniciar à mão um binário compilado por você, use MALLOC_ARENA_MAX=1, como em MALLOC_ARENA_MAX=1 veil daemon.
Uso gratuito, código-fonte disponível, não é código aberto.
O veil é licenciado sob a PolyForm Strict License 1.0.0, com permissões adicionais. É permitido ler o código e usar o veil para qualquer fim não comercial.
Permitido
- Usar o veil para qualquer fim não comercial.
- Compilar o veil a partir do código-fonte para uso próprio.
- Redistribuir os tarballs de lançamento, sem alterações, byte a byte.
- Citar até 50 linhas do código-fonte, com atribuição.
- Usar o nome e o ícone para se referir ao veil.
Não permitido
- Distribuir o código-fonte ou uma compilação própria.
- Alterá-lo ou criar novas obras a partir dele.
- Usá-lo comercialmente.
- Usar o nome ou o ícone para outro produto ou para uma versão modificada.
O veil não aceita pull requests, patches nem issues. Relatos de como ele funciona na sua máquina são bem-vindos no GitHub Discussions, e problemas de segurança, em particular, como diz o SECURITY.md.
Os documentos do próprio veil.
Estas páginas são cópias dos documentos do repositório do veil, e por isso são lidas do mesmo jeito aqui e lá.
Início
Referência
Projeto
Beta · 1.0.0-beta.1
Uso gratuito, código-fonte disponível e inacabado. O que se sabe estar errado está nesta página; o que você encontrar na sua máquina é bem-vindo nas discussões.