Distribuciones

Jamey Sharp elogia el diseño de Wayland tras crear su primer cliente

Hay una clase de elogio que vale más que cualquier encuesta de escritorio: la de alguien que construyó el protocolo anterior y todavía puede comparar las dos arquitecturas con las manos. El 27 de octubre de 2026, Jamey Sharp escribió en Mastodon que acababa de escribir su primer cliente Wayland y que estaba, textual, honestly really impressed by the design of the Wayland protocol. Sharp es co-creador de XCB, la implementación en C del protocolo X que sustituyó a Xlib, así que su opinión no es la de un usuario que acaba de cambiar de escritorio: es la de quien lleva dos décadas diseñando la capa de transporte que hoy se considera el problema.

Lo interesante es que el resumen que circuló se quedó en la mitad pequeña de la historia. El cliente de Sharp no era un ejercicio de ventana: era un instrumento de medición. Lo escribió para destapar un bug de VK_EXT_present_timing en Mesa, quitando capas de abstracción hasta quedar frente al protocolo crudo. Y en el camino encontró algo que sigue abierto: los timestamps de presentación que reporta Wayland llegan con uno o dos frames de retraso, y Sharp no llega a concluir si la culpa es del compositor, del kernel o de la especificación. Este post recorre ese hilo completo, te da los comandos para auditar tu propio compositor y te muestra el mapa de versiones del protocolo por distribución, que es donde casi siempre se esconden las sorpresas.

TL;DR — Lo que vas a tener al final

  • Tiempo de setup: 35-45 minutos reales: 20 de lectura del hilo original y del XML del protocolo, 10 de auditoría con wayland-info y WAYLAND_DEBUG sobre tu sesión, y 15 de compilación del cliente de prueba en Rust.
  • Requisitos: Un escritorio Linux con sesión Wayland activa (en un servidor headless no hay compositor que auditar), los paquetes wayland-utils y libwayland-bin, y Rust 1.86 o superior para que cargo resuelva wayland-protocols 0.32.13 y no se quede en 0.32.12.
  • Resultado: Entiendes el argumento de diseño de Sharp (un protocolo pensado para lo difícil, no para lo fácil), puedes listar los globals que negocia tu compositor y las versiones exactas de xdg-shell, y terminas con un cliente Rust mínimo que abre una ventana.
  • Troubleshooting: Si wayland-info responde failed to create display estás en una máquina sin compositor; si loginctl se queja con self, usa el identificador de sesión de loginctl list-sessions; si cargo se queda en wayland-protocols 0.32.12, tu rustc es anterior a 1.86.

El contexto: por qué Sharp es la persona indicada para hablar de Wayland

XCB es, según su propia página oficial, el reemplazo de Xlib con huella pequeña, ocultamiento de latencia, acceso directo al protocolo, mejor soporte de hilos y extensibilidad. Es decir: la respuesta de la comunidad X11 a que Xlib fuera un monolitodiseñado para todo y por lo tanto Holgado para todo. XCB tampoco hizo que escribir una aplicación fuera trivial, y esa es la parte que Sharp mismo reconoce con franqueza en el hilo: un par de funciones donde antes había una, porque cada ida y vuelta al servidor X tiene costo, y esconder ese costo detrás de una función cómoda solo empuja a los desarrolladores a escribir clientes X peores.

Sharp también intentó resolver el problema de los ayudantes que no pertenecen al protocolo, con las librerías xcb-util, aunque en su propia retrospectiva admite no estar seguro de que alguna vez tuvieran suficiente desarrollo para ser realmente útiles. Ese es el recuerdo de fondo útil: la lección de XCB fue que un protocolo más estricto y asíncrono no resuelve por sí solo la experiencia de desarrollo. Si alguien que diseñó eso mira Wayland y dice que el diseño es bueno, la razón tiene peso.

Lo que se lee entre líneas del elogio

El fragmento en el que Sharp responde a alguien que se quejaba de cuánto código hace falta para abrir una ventana en Wayland es la parte que resume el argumento completo: this is a protocol designed to make hard things possible, not to make easy things easy. Un protocolo que hace fácil lo fácil no aporta nada frente al que ya tienes; lo que aporta es poder hacer las cosas que antes no se podían hacer. Wayland no compite con Xlib en ergonomía, compite en capacidad: superficies con Damage explícito, Present con tiempos de fotogramas reales, compositor como autoridad única sobre la pantalla en vez de un servidor X que todos comparten. La comodidad, en ese esquema, vive en las capas superiores (GTK, Qt, SDL), que eligen qué parte de la flexibilidad del protocolo descartar.

