ANGLE finally got Wayland support, and it's kind of a big deal
For about a decade now, Linux has been quietly migrating off a window display system designed in the 1980s. Most of that move has gone smoothly. But a stubborn handful of apps never quite seemed to make the jump: Spotify, Discord, Steam’s in-game overlay. They’d run, sort of, while feeling subtly broken in ways nobody could fully explain to a regular user. These issues would range from input lag, to focus breaking when you alt-tab, to HDR refusing to behave. This of course isn’t an exhaustive list, but it is meant to give you an idea.
The reason, it turned out, was the same for every one of them: they all lean on a single shared piece of graphics plumbing, and that one piece had never learned to talk to Wayland directly. So instead, everything fell back to an older compatibility layer, one that emulates a full legacy X11 session inside Wayland, and the inherent issues showed.
Just yesterday, somebody finally fixed the issue at the center of this all. And how it got there is the kind of small, fiddly software story I find genuinely interesting, so let me walk you through it.
First though, hello blog! This is my first post here. It’s a niche topic, but I enjoy writing about the little details of how things come together in software, and this is a good one. If you’re not deep in Linux world, don’t worry: I’ll explain the terms as we go, and you can look up anything that might be a bit unclear.
Now, let me explain what this story is about.
The status quo, and the problem
Quick context for anyone not deep in Linux world (and apologies to the people who are, feel free to skip ahead):
When you open an app, something has to take the pixels that app wants to draw and actually put them on your screen, route your mouse and keyboard input back to it, decide where the window goes, layer it above or below other windows, and so on. The rules for how that whole conversation between apps and the system works are called a display server protocol.
A few of these exist for Linux-based systems, but the two that matter for this story are:
- X11 (the “original” protocol; the implementation pretty much everyone runs is called X.Org): the old one. Designed in the 1980s, served well for decades, and is meant to be retired at this point.
- Wayland: the replacement. The Wayland project itself describes it as “a replacement for the X11 window system protocol and architecture.” Cleaner, faster, more secure, and designed to fix the things X11 got wrong, now with decades of hindsight to learn from.
The catch is that basically every Linux app spent decades assuming X11 was the standard, so switching is slow. That’s where this story is set.
Wayland has been “the future” for a while now. KDE, GNOME, pretty much every major desktop environment has pushed hard for it, and for the most part it works great. Native apps feel snappy, input handling is clean, compositors like Gamescope can do cool things with it.
(For non-Linux folks: a compositor is the program that takes the windows each app draws and combines them into the final image on your screen, while also handling input routing and effects. Gamescope is Valve’s tiny embedded compositor (the one used on the Steam Deck) that runs each game in its own private display. That lets Steam control resolution, framerate, and the overlay independently, and it handles HDR, which XWayland struggles with.)
But there’s always been this awkward group of apps that didn’t quite fit the Wayland ecosystem. Spotify. Discord. Steam’s in-game overlay (the whole thing, not just the browser part inside it). OBS’s browser source.
At best, they’d open and render but something would feel subtly off: input lag, focus weirdness, the overlay drawing wrong, that kind of thing. At worst, they straight-up wouldn’t work. OBS’s browser source is officially unsupported on Wayland Linux. Discord’s screen sharing was famously broken. Steam’s overlay had its own catalogue of issues. Spotify spent years as a janky XWayland blob before recently shipping native Wayland (and even that is still unreliable).
And the reason for the awkwardness is XWayland.
XWayland is a compatibility layer that lets X11 apps run inside a Wayland session. It’s not bad. It’s actually pretty brilliant as a gap-filler. But it’s a layer that has racked up a lot of complexity and bears the weight of trying to emulate an X11 that’s grown overly complex over the decades. Input events go through a different path, focus handling behaves differently, HDR doesn’t pass through cleanly, and you’re essentially running a mini X server inside your Wayland compositor. For most things it’s invisible, but for overlays and anything that needs to interact closely with the compositor, it breaks pretty badly.
The frustrating part is that these apps could have been native Wayland. The technology was there. Something in the graphics stack was just missing.
CEF, the web rendering engine inside “everything”
Here’s something most people who aren’t tech-savvy don’t know: Steam’s overlay, Spotify, OBS’s browser source, the Epic Games Launcher, Battle.net, Amazon Music, and a bunch of other apps all run on the same embedded browser engine under the hood. It’s called CEF, the Chromium Embedded Framework. It lets developers drop a basically-full Chromium into their app, without building a browser from scratch.
CEF is why Spotify can show you lyrics with smooth animations.
It’s why the Steam overlay works at all (the whole steamwebhelper process is CEF).
It’s in a lot of places, and most users would never know.
Now, CEF needs a graphics backend to actually render things. And that’s where ANGLE comes in!
ANGLE, the layer nobody talks about
ANGLE stands for Almost Native Graphics Layer Engine, and it’s a Google project. What it does is take OpenGL ES calls (the graphics API that web content and a lot of apps use) and translate them to whatever the platform actually supports. On Windows, that’s Direct3D 11 (with a Direct3D 9 fallback for older systems). On macOS and iOS, it’s Metal. On Linux, it’s Vulkan or desktop OpenGL. And on Android it’s Vulkan or GLES.
It’s the reason WebGL works everywhere: Chrome, Firefox, and Safari all route WebGL through ANGLE these days (Safari did it most recently, around Safari 15). It’s also the reason Chrome’s rendering is consistent across platforms.
CEF uses ANGLE as its rendering backend. So when CEF needs to draw something on screen, it goes through ANGLE.
And until yesterday, ANGLE had no native Wayland support at all. None.
The missing piece
ANGLE knew how to create windows on X11. It knew how to render via Vulkan, Direct3D, or Metal. There were partial Wayland type definitions floating around in some headers, but no working native Wayland window path. No way to create a surface, no way to connect to the compositor directly, nothing usable.
So when CEF ran on a Wayland session, it couldn’t use ANGLE’s native window creation path. It fell back to XWayland. Every single time, for every single app built on CEF. Some apps didn’t even try and just flat-out didn’t work on Wayland (OBS’s browser source, for example, is documented as unsupported on Wayland Linux).
Chromium browsers themselves were fine. Chrome and Chromium have their own platform abstraction layer called Ozone that handles Wayland directly, bypassing ANGLE for windowing. (Ozone is Chromium’s internal “swap-in” layer that lets the same browser code run on Wayland, X11, ChromeOS, or headless by hiding the platform-specific windowing details behind one interface. Ozone owns the surface and ANGLE draws into it.)
But anything that embeds CEF standalone, outside of a full Chrome build, was stuck.
There’s been a CEF issue tracking this in their Bitbucket tracker (the GitHub repo is just a mirror, and Bitbucket gates issue views behind a login, so I’m not linking the URL directly). Almost seven years.
January 2025, someone starts the work
A developer named Joel Winarske opened CL 6164683 against the ANGLE repository in early 2025. The title was simply “Wayland support”.
101 files changed.
New vendored copies of the Wayland client library, wayland-protocols, and expat (an XML parser needed by the Wayland scanner), all brought directly into ANGLE so there’s no external dependency to worry about.
New WaylandWindow and WindowSurfaceVkWayland classes implementing the actual surface and window lifecycle for Wayland.
(For non-techy folks: in plain English, ANGLE now bundles its own copy of everything it needs to talk to Wayland directly inside itself, so it doesn’t depend on whatever’s installed on the user’s system. Plus brand-new code to actually create and manage Wayland windows from scratch. Techy folks: yes, “vendoring” the deps means no external linkage required, which is the whole point.)
And then Joel went silent.
No updates, no responses to comments, nothing, after Patchset 3. The CL just sat there, the way these things do: a near-complete fix to a seven-year-old problem, parked, waiting for someone to care enough to pick it up.
After a few months of watching it not move, I left a comment asking if anything was blocking it from progressing.
Conveniently enough, a few weeks later it caught the attention of another developer, Dianda Lin. She picked up Joel’s dormant CL, answered the open comments, and started pushing the work forward in her own forked CL. Nice timing on my part, I guess. The code was Joel’s, and the heavy lifting of getting it past review was Dianda’s regardless.
(Side note: if you check the Gerrit author metadata, it still lists Joel as the author on the landed CL. She seems to have flubbed the authoring credit a few times during the pickup, which is why public trackers credit Joel for everything. But the real continuation work was hers.)
The review took over a year, counting from Joel’s original CL in January 2025. It went through multiple rounds of feedback from Google’s ANGLE team, with Yuly Novikov and Shahbaz Youssefi as the main reviewers. These things take time.
May 26, 2026, it lands
The commit landed in ANGLE’s main branch on May 26, 2026, as f0a91999.
Within a day it was rolled into Chromium’s main branch via the automated ANGLE roller, and it’s already in Chrome Canary builds as of today.
I actually verified this locally: built ANGLE from that exact commit with Wayland enabled, ran the simple_instancing sample, and xlsclients didn’t list it while it was running.
Steam, Discord, and steamwebhelper all showed up there because they’re still on XWayland.
The ANGLE sample didn’t, because it’s using the new WaylandWindow code directly.
In plainer terms: ANGLE created a native Wayland window, rendered to it with Vulkan, and put it on screen, all without touching XWayland. That’s exactly what the process check above confirmed.
It works.
What happens next
Although this is a huge milestone, it’s not the end of the road for CEF’s Wayland support.
As I mentioned, CEF embeds a Chromium rendering engine and relies on ANGLE for its graphics backend.
But ANGLE having it doesn’t automatically fix CEF.
CEF doesn’t pin ANGLE directly: it pins a specific Chromium revision (see CHROMIUM_BUILD_COMPATIBILITY.txt in CEF’s canonical Bitbucket repo), and Chromium in turn pins ANGLE.
So the chain is CEF => Chromium => ANGLE, and CEF will have to wait for a Chromium release that includes f0a91999 before they can pull it through, then wire up the new window creation path on their side.
Luckily, the CEF side itself shouldn’t be a huge amount of work. The new Wayland classes are clean additions, not refactors of existing code, so there shouldn’t be anything breaking.
The catch is everything that has to happen before CEF can even start. The ANGLE change first has to roll through Chromium and ride that into a stable Chrome release, and that’s the real unknown: it could be a few weeks or a couple of months depending on where it lands in the release train. Only once it’s in stable Chrome can the CEF maintainers bump their Chromium revision, test that nothing broke, and ship a new CEF release.
So while the CEF integration itself is probably a week or two of actual work, the whole thing realistically lands months out, not weeks. No major API changes expected.
The blocker is gone, but it’ll still take a while for users to feel the benefits. Even once CEF ships a release with the updated ANGLE, every app that embeds CEF has to update to that new CEF version before anyone sees the difference, and that propagation takes time too.
What it means
Once CEF picks this up and apps update to the new version, those apps should behave noticeably better on Wayland. For example:
Steam’s in-game overlay becomes a native Wayland client. That clears out a whole category of XWayland-caused problems in one go. I won’t go into all of them here, but notably it might also fix the cases where the overlay simply doesn’t show up at all.
On SteamOS and with Gamescope specifically, this is probably a small plus. Gamescope itself runs games through an embedded XWayland, so anything in the rendering path that can stay native Wayland instead of crossing into XWayland is one less source of indirection. The HDR path might also get simpler when you’re not crossing the XWayland boundary, though I’d hesitate to make a strong claim there without specific test data.
And more broadly, it means any app that embeds CEF (Spotify, OBS, the Steam overlay, and others) has a clear path to dropping XWayland for their rendering. Some will be faster than others to adapt. But the main blocker is gone.
Years of “waiting on ANGLE” end here. It’ll take a bit to trickle down, but it’s coming soon, to a CEF-based app near you.