
Show HN: Wayland compositor in around 500 lines of annotated C - ddevault
https://gist.github.com/SirCmpwn/ae4d1cdcca97ffeb2c35f0878d75dc17
======
Sir_Cmpwn
I saw this discussion yesterday:

[https://news.ycombinator.com/item?id=17765446](https://news.ycombinator.com/item?id=17765446)

And thought I'd whip up something for Wayland, too. Happy to answer questions
about Wayland if anyone has some!

~~~
mrweasel
I read the blog posts you linked to yesterday, regarding wlroot and
understanding how Wayland works. They help a lot in understand what Wayland is
and how it work. It's really well written, thanks.

There's just one thing that's still a little weird. You show with Wayland
McWayface how you can start clients, and use gnome-terminal in the example.
The Gnome terminal shows up with window decorations, and as I understand it,
that's because Wayland encourage (require?) the client to provide those
decorations.

If the client provides the windows decoration, then that sort of eliminates
what most of us would define as a Windows Manager, at least for the very
simple ones. So it seems like you could write a GTK application for instance,
say a desktop like the old Windows 3.11, theme it and then just start it with
a random compositor.

I guess the question really is, could you write a general compositor, which
just handle inputs and output, and then use that compositor to run any number
of different desktop environments where the authors technically doesn't need
to worry about Wayland?

~~~
Sir_Cmpwn
>I guess the question really is, could you write a general compositor, which
just handle inputs and output, and then use that compositor to run any number
of different desktop environments where the authors technically doesn't need
to worry about Wayland?

This is a goal we're working towards in the wlroots camp. You could do this,
but the issue would be running a lot of the things that tend to define the
desktop environment, such as the panel, menus, desktop feel, etc. In order to
support that, we need a Wayland protocol that lets clients have some say in
where they are displayed on-screen, such as a taskbar wanting to be shown
across the bottom. For wlroots we made such a protocol[0], and it is slowly
being adopted across the ecosystem. Porting DEs to use it would be a great way
to help improve Wayland :)

[0] [https://github.com/swaywm/wlr-
protocols/blob/master/unstable...](https://github.com/swaywm/wlr-
protocols/blob/master/unstable/wlr-layer-shell-unstable-v1.xml)

~~~
phkahler
>> You could do this, but the issue would be running a lot of the things that
tend to define the desktop environment, such as the panel, menus, desktop
feel, etc. In order to support that, we need a Wayland protocol that lets
clients have some say in where they are displayed on-screen, such as a taskbar
wanting to be shown across the bottom.

Isn't that the job of something higher level? I thought the wayland compositor
would implement some desktop environment functionality. In other words the
compositor itself would also define the DE by starting a panel and placing it
at the top/bottom/side and by starting and placing any other items/processes
that are part of that environment. I understand that this would add complexity
to the compositor but isn't that where it really belongs? I still feel like
it's a security concern for general processes to know much about the
environment they are running in. OTOH I want to start several things at login
and have the ability to place the windows from a script (like .login and
passing window geometry to X). These are interesting issues and I hope the
people making the decisions are keeping things both secure and simple in the
software.

BTW, I'm hoping for animated wallpaper on my desktop. This is a low priority,
but would that be an application that runs in root window, or would that be
something the compositor knows to start an places it there? IMHO that's so
special it's more of a compositor feature, but who knows... Should there be
added protocols to do these things or just make a special compositor feature?
I'm in favor of having it a compositor feature rather than increasing
complexity of a protocol - I think it's less complex.

~~~
Sir_Cmpwn
> I thought the wayland compositor would implement some desktop environment
> functionality. In other words the compositor itself would also define the DE
> by starting a panel and placing it at the top/bottom/side and by starting
> and placing any other items/processes that are part of that environment

It can, that's how GNOME works today. It's not how it generally works on X,
though, and it's not very modular.