Lo que Sharp escribió realmente: el hilo completo

El post que desató la conversación salió el 27 de octubre de 2026 a la 1:13 PM en su cuenta de Mastodon, y en el mismo día abrió un hilo de réplicas que es donde está el contenido técnico de verdad. Michael Larabel lo recogió en Phoronix el 28 de octubre de 2026 a las 08:54 AM EDT con el titular sobre el diseño del protocolo de Wayland y 317 comentarios, pero su resumen se queda en el primer mensaje.

En el segundo mensaje, Sharp aclara el motivo: I actually wrote this Wayland test app because I think I am getting incorrect data from the VK_EXT_present_timing extension as implemented by Mesa on Wayland, y aclara que estaba quitando capas de abstracción para poder reportar el bug con datos limpios. También menciona que tuvo que saltarse WGPU, que es una abstracción agradable, porque todavía no soporta esa extensión de Vulkan y tuvo que bajar a la capa cruda en varios puntos. La comparación con Vulkan termina siendo explícita: para Sharp, Vulkan es otro diseño de make difficult things possible, no una abstracción multiplataforma en la que apoyarse.

Al día siguiente, la observación que sostiene todo: Today I tested five different compositors and they all produced timestamps that were off by one or two frames. Cinco compositors, el mismo desplazamiento. Su hipótesis inicial fue un bug del kernel, aunque dejó la puerta abierta a que fuera un problema de diseño de API. Lo importante para el lector: Sharp dice I am still investigating, y esa frase es exacta y deliberada. No hay bug confirmado, no hay parche, no hay CVE. Hay una medición que no cuadra y una hipótesis de trabajo que nadie ha cerrado en público.

Audita tu sesión Wayland para ver qué negocia tu compositor

Antes de discutir versiones, conviene ver con qué estás trabajando. La herramienta base es wayland-info, que viene en el paquete wayland-utils y lista los globals que el compositor publica. Este primer bloque identifica tu sesión, que es el paso que casi todos olvidan porque asumen que el terminal corre dentro de la sesión gráfica:

echo "XDG_SESSION_TYPE=${XDG_SESSION_TYPE:-sin valor}"
echo "XDG_CURRENT_DESKTOP=${XDG_CURRENT_DESKTOP:-sin valor}"
loginctl list-sessions --no-legend
SID="${XDG_SESSION_ID:-$(loginctl list-sessions --no-legend 2>/dev/null | awk 'NR==1 {print $1}')}"
loginctl show-session "$SID" -p Type -p Name --no-pager

El valor de Type es el que te dice contra qué estás trabajando: wayland para una sesión Wayland, x11 para una sesión X11 clásica y unspecified para sesiones de terminal como las que abre SSH. Si tu terminal es de ese último tipo, no hay compositor al que auditar y este bloque te da la respuesta sin adivinar.

Ahora sí, el inventario de globals. En una sesión gráfica activa vas a ver el compositor, la superficie, el gestor de dispositivos de entrada y el shell de escritorio:

wayland-info 2>&1 | head -25

Si la salida es failed to create display: No such file or directory, no hay compositor al alcance del proceso, y ese mensaje es exactamente el que obtuve al ejecutar este bloque en una máquina sin sesión gráfica. No es un error de configuración: es la respuesta correcta para un servidor headless.

Para ver la negociación completa, con cada request y cada evento, activa el rastreo del propio cliente. La variable WAYLAND_DEBUG está compilada dentro de libwayland-client, y a nivel 1 imprime el tráfico del protocolo en la salida estándar:

WAYLAND_DEBUG=1 wayland-info 2>&1 | head -30

Lee el protocolo en el XML: qué versiones estás negociando

Cada interfaz de Wayland tiene un número de versión independiente, y el compositor publica el máximo que soporta. La forma más limpia de ver qué versiones trae tu sistema es leer el XML que instala el paquete wayland-protocols, no el que trae el compositor en ejecución. En una Debian 13:

grep -oE 'interface name="[a-z_]+" version="[0-9]+"' /usr/share/wayland-protocols/stable/xdg-shell/xdg-shell.xml | sort -u

Ese archivo define cinco interfaces: xdg_wm_base, xdg_positioner, xdg_surface, xdg_toplevel y xdg_popup, todas en la versión 7 tanto en el archivo local de Debian 13 como en el XML actual del proyecto upstream. La jerarquía importa: xdg_surface es la base de una superficie de escritorio, xdg_toplevel es la ventana, y xdg_popup son los menús contextuales y desplegables, con xdg_positioner decidiendo dónde caen. Un cliente que habla xdg-shell 7 sabe más que uno que habla la versión 4, y por eso el número de versión no es un detalle de empaquetado.

