For the next digiKam releases, the digiKam team needs photographs for digiKam and Showfoto splash-screens.
Proposing photo samples as splash-screens is a simple way for users to contribute to digiKam project. The pictures must be correctly exposed/composed, and the subject must be chosen from a real photographer’s inspiration. Note that we will add a horizontal frame to the bottom of the image as in the current splashes.
The Kdenlive 26.04 Release Candidate is ready for testing. Many bug fixes and workflow adjustments should make your editing sessions nicer. It is also worth noting that we had quite a few new contributors helping our small team on this, so thanks to all those who helped us!
Please remember that this is an RC version, not yet final, to be used only for testing and reporting issues.
Features highlights:
Added animated previews for transitions
Added a feature to mirror the monitor to an external monitor, allowing you to see the image in the usual interface, while duplicating the output to a secondary monitor
Added an entry in the timeline context menu to directly import a clip to the project and add it at click position
Added an option to always zoom on the mouse position instead of the timeline playhead
Generate audio thumbnails for sequences
Dropping a transition to timeline will automatically adjust its duration to the above/below clips
Allow changing speed of multiple clips
Feedback Needed
Now is your chance to test it and let us know if you encounter any bugs or have suggestions to help us polish the final release. Share your feedback in the comments below
Available Binaries
The AppImage and Windows versions can be downloaded through the links below. Update: the MacOS binaries are now also available
Download the binaries from below and give it a spin!
Falkon Connect: The Roadmap Ahead (WebXDC, XSLT, and Daily Puzzles) In my previous post, I broke down the architecture of building Falkon Connect from scratch—turning the KDE Falkon browser into a decentralized XMPP client.
A look at what went into the Kubuntu 26.04 LTS Resolute Raccoon release — bug fixes, new contributors, KFocus teamwork, and a call for beta testers ahead of the April 16 RC.
This release mainly fixes an issue for Windows users: some applications, like Microsoft Windows Powertoys' Fancy Zones or the Google Drive plugin cause problems for Krita. These applications query all running applications for their accessibility abilities.
Until Qt6, Qt's QML module, which is used extensively in the new text tool, would then recursively query all active screen objects, like comboboxes or buttons, and up and down the entire class hierarchy for accessibility features. This slowed down Krita to the point where even menus would be slow to open.
It was extremely tricky to figure this out, since none of the Krita developers actually use these external applications... But it should be fixed now!
There are more fixes in this release:
The mutator shortcut is now Ctrl-alt-shift-m instead of Z in accordance with the plugin's manual.
On Android, the canvas will not pan up when you use the text tool
On Android, the OnePlus stylus middle click button works
Animation Key Frame copy pasting now works in Krita 6
On Wayland, drag and drop is fixed (Wayland clears the clipboard when a new window is opened, so now we have to cache the data.)
The canvas resize dialog now works correctly when changing units (bug: 517857)
The Incremental Backup/Version saving function now works in Krita 6.
On Android, text fields should no longer block stylus movements, pressing spacebar should work as a shortcut and the view should no longer turn blue when pressing a keyboard key. These issues only occurred on some devices.
Check out the release notes for a full overview of all the new features in Krita 5.3 and 6.0.
⚠️ Warning
One again, we consider Krita 5.3.1 suitable for productive work; 6.0.1 is, because of the many changes from Qt5 to Qt6 more experimental.
5.3.1 Download
Windows
If you're using the portable zip files, just open the zip file in Explorer and drag the folder somewhere convenient, then double-click on the Krita icon in the folder. This will not impact an installed version of Krita, though it will share your settings and custom resources with your regular installed version of Krita. For reporting crashes, also get the debug symbols folder.
The Linux AppImage and the source tarballs are signed. You can retrieve the public key here. The signatures are here (filenames ending in .sig).
6.0.1 Download
Windows
If you're using the portable zip files, just open the zip file in Explorer and drag the folder somewhere convenient, then double-click on the Krita icon in the folder. This will not impact an installed version of Krita, though it will share your settings and custom resources with your regular installed version of Krita. For reporting crashes, also get the debug symbols folder.
Nothing much has changed here outside of some better error handling, consistency in argument help strings, and improved readability of log messages.
The script has run well on its weekly timer and seems to show no signs of giving up.
I do think I can improve it by making it more extensible to accommodate the scrubbing of new websites and accounts, but as of now it functions well for the links we're most worried about.
Reddit Insights page scraper
In the prior blogpost I mentioned worries about getting the script to run on a headless server.
The script has since been made capable of running headlessly through use of a Docker image which wraps the program run with an Xvfb display server.
Xvfb enables this by running display requirements in virtual memory, allowing for the use of headful software in a headless environment.
Shoutouts to Sean Pianka's repo containing dockerfiles used to run Xvfb-wrapped Selenium scripts and Selenium's own Docker images used for Selenium Grid server project.
Without those resources it would have taken me a lot longer to hack together the requirements for a Docker image that could run Selenium headfully.
Along with the headless runs being solved, I also implemented plenty of bug fixes and improvements to user-facing messages.
Many of the bugs came from not properly exiting Selenium during handled errors which I found out from the server having hundreds of open Firefox instances.
Hopefully I've cleaned all those up.
Google Alerts evaluator
This task was a fairly large undertaking involving plenty of research and implementation steps.
There were three major requirements:
Develop a pipeline to take in Google Alerts emails and pre-process them into articles the model can read.
Evaluate lightweight sentiment analysis models that can run on a server for their ability to analyze articles on KDE products.
Parse model output into a human-readable and easy to work with data format.
The final result is a pipeline that
Reads Google Alerts emails
Pre-processes the articles into Markdown files for model reading
Feeds them to a local LLM configured to provide sentiment analysis output
Takes the LLM output and sends it into a CSV file (if possible)
You can see how this task could take a lot of time out of people, so hopefully this pipeline can significantly alleviate that time spent.
Google Alerts email reading and processing
This was no issue as Google Alerts are all sent through Gmail and Google itself provides a very useable Gmail API for extracting emails from Gmail accounts.
After generating the required credentials, fetching emails was as easy as using tools built specifically for this job in a Python package that contained bindings for the Gmail API in Python.
The emails were all formatted in XML, so past experience with webscraping from the last two tasks played a part in making fetching article links from the emails painless to implement.
After the article links were extracted from the emails, their contents were then fetched in Markdown format for use with the decided model.
Model evaluation
We very quickly looked towards some local large-language models (LLMs) to serve the sentiment analysis task.
There were more than a few sentiment analysis fields that would be difficult for more basic models and it simplified implementation greatly.
After the evaluation of some small-footprint models, by far the best at both conforming to the desired output format and performing sentiment analysis on the articles was Qwen3 with 4 billion parameters.
It is lightweight enough to run on an older CPU in decent time, and while it doesn't agree amazingly with human judgement it more often errs on the side of caution, such as deciding more articles are related to KDE than aren't which wastes time but doesn't exclude relevant articles.
Designing model output and post-processing
It turns out that LLMs come in different flavors, and some, specifically instruct models, are much better at conforming to instructions than others.
Many attempts were made to make other types of models provide output in a strict format and, if you need specific output, it's a headache you should definitely consider avoiding by choosing instruct models from the start.
An instruct model coupled with a well-constructed system prompt (the meta prompt that sets initial instructions for the model) and grammar file written in GBNF format can cause model output to be very predictable.
The system prompt written for this task is specifically constructed to bound model output by asking it to output sentiment analysis features in a Python formatted array of strings.
Even with the above methods, instruct models still do botch output occasionally, so the script contains plenty of post-processing and error handling steps before model output is processed into the output CSV file.
Experience and lessons learned
I've learned a significant amount about web scraping and how to navigate data troubles.
I'm definitely a lot more confident about using developer webtools, HTML processing, and browser automation frameworks as a result of my SoK experience.
Also after working on the Google Alerts sentiment analysis task, and I certainly feel more educated on AI topics and how they are used and deployed.
My project was a little unusual in that I wasn't working on an existing KDE software but utility scripts that were built from ground-up for KDE community members.
This made things fun through the freedom I had with implementing solutions, but I feel the scripts are not fully developed or as problem-free as possible.
I'd hate to just leave them as is while feeling that way, so I'll continue working on the already made scripts as well as new ones so long as I can help out.
Huge thanks to Paul Brown for mentoring me through this project and being a pleasure to work with, as well as the KDE community for hosting this great event.
I had a lot of fun working on these scripts and am glad I could help out by contributing something to this awesome community.
Eight weeks, a deep dive into KDE's architecture, and one completely fried motherboard later, my Season of KDE (SoK) journey has officially come to an end!
For the past couple of months, I've been working on KDE's computer-aided translation tool, Lokalize, under the mentorship of Finley Watson. What started as a simple UI ticket ended up teaching me a ton about open-source development, community collaboration, and user experience.
Fixing the "Jumping" Menubar
If you use Lokalize, you’ve probably run into this bug: the menubar reshuffles every time you switch tabs. Go from the Editor to the Project Overview, and suddenly the Edit, Go, and Sync menus disappear or swap places. It totally breaks muscle memory. As part of my Season of KDE project, my task was to fix it.
Instead of just hacking together a quick fix, I restructured how Lokalize handles its menus globally. I created a "Global Skeleton" layout that reserves a permanent spot for every menu, regardless of which tab is open. I then wrote logic that hooks into the application's tab-switching events. Now, if a menu isn't needed for your current tab, it simply greys out instead of disappearing completely. The result is a much more predictable UI!
Ghost Actions & The Bookmark Manager
While exploring the codebase, I discovered a graveyard of "ghost actions"—UI buttons that existed on the screen but had zero backend code making them work. After surveying the KDE translators' mailing list to understand their daily workflows, I got to work building them:
Core Editing & Batch Actions: I built the backend logic to make Cut, Copy, Paste, and Alternate Translations work seamlessly. I also implemented batch actions (Save All, Close All, Revert All), complete with a safe shutdown sequence that prompts users for unsaved changes so they never lose their work.
The Bookmark Manager (In Review): Translators lacked a good way to review multiple flagged lines in large files. I designed a brand-new, interactive Bookmark Manager dialog that lists all bookmarked entries with text previews and checkboxes. Currently, this feature is under active discussion with the KDE Visual Design Group (VDG) to ensure the UX aligns perfectly with KDE's design guidelines.
What I Learned
Writing code was really only half the experience. My biggest takeaways from SoK were:
Navigating Legacy Code: I learned how to read, trace, and respect a massive, established C++ codebase rather than trying to rewrite everything from scratch.
Community-Driven Development: Talking to the translators and getting feedback from the design team taught me that building what users actually need is just as important as writing the code to make it work.
While Season of KDE is over, my time with Lokalize isn't! I will keep contributing to get the Bookmark Manager completed, and I am currently drafting my proposal for Google Summer of Code (GSoC).
Special Thanks
A very special thank you to my mentor, Finley Watson. None of this would have been possible without your guidance. Thank you for the incredibly thorough code reviews, your endless patience, and for being so supportive when my hardware literally went up in smoke. Thank you for making this such a great first experience with KDE.
Finally, a huge thank you to the translators on the mailing list who helped shape these features, and the entire KDE community for being so welcoming.
As we're nearing the end of SoK 2026, I am writing to share my experience and progress since my previous blog.
The second half of my SoK project has been a real learning experience for me, about how contributions to KDE and open-source communities in general work. I also learnt the importance of thorough testing, bug fixing, and polishing that is required before shipping any software.
Technical update and challenges faced
Till the halfway mark, I was able to complete a rough working version of the source mode editor. But after feedback from my mentor, I realized that a lot of work was still left to be done.
Firstly, there were a lot of repeated lines of code in my solution, as I had essentially split the existing editor into two - the rich editor and the raw editor. This meant that a lot of the functionality was common between the two editors, and I had re-used existing code for that. This was true for both the QML pages and the C++ document handlers.
As I now realize, that would have been a nightmare for maintainability, as any single fix or change would have to be made in two places.
The fix for the C++ part seemed to be obvious: to use inheritance. So I decided to make the RichDocumentHandler and RawDocumentHandler inherit from a common parent, the DocumentHandler. DocumentHandler now contained all the common methods, significantly reducing repeated lines of code.
Similarly on the QML side, I made a parent component, EditPage, and made the Rich and Raw edit pages inherit from it. This caused some issues (mostly related to property sharing between components) that were eventually fixed.
A major issue I faced was caused by the fact that my MR essentially removed the existing EditPage.qml and documenthandler.cpp (although files with the same name are still present, they serve different purposes). Their contents were divided into two files - the rich and raw versions respectively.
But while I was working on my feature, other contributors were still modifying the old files. Git can't handle this automatically, because the old file is in a way completely changed. This meant that I had to manually go through each commit to the old files, and move the changes accordingly to the new files.
This proved to be a major headache, and caused me (and even Carl) to spend considerable time manually rebasing.
So when finally the feature was merged, it was a sigh of relief, as we wouldn't need to manually maintain it anymore!
Apart from this, I also added a spell-checking capability to the editor, using Sonnet.
Demo
Learning and experience
I was grateful to see my work get published in Marknote 1.5 - and also felt a responsibility at the same time. Source mode is an asset for the app, but at the same time any bugs in my work are also a liability!
I learnt how a professional application is different from a hobby project, and how the quality and rigour of work should reflect that.
It was a really fun experience working with the KDE community and I'd like to thank my mentor Carl Schwan for always being there to help!
SoK has been a great first stepping stone to introduce me to the community, and I'm looking forward to contributing to Marknote and other apps even after the program!
Global objects are one of the core abstractions in Wayland. They are used to announce supported protocols or announce semi-transient objects, for example available outputs. The compositor can add and remove global objects on the fly. For example, an output global object can be created when a new monitor becomes available, and be removed when the corresponding monitor gets disconnected.
While there are no issues with announcing new global objects, the global removal is a racy process and if things go bad, your application will crash. Application crashes due to output removal were and still are fairly common, unfortunately.
The race
Let’s start from the start. If the compositor detects a new output, it may announce the corresponding wl_output global object. A client interested in outputs will then eventually bind it and receive the information about the output, e.g. the name, geometry, and so on:
A new wl_output announcement.
Things get interesting when it is time to remove the wl_output global. Ideally, after telling clients that the given global has been removed, nobody should use or bind it. If a client has bound the wl_output global object, it should only perform cleanup.
The preferred way to handle wl_output global removal.
However, it can happen that a wl_output global is removed shortly after it has been announced. If a client attempts to bind that wl_output at the same time, there is a big problem now. When the bind request finally arrives at the compositor side, the global won’t exist anymore and the only option left will be to post a protocol error and effectively crash the client.
A wl_output global removal race.
Attempt #1
Unfortunately, there is not a lot that can be done about the in-flight bind requests, they have to be handled. If we could only tell the clients that a given global has been removed but not destroy it yet, that would help with the race, we would still be able to process bind requests. Once the compositor knows that nobody will bind the global anymore, only then it can destroy it for good. This is the idea behind the first attempt to fix the race.
The hardest part is figuring out when a global can be actually destroyed. The best option would be if the clients acknowledged the global removal. After the compositor receives acks from all clients, it can finally destroy the global. But here’s the problem, the wl_registry is frozen, no new requests or events can be added to it. So, as a way around, practically all compositors chose to destroy removed global objects on a timer.
That did help with the race, we saw a reduction in the number of crashes, but they didn’t go away completely… On Linux, the monotonic clock can advance while the computer sleeps. After the computer wakes up from sleep, the global destruction timer will likely time out and the global will be destroyed. This is a huge issue. There can still be clients that saw the global and want to bind it but they were not able to flush their requests on time because the computer went to sleep, etc. So we are kind of back to square one.
Attempt #2
The general idea behind the first attempt was sound, the compositor only needs to know the right time when it is okay to finally destroy the global. It’s absolutely crucial that the Wayland clients can acknowledge the global object removal. But what about the wl_registry interface being frozen? Well, it’s still true, however we’ve got a new way around — the wl_fixes interface. The wl_fixes interface was added to work around the fact that the wl_registry interface is frozen.
With the updated plan, the only slight change in the protocol is that the client needs to send an ack request to the compositor after receiving a wl_registry.global_remove event
After the compositor receives acks from all clients, it can finally safely destroy the global.
Note that according to this, a client must acknowledge all wl_registry.global_remove events even if it didn’t bind the corresponding global objects. Unfortunately, it also means that all clients must be well-behaving so the compositor can clean up the global data without accidentally getting any client disconnected. If a single client doesn’t ack global remove events, the compositor can start accumulating zombie globals.
Client changes
The client side changes should be fairly trivial. The only thing that a client must do is call the wl_fixes.ack_global_remove request when it receives a wl_registry.global_remove event, that’s it.
Here are some patches to add support for wl_fixes.ack_global_remove in various clients and toolkits:
libwayland-server gained a few helpers to assist with the removal of global objects. The compositor will need to implement the wl_fixes.ack_global_remove request by calling the wl_fixes_handle_ack_global_remove() function (it is provided by libwayland-server).
In order to remove a global, the compositor will need to set a “withdrawn” callback and then call the wl_global_remove() function. libwayland-server will take care of all other heavy-lifting; it will call the withdrawn callback to notify the compositor when it is safe to call the wl_global_destroy() function.
Conclusion
In hindsight, perhaps available outputs could have been announced differently, not as global objects. That being said, the wl_output did expose some flaws in the core Wayland protocol, which unfortunately, were not trivial and led to various client crashes. With the work described in this post, I hope that the Wayland session will become even more reliable and fewer applications will unexpectedly crash.
Many thanks to Julian Orth and Pekka Paalanen for suggesting ideas and code review!
Today is the simultaneous release of Krita 5.3.0 and Krita 6.0.0!
Depending which version of Qt and KDE Frameworks you build, the same source will result in one of the other. Both versions are almost functionally identical, with 6.0.0 having more Wayland functionality.
But note that since Krita 6 is still considered rather experimental, since it's our first release based on Qt 6, and there were many complicated changes between 5 and 6.
For real work, please use 5.3.0! We expect 6.0 to become the main version of Krita before the end of the year, though.
Krita 5.3/6.0 is the result of many years of work by the Krita developers. Some features have been rewritten from the ground up, others make their first appearance.
Enjoy the completely new text feature: on canvas editing, full opentype support, text flowing into shapes. It is now easier than ever to create vector-based panels for comic pages. Tools got extended: for instance, the fill tool now can close gaps. The liquify mode of the transform tool is much faster. There are new filters: a propagate colors filter and a reset transparent filter. Support for HDR painting has been improved. The recorder docker can now work in real time. There is improved support for file formats, like support for text objects in PSD files. And much, much, much more!
For a complete overview of everything, check out our extensive release notes!
5.3.0 Download
Windows
If you're using the portable zip files, just open the zip file in Explorer and drag the folder somewhere convenient, then double-click on the Krita icon in the folder. This will not impact an installed version of Krita, though it will share your settings and custom resources with your regular installed version of Krita. For reporting crashes, also get the debug symbols folder.
The Linux AppImage and is signed. You can retrieve the public key here. The signatures are here (filenames ending in .sig).
6.0.0 Download
Windows
If you're using the portable zip files, just open the zip file in Explorer and drag the folder somewhere convenient, then double-click on the Krita icon in the folder. This will not impact an installed version of Krita, though it will share your settings and custom resources with your regular installed version of Krita. For reporting crashes, also get the debug symbols folder.