As far as security is concerned, our layer shell protocol assumes that the
client is trusted. We're working on ways of securely allowing third-parties to
access this, but it's possible today to start implementing layer shell and
restrict its use to trusted clients.

>BTW, I'm hoping for animated wallpaper on my desktop

This is possible with the layer shell protocol I'm talking about.

~~~
phkahler
>> It can, that's how GNOME works today. It's not how it generally works on X,
though, and it's not very modular.

We don't need modular.

>>>BTW, I'm hoping for animated wallpaper on my desktop

>> This is possible with the layer shell protocol I'm talking about.

It's also possible by building the feature into the compositor. No new
protocols or possible security issues needed. Simpler is better in most cases.

~~~
Sir_Cmpwn
I don't think that makes it simpler. I think that just makes a massive
compositor which tries to please everyone and ends up pleasing no one, and
being 10x the size it needs to be.

~~~
phkahler
Ultimately the compositor IS the desktop environment. You can try all you want
to keep it simple and enable functionality via other apps using a protocol,
but that's essentially a complicated way of making plug-ins to the compositor.
You will end up delegating security to everyone else.

~~~
Sir_Cmpwn
That's not true. It's true for GNOME, and I guess Enlightenment, but they are
not the only players. If you think there are legitimate security concerns with
our approach then I'm open to hearing them but so far as I'm concerned so far
you haven't said anything of value.

------
magicalhippo
Been hoping Wayland would help improve the sad state of remote desktop on
Linux but from what I can see I'll have to way another 5+ years for something
useful :(

I've installed KDE Neon on a NUC to play around with and I really like it a
lot. But the lack of proper RDP server support is the primary thing keeping
Windows on my primary machines.

Key features required:

\- Ability to resume local session from remote client and later locally again.

\- Ability to start session from remote client if no local session exist, and
later resume it locally.

\- Performance (framebuffer-delta ala VNC is no-go).

\- Functional clipboard, so I can copy/paste between client and host. Text
required, though images and files would be nice.

Anyway, really nice piece of code. Sure it's 500 lines but it seems quite
straight forward.

~~~
Sir_Cmpwn
We haven't forgotten about you, but we could use your help if you want it done
fast. We've made some important progress towards supporting this functionality
recently. A protocol our people have been working on is currently undergoing
standardization[0] which enables software keyboard devices. A similar protocol
could enable software pointer devices. We also made another[1] protocol for
efficiently capturing the contents of the display.

Plug all of these together and an RDP server is probably possible. Maybe a few
weeks of work with FreeRDP for the motivated programmer. My email is in my
profile, reach out if you want to make some connections and get started.

[0] [https://lists.freedesktop.org/archives/wayland-
devel/2018-Au...](https://lists.freedesktop.org/archives/wayland-
devel/2018-August/039237.html) [1] [https://github.com/swaywm/wlr-
protocols/blob/master/unstable...](https://github.com/swaywm/wlr-
protocols/blob/master/unstable/wlr-export-dmabuf-unstable-v1.xml)

~~~
codedokode
Another issue with remote desktop (using VNC) on Linux is keyboard layouts
(for inputting non-latin characters). With X server, the server passes a
physical key number (keycode) and modifiers state (whether keys like Shift or
Caps Lock are active) to the client and the client converts it to the
corresponging character (keysym) using translation tables loaded earlier from
the X server.

When you are accessing another computer remotely using protocols like VNC the
local computer's keyboard layout can be different and it can produce
characters not present in remote computer's translation tables. The VNC
protocol itself transmits keysyms, not keycodes. So there can be a situation
when there is no matching physical key number (keycode) for given character.
So VNC servers like x11vnc had to modify translation tables on the fly and
insert non-existing key into the tables and pass that key's number to X
clients.

I wonder if this problem is solved with Wayland. As I understand, Wayland uses
similar scheme and the compositor sends only a physical key number (keycode)
along with the modifiers to the client and the latter does the translation. By
the way, would not it be easier if the compositor did the translation itself?

The hack I described can also cause issues with hot keys. If I run application
locally and it has a hotkey like Ctrl + S, and my keyboard has two layouts
(English and Russian) then it will probably work with both of them because the
application can bind the hotkey to physical key number. But when we send key
presses remotely over VNC we send only a keysym (a letter code), not a
keycode. If the remote server doesn't have Russian layout it is unable to
guess what physical key was pressed and cannot recognize that I pressed Ctrl +
S in Russian layout.

------
tomcam
This code is so well-commented that it makes me want to do some graphics
programming – and I haven’t needed to do any graphics programming other than
HTML canvas in 30 years. What a fantastic contribution. Thank you.

~~~
Sir_Cmpwn
Any of these projects could use your help :)

