 Thank you all for being here for my academy talk and I'm going to talk about K-Runa, past, present and future and that includes topics like porting new features since I started contributing and also plug-in distribution. So how does K-Runa affect you? Because most people only know it as the standalone executable that is launched when pressing all space or alt and function 2 key. But it is also a flexible framework and it powers your normal application launchers like kicker. And because of that, it is an essential part of the KDE desktop experience. And now I'll come to my structure. First, I'm going to tell you who I am and how I ended up in KDE. And then we are going to have a brief look at the KDE four times and we look at the major improvements and features since I started contributing. But since I'm in the community for three years, I can't cover all features, so it's only an optimized subset of it. And then we look at K-Runa's ecosystem and specifically the plug-ins. And afterwards we look at the upcoming changes and improvements in KDE framework 6 and also look at some of the things that are not yet implemented but planned or in progress. So who am I and how did I end up in KDE? I first tried KDE in 2019 and I immediately loved it. And I initially played a lot around with the applets, so it was very fun like installing some new applets through K-new stuff. But it was mostly just playing around. But I only later discovered K-Runa and all its features. And at the time, the normal application launcher did not have all of the plug-ins available that K-Runa has. And I then played around with some of the KDE plug-ins and installed some other ones from GitHub. And eventually I wrote my own plug-ins, if you want to call them using K-Runa Bridge, which in and of itself is another plug-in. But there I hit some architectural constraints and performance issues because it was starting like a new process, usually a Python process for every character typed. And that of course can be very fast. And then I decided to rewrite my plug-ins in C++, which is what some KDE for tutorial also suggested when you want to create a K-Runa plug-in. But I barely knew it at the time, so it was quite adventurous. And most of the plug-ins are still around on GitHub. For example, here you have an overview of my PIN GitHub projects. And you can see the JetRuns run-up plug-in, which allows you to integrate the recently launched projects in the JetRuns IDEs in K-Runa. And they also made a Dolphin counterpart for it. And I had created a plug-in for like searching and copying and pasting emojis. And there's also an integration into K-Rulet, though that's maybe not super useful for most people, but at the time I found it useful to have. And when talking about how one started contributing to KDE, everyone has like an origin story. It was a feature. They ideally wanted a bug that was annoying them. And in my case, I had some runners that required configuration, and they weren't very useful without having some settings configured there. And ideally, I wanted to do that right after the installation. So I had the simple idea of passing in an argument when launching the Plasma Search KCM, and that would then launch the runners config module. And that was my first fabricator patch. And I'm still here three years later, and contributing to KDE has proven to be quite addictive. And looking back at the KDE four times, I have a screenshot. And you can see there's of course some resemblance, like the normal apps like console that are provided in the results. Conqueror is not as in as it was back then. And there are of course some differences. For example, in KDE four, we had a keyword space user interface, and Karen had some API to directly integrate into that. And that was called run options where each runner could produce a custom widget for a given match. And the API was still around in the KDE five times, even though it didn't work. And I also stumbled upon that when I started creating my first runner. And also there was a help button, and that is one of the features I'm going to talk about in a moment, because I revived that for KDE five. And back then we also had scripting support using cross, which was, or is a KDE framework that allowed you to create scripts in Python, Ruby, and JavaScript. And so you could create K-runner plugins in all of those languages and cross would take care of making them work. And one feature that I mentioned a moment ago was the help integration. And in KDE four this button was coded as part of the UI, so it was only specific to the Karen executable. But the runner syntax class, which is used by the plugins to provide information, like what are the example queries and how is the description, was still in KDE framework five, and the plugins still used it. And some third parties even adopted that, maybe they just copied it from existing KDE code. But I wanted more flexibility by implementing it as a plugin. And I did a little magic trick there, and because I've cast the parent to a runner-manager object, which is always guaranteed to be true, so that I can access the other runners and their syntaxes. So here we have a screenshot of the help plugin in action. And on the top left corner, you can see that when just typing question mark or pressing the button with the question mark in it, you'll get an overview of the available runners and their first example query. For example, we have the spell runner here, the places runner. But some runners have more syntaxes. And because of that, you can select one of the matches and you will get then all available syntaxes. And that is what you can see on the top right corner. And the daytime runner, for example, has certain trigger words like date and time and can optionally have a query after that. And here you can see that it is put in angle brackets. And when you then run one of those matches, the text that is in angle brackets will be selected. And the other text will just be inserted into the UI so that you can easily try out those example queries. And you still know what you're supposed to type in the placeholder, and you can override it with just one keystroke because the text is selected. And since it's a plug-in, it is also available in kickoff. And here you have an overview of how that would look. And with the scrollable view, it's also quite nice because you get all the runners. And in Academy 21, there was a really cool Reddit post highlighting some of K-runner's features. And hopefully you'll be able to discover those features yourself. And if anyone ever needs to do a similar post, it will hopefully take them less time. Also, K-runner supports multi-line text. And this is used in the dictionary runner and also the help runner. And while the description is multi-line, it can also contain a cute style text markup that is used for organizing and highlighting information. And be activated using a simple setter. And here in the screenshot, you can see that the example queries like screen brightness with the placeholder and the dim screen example query are both displayed in bold. And the description comes after that so that you can visually separate the example queries from their description. Also, testing is quite important and that perfectly aligns with the KDE goal that was presented already. And K-runner has gotten a lot more test coverage in the framework and also the individual plugins. And before I made an improvement with that, it was quite hard to write tests that actually used the plugin because you either had to load the plugin manually from the build directory because we usually want to be able to run tests uninstalled or you had to build the runner class in a static library. But that is, of course, a bit tedious and causes annoying CMake code. But luckily we have the K-runner configure test CMake function to the rescue and that takes, or that works for both D-Bus and C++ runners. And we'll talk about D-Bus runners in a moment, but the concept of them is that they are just a separate process and K-runner can query them using D-Bus and a specified API. And to use this CMake function for D-Bus runners, we first have to pass in our test target and then our executable target for the D-Bus runners and also the desktop file name and the desktop file path because for D-Bus runners the metadata is not embedded. And for normal C++ plugins, we don't need to pass in the desktop file because the metadata is embedded. And this CMake function is accompanied by the abstract runner test header and that contains some utility methods, for example, init properties which checks that the runner plugin can be loaded and then loads it into the runner manager. And for D-Bus runners you can also start the D-Bus runner, or a D-Bus runner process for it and it also makes sure that the process starts properly and the D-Bus service is registered. And since you can start processes, you, of course, also want to stop them. For example, if your test ends or if you want to have a clean state during your test execution, but the method you will be probably using most of the time is launch query which just takes the different query and tells the runner manager to launch it but then it rates with a given timeout for the runner manager to finish and while making the slides, I thought it might be useful if this method actually returned the matches of the runner manager so I patched that a few days ago and that should make your testing code even simpler. What was also annoying quite a lot of users was the duplication in the K-runner results for example the recent documents in the Loo runner often produced matches for the exact same file because one remembers your recent files and the other one your indexed files and if you have the same or if you have an indexed file recently opened it is logical that both of them will show up and also the shell runner which executes shell commands and the application runner then often produced results for the exact same thing like I type Firefox and the application's desktop file would only execute the given command but the shell runner would suggest it as a separate match but now we have deduplication based on the query match ID and that needs to be explicitly enabled in the metadata because not all plugins properly set an ID for their matches but all of that is documented on develop.ke.org and for most runners in KDE it is already implemented but there are some remaining or some smaller issues and now I'm going to talk about K-runner's ecosystem and we had the KDE goal all about the apps and because of that I thought all about the plugins would be a suitable headline for K-runner because K-runner is entirely based on plugins and remember that I said in the KDE four times there was scripting support using cross but all of that was removed in the KF5 transition and all scripted runners became unsupported as a result but with Debas runners we luckily have once again a thriving ecosystem and because it's really easy to create such a runner for example Python and there's an official template for that in the K-runner repository and since the Debas runner API was initially created by David Edmondson there were some improvements done for example they now have lifecycle methods like teardown and that allow you to clean up any data or invalidate a cache when the match session finishes and K-runner is closed there are also optimizations like setting a specific trigger word for your runner so that the Debas runner process is not started before it is actually useful because I had a little plugin that allowed me to mount VeraCrypt volumes and that was only triggered by the word VeraCrypt and because of that optimization it no longer started a process every time I booted into the plasma session and it is also now possible to set actions only for specific patches and before K-runner would always take all of the actions that you have provided for your entire Debas runner and add them to every match and now you can specify that explicitly if you want and you can also support or you can also define your user-chelp in a runner syntax compatible array in the metadata and the metadata are just desktop files and all of the properties are also documented on the develop KDE.org page and because we both the K-runner ecosystem in the KDE 4-5 transition we don't want to do that again and because of that we have the promise to keep the KF5 runners compatible and working with KF6 but only as long as you would get a deprecation warning about the desktop file location because we internally needed to get rid of K-Service type trader and the new location is in the data root tier and then K-runner slash Debas plugins so it's really easy to port that and the installation of the new install location is available since KDE Frameworks 572 and that has even hit Debian stable or Debian 11 so there's really no reason not to port to it and in Plasma 5.21 there was an integration for the K-runner plugins into the KDE Store edit and that supported like custom install scripts as some pre-built packages and of course there were proper warnings and recommendations given in the install dialog and for Python scripts it is relatively simple to just manually review the one or two files that are in there but because we didn't have a standardized install procedure we had to rely on the install scripts and open a terminal window for them because some scripts required manual intervention or adjustments and for example if there's a yes or no question inside of the install script and that had worked great and we got many more plugins on the KDE Store and it made it also far more discoverable for users but it is still not great to X to have a terminal window open and when you want to install something the Linux nerds probably are perfectly fine with that but the average user might be a bit confused and most install scripts for Debas runners are just based on the official template in the K-runner repository which just adjusts and copies a few files and the idea is that we can specify the files that need to be copied or the information required for files to be generated in the metadata format and then we can manually generate or copy those files without the need to execute any custom script and maybe that can be extended with some dependency checks or installation checks so that your runner works properly after being installed and the merge request for that has recently landed and I will of course make use of it in the official Debas runner template in the K-runner repository and in KDE Framework 6 there were quite a lot of changes and when looking at the Git history there was lots of code removed and API refactored there were quite a lot KDE 4 leftovers as I mentioned with the one-options API that was entirely defunct and most consumer-facing changes were already prepared with deprecation macros but not every change could be prepared with them for example the namespace was changed from Plasma to K-runner because K-runner is its own framework now and no longer a part of Plasma and that didn't make sense at all of the KF5 time and we have a significantly reduced dependency tree and because in KF5 K-runner depended on Plasma frameworks in its public API which was quite ugly and it now only depends on K-activities internally and K-coordins in its public API and besides that only Qt core and in KF6 there's also the model for Mulu imported and that model is responsible for sorting the different matches the runners provide and it also exposes the information about the matches to QML and with that move all of the core functionality is now in one place in the K-runner framework and that means we are more flexible when doing code changes because we don't have to worry about all of this but of course we still need to keep binary compatibility and such and Kikar already uses this unified model and that allowed us to get rid of the sorting implementation there also there was a new class created in K-runner which is just called K-runner action and that is a very simple data class which contains like the ID text and icon or icon name and because having a queue action was overkill and caused also issues with threading but the porting can just be done using the fight-entry-place and you can remove the new keyword to instantiate it because it's now not a pointer but passed by reference also the refactoring of the threading was a large effort and the previous date was summed up by Kai Prettywell who said currently K-runner uses mental multi-threading for everything which I found quite funny and he was referring to the abstract-runner-match method being called in different threads and sometimes it was called like by different threads at the same time if you have a very long or if you have a match method which takes very long and the prepared teardown init and reload configuration methods were still done in the main thread and so if you were to do any heavy lifting there you would still block the main UI and if you want to do data initialization without blocking the main thread it's a pretty big hassle and in KDE code we have often used the pattern of having a mutex so that for the first match method call you initialize the data in there and then you write it into a variable and then unlock the mutex and reuse it for the rest of the match session and clean it up afterward but in KF6 every runner is moved to its own thread and the prepared teardown init and reload configuration methods are also called in the runner's thread and that allows for a safe initialization of the type of data and makes the code far simpler and even in frameworks it is less code because of the threadweaver jobs could be removed and there's also the possibility for further optimizations like in some runners we query the bookmarks using a normal SQLite connection and if we type like KDE we use the first three letters and we type another letter afterward we could maybe reuse the previous results instead of making a new query and that is now possible due to the match method not being called from separate threads at the same time but I have also some further plans and ideas but before coming to that I'd say that Karina is currently in a pretty good state and we are utilizing D-Bus runners we are appropriate like in Plasma Browser Integration Quinn and the K-Activity Manager daemon but that currently means we have a bit of code duplication and we have this D-Bus Util setup from Karina copied in a bunch of different places and ideally we would have a small C++ library for that only so that we can deduplicate that code internally in KDE also the thoughtings there needs improvements because we currently use both the match type and relevance for sorting which is a bit confusing and the match type is basically an enum with magic values and the values don't make very much sense anymore because they are like no match or exact match and we don't have like any specific usage of a helper match we only care for the integer value that is assigned to it and in case the match type is different and the is different between two matches the higher match type is preferred and only if the match type is the same we consider the relevance of the matches and that is confusing a lot of people and it also makes it really hard to like tweak the order inside of the plugins because you can sometimes by accident rearrange the categories with the results that other runners produced and instead we want to have separate values one for like sorting the categories so that the applications may be more important than the software center runner and then we keep the relevance so that runners can tweak the order of their own matches and that would also allow Carina to learn smarter what results you prefer because it can both learn like what specific applications you most often launch but also what runners you generally use and there is also a feature, a longstanding feature request about making the search order configurable in the Plasma Search KCM and the idea is that you can specify a few favorites and all of those favorites will be presented in a fixed order when they produce matches in Carina and the order within the category is unchanged because that would be like over configuration and on the right hand side you can already see a screenshot on how that could look visually usually the QML bits are the hardest for me when implementing such features but Marco helped me out with some details here and you can see that you are able to rearrange the favorites using drag and drop and finally I want to end with a big thanks to the community because all of those awesome features and contributions would not have been possible without other members and I've listed a few notable ones like David Atmanzen and also Natalie Clarios and Kai Uwe who was the previous maintainer of Carina and Nate Graham who has been very helpful in reviews and visual feedback and there's also a buff about K-Runner Tuesday 9am in room 2 and we plan to discuss some LibasRunner related ideas and also some visual improvements and Kai has motivated me to make a buff about it thanks thanks Alex are there questions? this is just a general question but over time we have suggested a few UI changes to K-Runner and some of them are implemented which is really cool but along with the work that you're doing with plugins are you also open to visual changes to do some of that or no, not for now? well the framework itself is not specific to any visuals but if you are referring to the K-Runner executable I'm open for suggestions and discussion and then it would be really cool if you would join me at the buff on Tuesday because there will also discuss some ideas there thank you do you agree that all space is the correct shortcut for opening K-Runner instead of all the other default ones? I have mapped my MetaKey to open K-Runner and I'm so used to that by now and every time I'm on my work windows PC I'm wondering why does the menu open up on the bottom left corner so you need to import K-Runner to windows so you can use it on your work machine yeah well the framework itself would build against windows but most of the useful plugins in the executable are part of Plasma okay thank you that concludes the session for today and tomorrow at 10 we will start again with the next talks and in case you have any questions when trying to implement your own runner feel free to ask