El protocolo base de Wayland trae además el conjunto habitual: wl_display y wl_registry en versión 1, wl_compositor y wl_surface en versión 7, wl_seat en versión 11 con su teclado, puntero y táctil, wl_output en versión 4, y wl_shm en versión 3 para la memoria compartida.

Genera el código del protocolo con wayland-scanner

El XML no es documentación: es fuente. El mismo archivo que leíste antes se convierte en un encabezado de C con wayland-scanner, que vive en el paquete libwayland-bin. Este es el mecanismo real detrás de cualquier binding de Wayland, y el mismo comando genera las definiciones de Rust:

wayland-scanner client-header /usr/share/wayland-protocols/stable/xdg-shell/xdg-shell.xml /tmp/xdg-shell-client.h
wc -l /tmp/xdg-shell-client.h
grep -c 'static inline void' /tmp/xdg-shell-client.h

En esta máquina el encabezado generado tiene 2381 líneas y 42 funciones de request generadas. Ese es el volumen real de la superficie xdg-shell: si un binding te parece gigantesco, estás mirando esto, y la queja de que Wayland exige mucho código para abrir una ventana se entiende mucho mejor después de ver cuántas funciones hay debajo.

Y hay una pieza de protocolo que explica buena parte de la complejidad percibida: el evento ping de xdg_wm_base pregunta al cliente si sigue vivo, y el cliente debe responder con un request pong o el compositor puede declararlo no responsivo. Un cliente que no implementa el ping no está escribiendo mal código: está dejando que lo desconecten.

Compila un cliente Wayland mínimo en Rust

Sharp escribió el suyo en Rust, y la ruta es directa porque wayland-client no necesita libwayland: trae una implementación pura en Rust del protocolo. El andamiaje completo:

cargo new --lib cliente-wayland
cd cliente-wayland
cargo add wayland-client wayland-protocols
cat Cargo.toml

El detalle que más salta en la práctica es el MSRV. wayland-protocols 0.32.13 exige Rust 1.86, y con un compilador anterior cargo lo descarta en silencio con un aviso: ignoring [email protected] (which requires rustc 1.86) as it is incompatible with rustc 1.85.1. El Cargo.toml resultante fija 0.32.12 y compila sin problema. Si tu proyecto de Rust tiene un rust-version viejo, esa es la explicación de por qué no llegas a la última versión del protocolo.

cargo check
cargo build --release

Los dos comandos terminan sin errores con las versiones compatibles que cargo resolvió. Para el ejemplo de ventana, Sharp siguió el simple_window del repositorio wayland-rs y después el tutorial de wayland-book.com, y documentó un tropiezo útil: no se repinta nada hasta que le dices al compositor que toda la ventana está dañada, algo que en X11 era implícito y en Wayland es una línea explícita de daño.

Compara las versiones del protocolo por distribución

Aquí es donde se cocinan los problemas en la práctica. Las versiones de la biblioteca de Wayland no van al ritmo de los tags upstream, y un servidor con una versión antigua no puede negociar las interfaces nuevas aunque el compositor de tu escritorio sí sepa hacerlo:

Distribución Serie Versión de libwayland Publicada
Debian bullseye 1.18.0-2~exp1.1 rama antigua
Debian bookworm 1.21.0-1 estable
Debian trixie 1.23.1-3 estable actual
Debian sid / forky 1.26.0-1 desarrollo
Ubuntu 22.04 jammy 1.20.0-1ubuntu0.1 2022-09-15
Ubuntu 24.04 noble 1.22.0-2.1build1 2024-04-16
Ubuntu 25.04 plucky 1.23.1-3 2025-02-20
Ubuntu 25.10 questing 1.24.0-1build1 2025-09-07
Ubuntu 26.04 resolute 1.24.0-2 2025-11-01

El salto entre Ubuntu 24.04 con 1.22 y Debian 13 con 1.23 es de un ciclo completo de protocolo, y un servidor con Ubuntu noble no puede usar ni negociar lo que sí está en trixie. Para verificar qué tienes en tu máquina, tres consultas bastan:

dpkg -l 'libwayland*' 'wayland*' 2>/dev/null | tail -n +6
pkg-config --modversion wayland-client wayland-scanner wayland-protocols
apt-cache policy wayland-utils wayland-protocols libwayland-dev wl-clipboard

