Show HN: Wayland compositor in around 500 lines of annotated C
gist.github.com
gist.github.com
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!
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?
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...
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.
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.
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.
Ouch, that's pretty ugly — that would imply that if I'm running a tiling window manager I'll get stuck with window decorations I don't want. Surely that can't be right!
Maybe the idea is that desktop environments decorate windows containing their clients?
[0] https://cgit.freedesktop.org/wayland/wayland-protocols/tree/...
- the client and compositor need both implement this protocol extension
- the client needs to ask the compositor whether it should provide its window decorations
- the compositor needs to cooperate and tell the client that the decorations are server-side
Is that right?
I'm also puzzled by something else now: in Wayland, any access to absolute screen coordinates is considered a security risk. So how can a client provide windows decorations then? The main functionality there is moving the window around, which means setting a new absolute window position after a user interaction. How is this possible when the position is hidden away?
EDIT: if I had read the compositor source code before posing the question, I'd have known that the client merely provides the window decoration as a visual area, but not its behaviour. The move and resize behaviour itself including user interaction is part of the compositor.
Things get weirder and weirder. So clients are supposed to draw in controls, but compositors determine how they behave‽ What if a client draws a close button, but a compositor doesn't have any such concept? What if a client doesn't draw a close button: how does a compositor expose the ability to close the window?
Either this is poorly though-out (unlikely) or I'm really missing something (rather more likely).
It seems to fit that specific use pretty well, and there's a lot of things I like, but it's certainly got some catching up to do when it comes to the mix-and-match flexibility of the X-server/compositor/window manager/client stack.
We're slowly working on standardizing means of granting third-party software access to these protocols, but a cross-compositor mechanism has not yet been built. It is entirely possible for the compositor to only allow certain clients to use certain protocols, though. A mechanism like Android's "grant app this permission" popup, for example, might be possible. Today sway lets you configure different executables to receive different policies.
What possible relationship could this sentence have to the question of determining "if a process can take a screenshot or not?"
The correct answer for an ostensible improvement on X is that arbitrary processes should not be able to take screenshots, ever. If you start punting that question to the app users we're back in the land of Certificate-Error-Continue-Not-Recommended.
Even on this Chromebook I'm using, I'd shut it down immediately if Chrome legitimately popped up a request from a site asking for the permission to take screenshots.
Besides, most of the time on Gnu/Linux it's the buggiest processes for which I want screenshots to send to the developers. If no one in the Wayland community has a design that fits that use case please just leave screenshot functionality out altogether.
X is a free-for-all. X-eyes is cute but should not be possible.
At some point, a web application is going to want to take a screen-shot (webX anyone?). The web browser will then be given permission to take screen shots without user interaction, and then it's all over. Sharing ones screen is NOT a browser function, it's an OS function. Changing the way software developers see this is the correct path forward, but it's hard. Providing people the same functionality that X did will lead to the same problems that X has.
OK then! Hopefully this isn't too off topic.
How should I write an application that does smooth animation in Wayland? I'd like to have a main loop like this:
while (1) {
DrawStuffIntoAPrivateBitmap();
GiveBitmapToTheCompositor();
WaitUntilNextFrameNeeded();
// This loop should iterate at 60 Hz or whatever the monitor's frame rate is.
}
Does that seem like a reasonable approach? I've searched for this info before and got nowhere. Does Wayland even have a mechanism to allow the compositor to tell the application that it is time to draw another frame? If I give the compositor a bitmap every 60th of a second, to I get any guarantee it will display it at the right time?An application I have in mind is smooth scrolling in a text editor. I have a mild preference for doing the private bitmap update on the CPU rather than the graphics card for various reasons.
Yes, Wayland will tell you when it's time for another frame.
>If I give the compositor a bitmap every 60th of a second, to I get any guarantee it will display it at the right time?
Basically you should wait for the compositor to tell you when it's time to draw the next frame, diff it from the time you drew the last frame, and smoothly animate over the difference.
If you don't want to draw on the GPU, what you can do is allocate a pixel buffer with wl_shm (shared memory). Then the compositor will read from this and presumably upload it to the GPU (with wlroots the GPU is always used, but you can probably convince it to use blitting instead with a custom renderer).
Check out my intro to writing Wayland clients article:
https://drewdevault.com/2017/06/10/Introduction-to-Wayland.h...
A friend of mine (and core contributor to wlroots) has written a dead-simple example client you can check out as well:
Said another way, how soon can I expect that GTK and Qt/KDE frameworks will hide the close/maximize/windowize/minimize buttons and disable toolkit-provided dragging/resizing cues (and the whole bar, if the standard decoration is all that's there) when server side decorations are preferred?
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.
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... [1] https://github.com/swaywm/wlr-protocols/blob/master/unstable...
However as mentioned the Wayland code posted looked quite nice, and so did FreeRDP as I remember it, so I'll at least have a look and see if I can help.
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.
"Xpra is an open-source multi-platform persistent remote display server and client for forwarding applications and desktop screens.
It gives you remote access to individual applications or full desktops.
On X11, it is also known as screen for X11: it allows you to run programs, usually on a remote host, direct their display to your local machine, and then to disconnect from these programs and reconnect from the same or another machine, without losing any state.
It can also be used to forward full desktops, from X11 servers, MS Windows, or Mac OS X.
Xpra also allows forwarding of sound, clipboard and printing services.
Sessions can be accessed over SSH, or password protected over plain TCP sockets with or without SSL.
Xpra is usable over reasonably slow links and does its best to adapt to changing network bandwidth constraints."
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
† yes, Mir can now use the wayland protocol
[trigger warning: C++]
(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.)
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?
Hopefully your fears are sufficiently alleviated by that! I suspect you've got a mistaken idea about what Wayland actually is and what it does.
As for your 3rd paragraph, I'd have to leave that to someone more experienced than I am.
[0] http://swaywm.org/ [1] https://github.com/swaywm/wlroots [2] https://github.com/swaywm/wlroots/wiki
Is it possible to implement an interaction bound to a global hotkey (e.g. middle click) that takes the current selected text (in any window) and send it to the event target window as keypress events? Without special support from either program? [xselection pasting]
Can I monitor and/or intercept (block) input events of any program without special (voluntary) support from the monitored program? Can I send arbitrary synthetic input events? [hotkey macros]
Features that require opt-in support from the application don't count (it needs to work on proprietary programs and programs that use any toolkit (not just GTK/Qt).
I rely on these features, so I will be sticking with X11 if Wayland isn't compatible.
>Is it possible to implement an interaction bound to a global hotkey (e.g. middle click) that takes the current selected text (in any window) and send it to the event target window as keypress events? Without special support from either program? [xselection pasting]
Yes, doing it the way you described is possible. Or you could just use the existing and moderately-well-supported primary selection protocol:
https://github.com/swaywm/wlroots/blob/master/protocol/gtk-p...
We should try to get that standardized...
>Can I monitor and/or intercept (block) input events of any program without special (voluntary) support from the monitored program? Can I send arbitrary synthetic input events? [hotkey macros]
Sure, from the compositor. If you want clients to call the shots you need a protocol.
> Or you could just use the existing and moderately-well-supported primary selection protocol
Unless I'm missing something that requires support from both programs (or at the very least the program that you copy from).
thanks, your contributions to the community are invaluable! this looks like a pretty awesome way to learn wayland :)
So it seems that hacks like [0] are impossible here. Is this a limitation of protocol or just this compositor (and/or wlroots library)?
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
edit: can't reply to you because of all the downvotes
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.
[0] https://github.com/swaywm/wlroots/tree/master/types/xdg_shel... [1] https://github.com/swaywm/wlroots/tree/master/types/seat [2] https://github.com/swaywm/wlroots/tree/master/types/data_dev...
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.
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.
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.
tinywl is 500 lines of application logic + 40,000 lines of library logic; compared to your example which is two lines, but doesn't include the application logic, which I think makes it an apples-to-oranges comparison.
To clarify anyway - "tiling vs free-floating" is an application behaviour, "move window from (x1,y1) to (x2,y2)" is a library function; "focus follows mouse vs click-to-focus" is an application behaviour, "set_focus(window_id)" is a library function; "apps have icons vs apps have text labels" is an application behaviour, "render_icon()" and "render_text()" are library functions; etc.
As somebody who is interested in creating my own window manager, because none of the existing ones behave in the way that I want them to, I find the definition used by the author here to be very useful - the 500 lines are what I need to grok in order to build a WM which works in the way I want it to, and the 40,000 lines are what I can just call without needing to care about the internals. (To use parent's 2-line example as a counterexample - grokking those two lines is not sufficient to build the WM of my dreams)
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...
only 500 lines of code (plus 40k but whose counting)
https://cgit.freedesktop.org/xorg/xserver/
~500,000 lines of code that wlroots does not depend on, but who's counting.
It's not really rude but rather a pointer that the argument made is not standing on very solid legs.
https://cgit.freedesktop.org/xorg/
Most modern xorg drivers depend heavily on mesa to do the heavy lifting:
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.
- 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.
https://github.com/swaywm/wlr-protocols/blob/master/unstable...
https://github.com/swaywm/wlr-protocols/blob/master/unstable...
There are several more protocols we have written and are working on to address similar concerns: 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.
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...
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.
Not when apps will exclusively choose to support it.
$ vim ~/.config/user-dirs.dirsApple? The iTunes concept proved to be popular with users.