[https://github.com/swaywm/wlroots](https://github.com/swaywm/wlroots)

[https://github.com/swaywm/wlroots/wiki](https://github.com/swaywm/wlroots/wiki)

------
gnomewascool
This is very valuable educationally! Thanks!

A slightly less minimal, but still small — 2000 lines total among all files —
DE, leveraging Mir†, rather than wlroots, is here:

[https://github.com/AlanGriffiths/egmde](https://github.com/AlanGriffiths/egmde)

† yes, Mir can now use the wayland protocol

[trigger warning: C++]

~~~
Sammi
I'm confused. Wasn't Mir supposed to be an alternative to Wayland?

~~~
gnomewascool
There was Mir the protocol and Mir the library/codebase implementing the
protocol. Since the Mir protocol and Wayland weren't _that_ different — after
all both were intended as replacements for X — it didn't take much effort to
adapt the Mir library to use the Wayland protocol.

(As for why Canonical thought that developing their own protocol was a good
idea, I'm not sure, but based on what I remember reading about it from various
sources — don't have links on hand, so take the following with a pinch of
salt:

1\. They, rightly or wrongly, thought that some bad decisions were made with
Wayland

2\. They preferred to have control over the protocol to be able to experiment
/ make quick adjustments based on their needs, and the experience they gained
while using it in Unity8 (the main DE using the Mir library).

3\. They were aware that porting the Mir library to use Wayland, if/once this
was decided valuable, would not be difficult (as turned out to be the case).

From a technical point of view, IMO it wasn't a completely terrible decision,
but from a PR one it was.)

~~~
eximius
If they had used Mir as a test bed like Chalk is for Rust, it might have made
sense.

------
simias
I haven't really followed Wayland very closely but as a huge fan of tiling WMs
(I've used StumpWM for more than a decade, although I switched to dwm lately)
I've been a bit worried by the claims that Wayland doesn't have a window
manager per se etc... Although I admit that's mainly because I haven't taken
the time to understand what Wayland is exactly.

Just in order to aleviate my fears, can somebody tell me if in this brave new
world it'll still be possible to effectively implement something like DWM or
some other tiling WM "within" Wayland? Are there pitfalls I should be aware
of?

I suppose there's got to be a way to do custom tiling, but I worry that there
might be other less obvious limitations. For instance every time I attempted
to use custom "window manager" on Windows (to add virtual workspaces for
instance) I quickly noticed that it didn't work very well. One problem was
that the window management was cooperative instead of preemptive: when the
"window manager" attempted to hide a window it'd basically send a message to
the application requesting that the window be minimized. If the app was frozen
or simply uncooperative it'd remain where it was. Could that happen in
Wayland?

~~~
PaulHoule
Wayland works the way that Windows has since Windows Vista.

~~~
yjftsjthsd-h
...is this an endorsement or a downside?

~~~
PaulHoule
just a fact.

------
amarant
you actually went and did it! not that I doubted it ;)

thanks, your contributions to the community are invaluable! this looks like a
pretty awesome way to learn wayland :)

------
vthriller
> seat, <…> conceptually includes up to one keyboard, pointer, touch, and
> drawing tablet device.

So it seems that hacks like [0] are impossible here. Is this a limitation of
protocol or just this compositor (and/or wlroots library)?

[0]
[https://news.ycombinator.com/item?id=17760255](https://news.ycombinator.com/item?id=17760255)

~~~
Sir_Cmpwn
No, a very similar setup is possible depending on the compositor. wlroots
enables this. The Wayland protocol only exposes up to one keyboard per seat to
the client, but wlroots lets you pass input to seats in any manner you choose.
In sway you can have multiple keyboards with multiple layouts and we swap them
out whenever you start typing on a different keyboard.

------
aleksis
Without wlroots it would need several times more loc.

~~~
Shish2k
Not to mention if you didn't use libc - and think of how many loc it'd need if
you wanted to implement the kernel and userspace tools too!

Thankfully, we live in a world where libraries exist and we can use them to
handle the low-level details, and then we only need to care about the 500
lines of meaningful application-specific logic :D

~~~
rain1
totally missing the point

edit: can't reply to you because of all the downvotes

~~~
Shish2k
So explain the point? In several threads recently I've seen people say "The
application's line count is higher if you also count the libraries as part of
the application!" \- I mean yeah, sure, that's a factually correct statement,
but... so what?

~~~
evmar
The point is that this app is 500 lines of C but it'd be two lines of Python:

    
    
        from wayland import solution_to_the_problem
        solution_to_the_problem()
    

In this case, wlroots is literally a library for writing a compositor.

("A small demonstration of the wlroots API" would have been a fine title for
this post. Pretending it's a small amount of code is silly.)

"I made a tiny webserver using only the Linux kernel" is impressive. "I made a
tiny webserver using only the Golang webserver API" is not as impressive. "I
made a tiny social networking website using the Golang webserver API" is
heading back towards impressive.

~~~
Sir_Cmpwn
You don't have to be impressed, but I don't necessarily think it's
disingenuous. A "small" Wayland compositor which doesn't use a library like
wlroots is nigh impossible. The code for handling DRM+KMS alone is over 2000
lines of code, and that's tangental to the goal of "make a Wayland
compositor". I'd compare it to saying a game written with GLFW isn't
impressive because they didn't do all of the work to set up an application
window.

~~~
juliangoldsmith
For a toy compositor, is there any reason not to just use SDL? The DRM and KMS
side of things is interesting, but doesn't help much in understanding the
Wayland protocol.

~~~
Sir_Cmpwn
You certainly could make a compositor with SDL, but I don't think it would be
any better than wlroots. We also provide an abstraction of the underlying
window system, the same code which runs your compositor in an X11 window can
also run it on KMS+DRM without any changes (the compositor in this very link
can run on X11, Wayland, and DRM+KMS with no changes). It also gives you a
number of useful things like an implementation[0] of xdg-shell, which alone
can be a couple thousand lines long. Also, negotiating graphics resources with
clients is going to require you to get into the gritty OpenGL details if you
intend to be efficient (and some clients don't even support shared memory, so
it's also a matter of compatability). You'd also need to implement the seat to
have input support, which can be another ~1,000 lines of code. GTK+ requires
the data device to be implemented as well - over 1,000 more lines of code in
wlroots[2].

[0]
[https://github.com/swaywm/wlroots/tree/master/types/xdg_shel...](https://github.com/swaywm/wlroots/tree/master/types/xdg_shell)
[1]
[https://github.com/swaywm/wlroots/tree/master/types/seat](https://github.com/swaywm/wlroots/tree/master/types/seat)
[2]
[https://github.com/swaywm/wlroots/tree/master/types/data_dev...](https://github.com/swaywm/wlroots/tree/master/types/data_device)

That being said, a simple compositor which only supports a subset of this
stuff, uses SDL for rendering, doesn't support a lot of important features
(like GTK+ dropdowns and context menus), and directly implements the Wayland
protocols, could probably be done in one or two thoundand lines of code. In
order to be equivalent in functionality to the TinyWL compositor I posted
today, it would probably need to approach 5-6,000 lines.

~~~
juliangoldsmith
>That being said, a simple compositor which only supports a subset of this
stuff, uses SDL for rendering, doesn't support a lot of important features
[...], and directly implements the Wayland protocols, could probably be done
in one or two thoundand lines of code.

That's what I'm interested in. wlroots hides pretty much all of the details
about what's going on. This would be more about producing an example than an
actual functional compositor. My next Rust project, maybe. Or even C#, for
that matter.

~~~
Sir_Cmpwn
If you're producing an actual functioning compositor you should be using
wlroots anyway. It's unopinionated, we call it "40,000 lines of code you were
going to write anyway". It's not practical to make a compositor without
leveraging wlroots unless you have a huge team like GNOME or KDE - this is
advice from several compositors who tried and are now using wlroots.

Still, if you insist on making _everything_ yourself, the wlroots code is
pretty accessible and I've heard from people working on KDE and Mir that it's
the best reference code to study for understanding how everything works and
applying it to their own software.

[https://github.com/swaywm/wlroots](https://github.com/swaywm/wlroots)

------
codedokode
Please note that it is not written from scratch and is using a wlroots library
that does most of the job. Most of the code are just the handlers for events
emitted by the library. You cannot write a Wayland compositor and implement
all required interfaces with just 500 lines.

------
Shorel
My question would be: given that current Wayland implementation kills all my
windows when an error happens, in contrast with X11 where the session is
killed but the windows are kept; what is the behavior of this compositor
regarding errors?

~~~
Sir_Cmpwn
Same, a crash will kill all of your applications. But that's also what happens
when xorg-server crashes. The difference is that window management is usually
handled in a separate process, and if that process crashes you don't lose the
windows themselves. xorg-server is generally stable enough so long as your
graphics drivers are stable and you don't do anything weird. It'll take time
for Wayland compositors to become similarly mature.

There has been some discussion around making Wayland compositors that behave
similarly, and on crash reslience with a Wayland-specific design as well,
notably:

[https://arcan-fe.com/2017/12/24/crash-resilient-wayland-
comp...](https://arcan-fe.com/2017/12/24/crash-resilient-wayland-compositing/)

------
kazinator
For values of 500 exceeding 900, this is about 500 lines.

~~~
sp332
It says 500 lines _of C_.

~~~
kazinator
Ah, OK. 500 lines of C, which are (further) annotated.

~~~
rain1
600

------
rain1
How do I use this on arch linux?

~~~
rain1
lol you need this which is 40k lines of code
[https://github.com/swaywm/wlroots.git](https://github.com/swaywm/wlroots.git)

only 500 lines of code (plus 40k but whose counting)

~~~
Sir_Cmpwn
TinyWM also needs all of this code:

[https://cgit.freedesktop.org/xorg/xserver/](https://cgit.freedesktop.org/xorg/xserver/)

~500,000 lines of code that wlroots does not depend on, but who's counting.

~~~
upofadown
The reasonable comparison would be with xlib. The xserver code is all about
the hardware drivers.

~~~
Sir_Cmpwn
Actually, the repository I linked to does not do much more driver stuff than
wlroots does. The xorg drivers are maintained in separate trees:

[https://cgit.freedesktop.org/xorg/](https://cgit.freedesktop.org/xorg/)

Most modern xorg drivers depend heavily on mesa to do the heavy lifting:

[https://cgit.freedesktop.org/mesa](https://cgit.freedesktop.org/mesa)

wlroots depends on mesa as well.

xorg-server _does_ do more things than wlroots, but it's mostly legacy stuff.
In terms of features anyone wants from a modern display server, they're pretty
close. wlroots is repsonsible for spinning up an EGL context, talking to
libinput, configuring DRM and KMS display resources, allocating GPU resources
with GBM, negotiating pixel buffers with clients, etc, all things that xorg-
server is doing for TinyWM.

------
chris111
If Wayland is the "Linux desktop" then all the advantages are gone. You do
know that Wayland's design effectively destroys any choice and customization
right? Wayland's protocol is basically an isolation prison that requires "big
DE's" and destroys choice. The protocol moves everything into one central
place called the "compositor" this machinery must provide:

\- the window manager \- the hotkey daemon -the compositing effects -the
windowing server -screen reading tools -screenshots -screen casting
-magnifying glass tools -global dictionary tools -etc etc etc everything.

Wayland's design makes it impossible to write a portable hotkey daemon for
instance. Supposedly for "security reasons". Wayland is a GNOME dev's dream,
it kills the ability of people to control their own system. If you're actually
excited for Wayland you either thoroughly misunderstand what it brings and
just like it because it's new or you're a drooling GNOME-lover who hates
customization.

~~~
Sir_Cmpwn
This is FUD. One of wlroots core goals from day one has been to promote the
standardization of cross-desktop protocols that allow for these features. We
have already addressed two of the points you brought up, namely screenshots
and screen casting, via these protocols:

[https://github.com/swaywm/wlr-
protocols/blob/master/unstable...](https://github.com/swaywm/wlr-
protocols/blob/master/unstable/wlr-screencopy-unstable-v1.xml)

[https://github.com/swaywm/wlr-
protocols/blob/master/unstable...](https://github.com/swaywm/wlr-
protocols/blob/master/unstable/wlr-export-dmabuf-unstable-v1.xml)

There are several more protocols we have written and are working on to address
similar concerns: [https://github.com/swaywm/wlr-
protocols/issues](https://github.com/swaywm/wlr-protocols/issues)

3 delegates from wlroots, including myself, who together represent 8 distinct
Wayland compositors, are joining 3 delegates from KDE at XDC 2018 to discuss
the standardization of these protocols and propose them for integration across
the whole ecosystem.

~~~
chris111
After 9 years there is not even anything close to a universal standard and
discussion across compositors has just started this year. That's embarrassing.

~~~
Sir_Cmpwn
There's already been universal standards under discussion for a long time, for
example xdg-shell for application windows. The recent discussions are
attempting to make _more_ standards, and has been going on for 2 or 3 years
now. This is a lot of work, we're replacing the X11 stack which has a legacy
going back over 20 years.

~~~
chris111
>xdg-shell for application windows.

Which is implemented by literally who? I can see a GNOME mutter commit but
can't find anyone else from a few minutes of googling.

Also: "As of June 2014, XDG-Shell protocol was not versioned and still prone
to changes. "[1]

Who else loves to build software atop unstable APIs?

>The recent discussions are attempting to make more standards, and has been
going on for 2 or 3 years now.

These should've been going on since the begin, really makes you think what
kind of intent the Wayland founders had. Wayland is being pushed as the future
and there still isn't even a way to have a universal fucking screenshotter, I
guess it's a security feature to be locked out of your own desktop, right?

1:
[https://en.wikipedia.org/wiki/Wayland_(display_server_protoc...](https://en.wikipedia.org/wiki/Wayland_\(display_server_protocol\)#XDG-
Shell_protocol)

~~~
Sir_Cmpwn
>[xdg-shell] is implemented by literally who?

Uh... everyone. Mutter, Kwin, qwayland, wlroots, wlc, Sway, waymonad, Way
Cooler, Weston, Enlightenment, and Mir all support it, as well as clients like
GTK+, Qt, GLFW, SDL, EFL...

Look, you don't have to use Wayland. No one has said it's done, and Xorg still
works fine. If it doesn't support everything you need, then it's not for you,
no big deal.

~~~
chris111
>No one has said it's done, and Xorg still works fine.

Not when apps will exclusively choose to support it.

~~~
Sir_Cmpwn
Well, woe is you then.