En la máquina donde armé esta guía, la primera consulta muestra libwayland-client0, libwayland-bin, libwayland-dev, libwayland-egl1 y libwayland-server0 en 1.23.1-3, más wayland-utils 1.2.0-2 y wayland-protocols 1.44-1. Las tres versiones de pkg-config son 1.23.1, 1.23.1 y 1.44. Nota que wayland-scanner viene en el paquete libwayland-bin y no en libwayland-dev: es un error de búsqueda habitual cuando buscas el generador de cabeceras y no lo encuentras.

Y para comparar con el upstream, estos son los tags recientes del proyecto: Wayland 1.26.0 del 16 de julio de 2026 y wayland-protocols 1.50 del 29 de octubre de 2026, con 1.49 y 1.48 como anteriores. En crates.io, las versiones estables actuales son wayland-client 0.31.15 y wayland-scanner 0.31.11, ambos del 22 de julio de 2026, y wayland-protocols 0.32.13 del 19 de junio de 2026, que es la que exige Rust 1.86.

Lo que Sharp no resolvió: el timestamp de presentación en Mesa

El detalle que hace que esta historia trascienda laorbid news es que el problema que Sharp encontró sigue sin cerrar, y la discusión técnica es precisa. En su mensaje del 28 de octubre, Sharp señala que la extensión de tiempo de presentación de Wayland dice literalmente que el timestamp corresponde al momento en que la actualización de contenido se convierte en luz por primera vez en la salida principal de la superficie, mientras que Mesa está reportando ese valor como el timestamp de la etapa de primer píxel salido, que en Vulkan se define como el punto en que los datos del primer píxel han salido del motor de presentación hacia el hardware. Su conclusión, con la prudencia de quien todavía está midiendo: I am mostly sure that reporting a timestamp from a couple of frames earlier is not the intended behavior. But I am still investigating.

Josh Simmons, que participa en el hilo, responde que la expresión turns into light es una forma de hablar y que no es lo que reporta nada, y sugiere que el problema puede ser que se está recibiendo el timestamp de un frame histórico en lugar del esperado, y que hay que emparejar los identificadores de presentación después del hecho. Sharp está de acuerdo con lo del emparejamiento, porque ya lo hace en su lado de Vulkan: asocia un identificador de presentación a cada frame, consulta present_timing más tarde y busca el informe del frame que le interesa. Y descarta la confusión entre frames propios como causa: espera al menos 100 milisegundos antes de presentar cada frame en sus dos pruebas.

Donde Sharp discrepa es en el punto de fondo, y ahí está la lección: no intenta resolver el problema de pacing de frames que preocupan a los desarrolladores de juegos. Lo que quiere saber es cuándo puede ver un humano una actualización en pantalla, para medir con exactitud cuánto tarda esa persona en reaccionar. Y por eso termina con una observación que vale para todo el ecosistema: hoy hace falta hardware especial para verificar que los timestamps sean correctos, así que no debería sorprender que existan bugs. Eso también explica por qué la extensión tardó más de cinco años en entrar en Mesa: en 2014, cuando trabajó en GLX_OML_sync_control, la presentación de frames con tiempos fiables no le interesaba a casi nadie.

Qué significa todo esto para tu homelab

Si tu trabajo es administrar servidores, la conclusión directa es que el elogio de Sharp no cambia tu lista de tareas de hoy. Wayland no es una migración de servidor: es un protocolo de gráficos de escritorio. Lo que sí cambia es la lectura que haces de los avisos de X11 y de las herramientas que dependían de X11, y ahí hay dos consecuencias prácticas.

La primera es sobre Xwayland. Mientras tu distribución mantenga la capa de compatibilidad, las aplicaciones X11 siguen funcionando sobre Wayland y no vas a notar un cambio el día en que el compositor deje de ofrecer X11. Pero cuando eso ocurra en tu distribución, las herramientas que automatizan pantallas, las que capturan ventanas y las que reciben eventos de teclado globals dejan de funcionar de la misma manera. Ahí es donde el diseño del protocolo se vuelve relevante: si tu automatización depende de interceptar y sintetizar eventos de entrada, esas capacidades existen en Wayland pero se retiran de forma deliberada, y las herramientas que las usan tienen que pasar por los canales de portal en lugar de hacerlo directamente.

La segunda es más aburrida y más útil: el versionado. Ahora sabes que xdg-shell va en la versión 7, que tu Debian 13 trae libwayland 1.23 y wayland-protocols 1.44, y que el upstream va por wayland-protocols 1.50. Cuando una aplicación nueva te exija una interfaz que tu sistema no tiene, el síntoma no va a ser un error claro: va a ser un cliente que se conecta y no recibe el global que necesita. Con la tabla de arriba y los tres comandos de consulta puedes responder esa pregunta en un minuto en lugar de una tarde.

