 The next talk is properly braven. It mentions valent and it's going to be given by a man who needs no introduction because you've been watching his mug for the whole day long in the afternoon session as the session chair. So go on, David. Thank you. As I've even said, my name is David Edmondson. I've been a KDE there for over 15 years, Plasma Dev for six or seven of them, and I've been a Wayland Dev for what seems like forever. So about this talk, what do I want to do to make it different from all the other talks? When we talk about Wayland, there's always a lot of focus on the window manager or your shells because that's where a lot of the development work needs to happen. But we tend to neglect the applications, which still have quite a lot to do. So for the duration of this talk, we're not going to make any mention of Plasma. We're not going to make it many mention of Quinn. There'll be no more mention of any other desktops, or a multi-name of any other compositor. Those are good jokes. Don't try to sway me otherwise. And we're going to focus purely on applications and Wayland, of course. So as an application developer, why do you need to care about Wayland? Well, it's one of the biggest transitions we faced as a Linux desktop. There's a lot of changes in a very, very core fundamental area that all of the applications are yet to happen. So I've got two sets of slides to this. I've been covered in one and a more carrot and stick approach. So Wayland does have a load of really cool features that you can use as an application developer. You get far more detailed input events in lots of different nuances that make the input so much better than what we had on X11, even with XI2. We have considerably faster rendering. It's a lot less happening to get from you making a change in your application to arriving on the screen, get faster frame rates, reduce power consumption. Firefox is doing some incredibly exciting things in the upcoming releases where when a user scrolls, all it does is redraw a scroll bar and then sends some magic metadata to your composite to do all the other work. It can do some very clever things. All around is going to be amazing. But if you are a calculator app, if you're writing KCalc, realistically, I'm not going to lie, none of this is going to matter. It's not going to be anything in Wayland that makes your application much better. If it's a boring app, no offense to KCalc. If it's a boring app, it's a boring app. It doesn't really gain a lot. But there is another side to Wayland's trade. A more negative way of encouraging people to care about Wayland. You don't have a choice. Or certainly you won't have a choice. Right now, we're not on Wayland by default. And for those that are, they're still at backwards compatibility level of X Wayland, where X clients can still run. But there's a few things to know. X Wayland, which is where a Wayland composite still supports backwards compatibility, it's not an exact one-to-one match, partly deliberately for security reasons. You still can't just sniff data from other applications. It's not quite the same as being an extra application on X. And there's other nuances such as scaling where things behave slightly differently. We're also finding that there's several places where people are switching to Wayland by default. Even if we're not in Plasma, known as switching a lot of places, there are people running Wayland composites which don't have any X Wayland support. And as people try and phase out X for their systems, at some point, we are going to see desktops where X Wayland isn't an option. So at some point, you're going to have to care. And this is a genuine code snippet from a KDE application. I won't say what. I'm not sure if you can read it, but the code says, if a platform was Wayland, show a message box and quit. And I can understand why I've done that is to try and encourage people to use X Wayland where right now our performance is better. It might get a better user experience, particularly as it happens to crash anyway on Wayland. So I can see why you want to encourage users. That makes sense. But this code snippet is also blocking any developer from even trying. And at some point, you're going to find yourselves five years down the line, certainly forced into running on Wayland. And then you'll be surprised when your functionality is missing and then users are going to be forced into a bad situation. It's important that we start early and all the developers should be doing things on Wayland and at least supporting and elevating any issues they have and making a big fuss if something is missing. So when it comes to this code, I'm not angry, but I am disappointed. What's the current state of a Qt application if you run on Wayland? Because in theory, Qt abstracts everything. So it should just work, just like Qt on Windows. Well, the difference between theory and practice is in theory they're both the same thing. In practice, there are some nuances. And that Qt example is quite good. In theory it should work, but if you look through Qt repo, you can see it's Christoph Coleman making a bunch of changes which are window specific because things were found even though the Qt library and Qt framework should have abstracted it. It's also interesting to note it's the developers making those changes. Steve Baum is not making those changes. Microsoft is not doing the work. He's sitting about in a massive mansion. And that's true for your Wayland port. It's very similar to porting to Windows as a whole new platform. And you can't expect all your Wayland developers to do your work. I'll be lounging about in a massive mansion. So, let's say you try your app on Wayland and there's a bug. Who is that for? There's actually a couple of different answers because there's lots of components in play. There are deliberate Wayland behavioral differences where we're not trying to make things behave exactly as they are on X and it will require applications to adjust. There are also potentially you've got bugs in your application just because something happened to work on X11 and we should be abstracting it, we might be surfacing some bugs that already exist. We also have a completely new plug-in part that we're going through in Qt. It's a very different code path. So, we might find we're hitting some bugs in Qt Wayland and Qt Wayland is a lot of code and it may have bugged on it. It could be bugs in the compositor. And generally, this is your first place to get blame but for most things that are happening inside a typical standard Qt application, it's not where a bug is going to be. It might be but it shouldn't be your only point of complaint. You might also find we're missing specifications. Wayland is behaviorally different from X11. Some things behave differently and often something that could have been done in X through a hack we're trying to do in neat, very somatic ways in Wayland but because of that we need to come up with a new somatic way for each of these individual use cases so you may find a specification's missing and then we'll have to go all the way to upstream because it's important that we get things standardized so that even when we fix our application it doesn't just work on KDE but it also works on these other desktops. Let's go over some of the deliberate Wayland behavior differences and I'm sure you may have heard all of these already. You cannot make a libx11 call as a Wayland client. This probably goes without saying but it does happen. We see code paths where we hit it. It won't be the easiest thing to search for. If you're doing something with Qx11 or Qx11 extra display or connection it's obviously going to fail. In general, most cases where we hit that we have found that an abstraction layer has already been written in frameworks. I'm not going to say that's true for everything you could possibly do but in general we're trying in KDE to introduce these abstraction layers and obviously Qt is an abstraction layer. Another big behavioral differences is you can't eavesdrop events. Wayland clients only get input when they have focus. So if you don't have focus and you want to find out when a user clicks a mouse or presses shift X, Q, you can't. You don't have those events and this is important to mention this also happens if you're running inside X-Rayland. So if you're doing your own by hand idle detection or your own by hand global shortcuts it's not going to work by design but if you use abstraction layers K idle time and K global Excel it'll just work out the box. It'll just continue to work exactly as before which is amazing. You can't grab other window content and this is deliberate. If you call Q window grab window it will just return an empty image. The best thing to do is replace it with a debus request to XG desktop portal and this is true if you want to find out the color of an individual pixel for like one of those color drop icons. One thing we're seeing with Wayland is not everything that was done in X11 has a direct equivalent in Wayland. There is a direct equivalent but it's not necessarily just because of the next X11 which happened to be the display communication. We don't have to do it in a display communication way of porting to Wayland. Sometimes we're doing things using other technology and other things out of bounds. And if you want video content I forgot to mention this. If you want video content you want to use pipe wire and it's code and plasma doing that already. One of the bigger changes that probably is more likely to affect you for a common app, global positioning. Wayland windows don't know where they are and they can't set where they are using as rain shells that we have. And this is probably one of the biggest porting challenges but there are a couple of options that are available and supported. The most important one is a framework called XG positioner which is where we semantically state where a pop-up should be relative to your parent window. So you would have this if you have a window and you want to open a context menu or a little tool tip or a combo box where you drop down a list of options. All of those are new windows and we're saying where that window pop-up should open relative to your window that we already have. Now one challenge with that, one behavioral difference is if you open something without global positions a client can't do detection of whether we're going to hit a screen edge or not. So if you have a combo box with a really long list and your window is quite near bottom of the screen and it's combo box of near bottom of the screen, you don't want it to overflow off the screen because that's rubbish. And on X11 you would typically do some of that code yourself or sometimes the window manager would just shove it on top of on top of your combo box, it would just shove it randomly. But with XCG positioner, which is really quite clever, you can provide hints on how to handle a constrained situation. So in this example of this combo box that doesn't fit beneath you can say, well, I want the contents to be above where my combo box is and not just include it. Or you can even say, I want everything to be shifted to your right to avoiding a combo box this way. Also resize a window and you can tell it how you would like it to be handled and then the compositor does the right thing. So it's a very, very well-designed class but acute implementation is kind of weak. You're using this framework implicitly whenever you create a QMenu, QContext box or QComba box or a little tooltip. But what Qt is doing internally to match existing internal API is just mapping everything to a global coordinate and then mapping everything back into a relative position. And then we'd not expose in all of these clever APIs that exist in the framework. One of the other projects called it exists is Plasma Shell which is what we're using for all the panels and some other custom parts within Plasma. And here is a sneaky sort of add-on API that we've added specifically four panels and things where you can set an exact position in global coordinates. And if you look at the code for Plasma panels you'll see this. And the downside of this is it's not universally supported. In fact, we're even trying to restrict access within KDE applications. The implementation was done quite early on in our way of development and in hindsight it's quite poor particularly with other changes and overall we're trying to phase it out. But you might see this class listed. And last but not least one of the new things that are popping up in a scene Layer Shell, which is where we semantically position something on a screen. So if you're familiar with QML anchors this is basically the same but for whole windows. We can say I want my window to be anchored to your right and I want to be anchored to your left and the top and 200 pixels tall and it'll be at the top 200 pixels tall. And you've got margins and such. Exactly like QML anchors. And we've used this already inside Case Blush and we've made an entire library available where we expose every feature that's relevant inside Layer Shell all of these margins and different offsets. And this is somewhat standardized protocol that works outside KDE. One big con with the current implementation that will be fixed out that's just a technical hitch temporarily is you can't have Layer Shell and regular windows in the same application. Once you've committed to using that Layer Shell library you then have to use that Layer Shell library for every other window which means every other window needs to be semantically positioned to a screen which doesn't make sense for some situations. So what's the other differences we see in Wayland? It's quite strict in terms of protocol on what you can do. One thing just to enforce that your application is doing things correctly. So pop-ups are one example. So for every time you have a pop-up you must have a parent and if you have a pop-up that creates a pop-up you must do this in the right order. You must create a pop-up that depends on the pop-up after the first pop-up which is natural. But it's also important from a Wayland protocol perspective to destroy things in the correct order. You can't open a pop-up and then a pop-up from it and then close the original. Doing so is Wayland considered illegal. It's akin to murder. It's one of the 10 commandments don't murder, don't create or destroy a pop-up in the wrong order. And cute Wayland tries to hide these problems but it's having to sort of retroactively guess what your client should be doing. So anything that is moderately sane is supported inside a Wayland protocol. But if you've got something very quirky inside your code it can just cause everything to just be closed or your pop-ups to be closed in the wrong place. So here's an example of what I mean with multiple pop-ups. In this case it's important that we close this right most pop-up first and then the middle one and then the left one. If you do anything wrong initially your application would be terminated but cute Wayland tries to hide or solve that but if it tries to solve it you'll just get a situation which just doesn't work. Which is slightly better than crashing but not by much. Window activation. So what do I mean by window activation? That's where we're passing focus from one window to another. So I'm in my chat application. I click on a link and open a browser. I expect a browser to suddenly appear in a foreground even if your browser is already open with some other content inside. Or you're in Dolphin, you've got your list of files. You click on a PDF of this presentation. You expect your PDF viewer to come to your front even if your PDF viewer is active. All the story I'm from Assistantry. When you click on a set of notifiers and for telegram you want telegram to appear. Makes sense. So I'm going to do a quick reminder of how this should be done on X11 and what you should be doing right now. So you should be creating this magical string. You're getting a user time or using case data of info and then we pass this out of bounds over the bus message that we're sending anyway or over an environment variable if we're creating a new process. And then if a season client should import this and then use QX11 extras set user input time use case data startup info to import this magical token which does everything internally. And only then do we call request activate. So that's what you should be doing now. What everybody probably does is ignore all of this and just call force active window. And it's something that if you had Martin complaining about focus issues on Quinn you would be told not to do this. API documentation says not to do this. Pragmatically lots of people do. It couldn't work and it was simpler. So now let's talk about what you should be doing on Wayland where you should be creating a magic token. You should pass it, be passing out using any other methods give us environment variables and then importing out into your new client. So the concept is exactly the same as what you should be doing but we don't have our force active window lazy workaround. The API is subtly different and I would go start to say it's considerably easier because case startup info is very, very, very confusing. So new classes are key window system request to XG activation token and then you get a signal back once it's resonating from this operation. And then from a client you import an equal set client activation token on a window and a window goes into your program. And where possible we are trying to handle this implicitly into existing calls like case startup info on X11 when you launch an application. But when you're importing a client when you've been activated we tend to be in a client custom code so a client does need to adapt. Okay, so minimizing to a system tray. If you use Q system tray or case status item everyone will continue to work as is, particularly on Plasma for Q system tray. One behavioral difference I'm seeing quite a lot particularly on random Qt GitHub projects is you don't have API to know when a window is minimized. So if you've got this fake concept of you click close and it minimizes to your tray it simply isn't going to work. Okay, so that's some very deliberate changes you need to be aware of. But I'm going to talk about some bugs in your app that Waylon might be surfacing. As one common one I've seen nine times I'm going to go into detail off. Okay, so just a minute. If everyone remembers Q2 Q3 very early days of X11 every widget used to be its own independent window so a button was a window a label was a window at a very technical level and then all of these windows formed together to create a top-level window as you would know it. And in Qt 4 I don't know exactly when at Qt 4 we stopped doing that now we just have a window that has all of your window contents. But this code path was kept you could still turn a widget into a window because it does make sense deliberately in a few very very specialist cases. So if you're a media player putting a media content in this own separate window OBS does this it makes sense. You can get some performance boost out of it in some specific cases. And Waylon has an analogous situation to this X11 window embedding for these same specific cases is a concept of Waylon sub surfaces acute extracts. So in theory this should all work exactly the same as no need to be aware of it. And that is true for any correct code. But one problem we've been seeing a lot is it's very very very easy to accidentally turn a Q widget into a window when you're not trying to do it when you're not doing it for performance reasons. And if you turn something into a window and then never show that window never call Q window show on that widget you end up in a situation where we've created a window but then rendered the content somewhere else. And doing so accidentally causes no visible issues on QXB on X11. It's still buggy, it's still wrong, it's still very very weird but you can't see those. And I can't expect developers to fix bugs that you can't see. But when you're running against QtWayland very very bizarre things happen because it just can't map things quite correctly. So you get a situation where input just doesn't reach certain widgets. So it has these slightly odd effects that you need to be wary of. So if you have a when if you do encounter this bug where symptoms are things are just behaving weird in a subtree of widgets check for this. And it's quite easy to check for just put a breakpoint in a Q platform window constructor. You should only have a Q platform window constructor when you're actually creating a window. Similarly, a same bug but coming up in a different way. Avoid QGL widget. It's a class that you don't want to be using. It's rubbish. Q OpenGL widgets should be used instead. This is what your documentation inside Qt says. Follow your documentation. But we have seen people where people haven't made it. We have seen cases where people haven't made a port yet. Another related case if you are deliberately turning some widgets into a window or deliberately using subsurfaces. Be sure to enable this flag which I've cleverly cut off called Don't create native widgets of links. And without going into what this flag does is it breaks your application and you don't want it. It's there purely for some compatibility with if you want this very same behavior as what we had in Qt 2 and Qt 3 which you don't. And there have been some other situations I fixed a crash in Kio where it just expected input to come in a certain order after we create a mode of dialogue. It was sure at once to create a mode of dialogue any input must be in that mode of dialogue. Anything else would be something to assert over. And that wasn't sure in Wayland because of like asynchronous gap. And there were many many cases where things happen to work fine on X11 but it doesn't mean your app was right. Not seeing a bug doesn't mean a bug wasn't there. And take away from this is you just need to test. So let's dive a bit into Qt Wayland itself. Qt Wayland somewhat has an impossible job because in Wayland people are trying to revisit some how can we do window management and all of the display server works in some new and creative ways. And those ways aren't wrong. They're just sometimes new and different. And Qt has to have backwards compatibility and forwards compatibility. Qt Wayland has an API that is fixed and abstracted and we have to support absolutely in 10 years ago we have Qt 6 API frozen so we're frozen for six years into the future and Qt Wayland is stuck in the middle trying to bridge his somewhat times different concepts. So it's in a difficult situation but despite that it's quite good. The code is really well written the unit tests are excellent. Another challenge with Qt Wayland and an opportunity is Qt Wayland itself lets you cherry pick what you want to support. If I'm making a coffee machine I don't necessarily need drag and drop so your composites you just wouldn't implement it. And we see this quite a bit. Qt Wayland has effectively two distinct sets of user groups with a depth upside and the embedded side and inside Qt Wayland we're seeing divergent code paths because you can completely replace one of the core protocols of how you turn some window content into what the window manager considers a window. So if you're only showing a full screen window you don't need the concepts of resizing and all of these so you go through a completely different code path with an API as much as what you need. But problem there is Qt Wayland then has these divergent paths. KDs have been very active on Qt Wayland. We've made well over 50 commits and I think Qt Wayland people do a very good job of now asking us for our opinion on any patches that would affect us. Two developers have gained a proof of status because of their work we've been doing in Qt Wayland that was myself and Alish. So if you do work in Qt Wayland you are going to be met with friendly faces on my face when you make a patch. And to some extent we're seeing a slight change in the Qt companies core demographic of not being so much in the desktop side but being slightly embedded focused at which point if we're the only people using a desktop side it's our responsibility to make it work you can't expect somebody who doesn't gain anything to do their work where people have gained from a lot of these desktop features it's our responsibility. And I do want to say acute maintainers both Jonas, Esco and Paul have been absolutely amazing welcoming people. So what are your next steps in Qt Wayland? Well we want to export a couple of more API for your Wayland specifics going really low level and exporting everything that you can do in Wayland to our clients. And getting things into Qt Wayland is a very good way of avoiding some of the issues that you might see with dependencies. If we do things on the KDE side we might have some challenges. So I mentioned earlier about Leia Shell we might want to well we do want to expose all of that inside Qt window activation that we've done and have commonly exposed as KDE API we want to just add that Q string overload somewhere into Qt even Qt Wayland itself or maybe into Qt Core so we can use it. And anything that we can't abstract into Qt window ideally we want to try and expose as much as possible in Qt Wayland API. There was a buff this week it is on Tuesday I can tell you the time in my time zone it's one o'clock but other people adjust accordingly. Please do attend. There are multiple ways to extend Qt Wayland if Qt Wayland doesn't have everything you need so Qt Wayland will do everything like show it a window but if you want to introduce some custom Wayland protocol we have some slightly fragmented landscape in KDE so there's a library called K Wayland which is a very low level API exposing a one-to-one mapping of Wayland protocols. In general we found this isn't necessarily a direction we want because from a client point of view it sucks to use a one-to-one mapping with what gets sent over the wire. On Wayland if you want to send a large struct we don't send a large struct because there's a message there's a maximum message size so instead we send it as a stream where we attend each thing individually and then there's a semaphore and you don't need to know from a client point of view about all of those details so I think we're finding we want to provide much higher level API and in the right place. There's also what I've mentioned Qt provides a mechanism to extend with a custom Wayland protocols it's a class called Q Wayland client extension and we're kind of in a transitional phase of what we're using inside KDE you can use a mix and match so to use Q Wayland client extension it's very much like using Qt versus XML to CPP it creates a class it's got a virtuals for messages to come to us and it has methods for things that we send to a compositor and because everyone's just like to copy existing code copy a code inside KDE add on source recorder and then just adjust accordingly it should be fairly intuitive but what about missing functionality for example if you've got an application with toolbars and toolbars sometimes behave a bit differently how we expose and we find the Wayland spec protocol doesn't have what we want but it's important to know the Wayland specs are still evolving this we are still getting changes in their activation that we talked about only landed in the last two months and we helped push that on the KDE side especially Alice Paul did a lot of the work so everything is still evolving and one of the things that I think has been a problem with Wayland till now is that all the specifications are being decided upon by compositor developers it's a big group of people all from different teams but everyone is a compositor developer and I think this is the root of a lot of the problems if this comes with an inherent bias are people answering their questions what is going to be best from the point of view of a compositor and we do need a healthy balance so I think we do need application developers to be coming in saying well these are my requirements this is what I need please make something that works so the solution to this is to get involved make sure all problems are known and elevated for our stack if you're missing something in Qt elevated to Qt if Qt is missing something in the Wayland protocols elevated to Wayland protocols all the people are very friendly and we'll listen as long as they're aware and a common theme that was found when we've been doing all of our work is it's better to start ages ago and with all of these things we thought oh which I've done that five years ago so I could be using it now whether it's a Qt change that we're now blocking in on Qt 6 or Wayland protocols which is a very slow moving process for good reason but it's a slow moving process so it's important to just start now so to wrap this up test test test again as developers you should be using Wayland on your application for as much as possible even if you don't try and assist that your users use it because of issues as developers you really should and we're here to help if you have a specific issue we are happy to help please do ping us if you're on bugzilla use the Wayland keyword and it will get noticed by people who search for that keyword which I do don't just move things to Quinn but I just Wayland keywords we can keep track of everything and if need be elevate issues to Qt and I think that's the end of my talk well I know that's the end of my talk I vote it and it says to the end thank you Dave there is a first one question does the layer shall work on X11 or does it need to be effect it would not work it would be possible to write a library that semantically does it in process and have a client only speaking somatic terms which then get mapped to X11 the layer shall library as is I don't know if it crashes if you try and use it but it certainly wouldn't be very useful okay I'll put in a question since you mentioned that Wayland protocols are moving target how much effort do you estimate has been let's say wasted because of those changes too much but a lot is necessary everyone's quite hesitant on committing to API particularly as Wayland doesn't have a very good mechanism of doing binary and compatible changes it's got a very good mechanism for adding API a binary compatible change but it doesn't have a very good one for incompatible ones so people are naturally cautious like you would be for a public API in the library but that means people tend to put things with certain names and just renaming a protocol with no actual code changes is quite difficult because you need to support anyone with an old name and anyone using a new name even if it's the exact same thing across the wire because this text description of the interface name is sent at some point and the code generator just don't handle that very well so thank you too much but it's necessary thanks there are no more questions as far as I can see but a lot of applause in the chat so I don't need to say give a hand to David thank you for the talk and see you later bye bye