Y queda el asunto de fondo, que es la lección de Sharp y la razón de su comentario sobre XCB: los protocolos con capas de abstracción no son un defecto de diseño, son la razón por la que puedes hacer cosas que antes eran imposibles. La comodidad tiene que vivir en algún nivel, y en X11 terminó viviendo en el sitio equivocado, dentro del núcleo del protocolo. En Wayland vive en los toolkits, que es exactamente donde puede vivir sin estorbar a quien necesita el control fino.

Preguntas frecuentes

¿Por qué Wayland necesita más código que X11 para abrir una ventana?

Porque Wayland no esconde el modelo de superficies. Tienes que enlazar los globals del compositor, crear la superficie, crear el objeto de shell, configurar el tamaño, adjuntar un buffer y marcarla como dañada antes de cada commit. X11 resolvía parte de eso en el servidor; Wayland lo resuelve en el compositor, y esa responsabilidad se nota en el código del cliente. La respuesta corta de Jamey Sharp es que ese es el trato: el protocolo hace posibles las cosas difíciles y deja la comodidad a los toolkits como GTK, Qt o SDL.

¿Qué es xdg-shell y por qué aparece en todas partes?

Es la capa que describe cómo se construyen las ventanas de escritorio sobre el protocolo base de Wayland. Define xdg_wm_base, xdg_positioner, xdg_surface, xdg_toplevel y xdg_popup, y todas están en la versión 7 en el XML actual del proyecto. xdg_surface es la base, xdg_toplevel es la ventana normal y xdg_popup son los menús y desplegables. Wayland puro sirve superficies; xdg-shell es lo que le da al compositor la noción de ventana, que es lo que los usuarios y las herramientas de escritorio esperan.

¿Cómo confirmo si mi sesión usa Wayland o X11?

Usa loginctl. El comando loginctl list-sessions muestra las sesiones activas con su identificador, y loginctl show-session con ese identificador y los parámetros Type y Name devuelve el tipo de sesión: wayland, x11 o unspecified para una terminal. Ojo con loginctl show-session self: en un servidor sin sesión de login devuelve un error de pertenencia a sesión y el comando falla. La variable XDG_SESSION_TYPE también sirve si tu terminal heredó el entorno gráfico.

¿Sharp reportó un bug de Wayland o de Mesa?

Ninguno de los dos está confirmado. Sharp escribió el cliente porque sospechaba datos incorrectos de VK_EXT_present_timing en Mesa sobre Wayland, y reportó timestamps con uno o dos frames de retraso en cinco compositors distintos, sin llegar a una conclusión. Él mismo dice que sigue investigando, y un participante del hilo sugiere que podría estar recibiendo el timestamp de un frame histórico en lugar del esperado. No hay parche oficial ni advisory asociado: es una investigación abierta.

¿Qué hago si cargo no instala la última versión de wayland-protocols?

Revisa la versión de tu compilador de Rust. La versión estable 0.32.13 de wayland-protocols exige Rust 1.86, y con un rustc anterior cargo la descarta y fija 0.32.12 en el Cargo.toml, mostrando un aviso de incompatibilidad. La solución es actualizar la toolchain o fijar la versión en tu manifiesto. El paquete de la biblioteca del sistema es otra historia: libwayland 1.23 en Debian 13 y 1.22 en Ubuntu 24.04 obedecen al calendario de cada distribución, no al upstream.

Lee también

Alfonso Moreno | Sysadmin Senior

Soy Alfonso, sysadmin senior con RHCE y más de 10 años administrando sistemas Linux para empresas y proyectos personales. Me especializo en infraestructura, redes, virtualización, monitoring, automation y self-hosting. Sobre SoyLinux.com SoyLinux.com es un blog técnico en español sobre Linux, software libre y self-hosting. Lo mantengo en mi tiempo libre. Áreas de expertise - Linux server administration: RHEL, CentOS, Rocky, Alma, Fedora, Debian, Ubuntu - Network services: Postfix, BIND, Samba, NFS, Squid - Virtualización y containers: KVM, Proxmox, Docker, Podman - Monitoring: Prometheus, Grafana, Zabbix - Automation: Ansible, Bash scripting - Self-hosting: Vaultwarden, Nextcloud, Jellyfin, Immich, Homelab Contacto - Email: [email protected]

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *