Hi all! I'm CJ, and I'm participating in Season of KDE 2026 by automating portions of the data collection for the KDE promo team. This post is an update on the work I've done in the first week of SoK.
My mentor gave me a light task to help me get set up and familiarize myself with the tools I'll be using for the rest of the project. The task was to automate the population of a spreadsheet that tracks follower and post counts for X (formerly known as Twitter), Mastodon, BlueSky, and Threads.
The spreadsheet takes the follower and post counts of some of KDE's social media platforms and makes calculations based off that data. Important things to note:
- data from the sites is entered manually
- there are a lot of styles and formulas in the sheet
Fetching Account Data
Grabbing data was mostly no trouble. Mastodon and BlueSky were especially easy to work with. They have a public and well documented API that lets people collect all kinds of data in human-readable formats. One particular endpoint from both sources output account information, including follower and post counts, for a given account in neat JSON files (BlueSky, Mastodon). All it took were GET requests to these endpoints and it was smooth sailing.
X and Threads proved a bit more finnicky. Both of their APIs limit access to much of their functionality usually meaning webscraping methods are the most accessible for grabbing public account data. Threads shows users' follower counts out directly on an account's landing page, so processing a GET request to the URL of KDE's Threads account made it easy to grab. The problem is that there seems to be no direct way to grab the post count either through their API or with webscraping methods. For now, we've chosen to leave that be and circle back when I explore Threads more in the future. X presents a similar problem but there is an open-source frontend alternative named Nitter, instances of which lay all the stats information out in the open. The reliability of this method depends on public Nitter instances being available so it may be worth coming back around to this in a later part of the project, but for now it's a viable solution for getting follower and post counts.
Inputting the Data Into the Spreadsheet
With the data all fetched, all that was left is to add that data to the ODF spreadsheet. I had this down as the easy part of the task but in the end it wasn't so simple. The two major Python packages I found that can interpret and write ODF files: Pandas and pyexcel. Both of these have no problem reading data from the files, but when it comes to saving they don't preserve some elements of the spreadsheet. In the end we went the simple route which is to save the data to a separate ODF file using one of the Python-ODF interfaces and import that into the data sheet. This took a little finagling with formulas to get things working without popping errors into cells the sheet, but in the end we have an output ODF spreadsheet file containing the required data and the original spreadsheet with all the calculations pulling that data into its formulas, removing any requirement of a human interfacing with this portion of data collection.
Learned Lessons
I feel like this week's task was a great first step into data collection automation. It was challenging without being too difficult to make progress on and forced me to explore different avenues for gathering data. On the confidence side, getting a (mostly) successful task out the gate helped me feel more comfortable with the tools and processes that will likely appear throughout the entirety of my SoK experience. Things will scale up from here on out though so I'm also keeping myself in check.
From what I understand some of the most difficult parts of automated data collection come through having to interface with Javascript and not getting banned, both of which I've yet to come face-to-face with in any substantial capacity so far. Along with that I've face unexpected problems, such as the issue with modifying ODF files and that some websites don't play as well with certain browsers, which I don't have an easy way to test for yet. With these in mind I'm trying to tread lightly and be diligent with research and good practice as I continue on.
Friday, 30 January 2026
Continuing previous efforts to update the “secure passwords” story of the Plasma desktop, I’ve done some integration work between Plasma and oo7.
Oo7 is a relatively recent SecretService provider written in Rust; it’s very nice, lightweight and cross-desktop. Very interesting for us supporting it as a first class citizen.
We want in the end to replace completely the old KWallet system with something based on SecretService, have all our applications migrated transparently with user data as well, if possible with a cross-desktop backend implementation.
We also want it to be as transparent as possible for the end user, not having any complicated first time setup, or dialogs that ask for a manual unlock when not needed. For the user, the whole system should be just invisible, except when looking up their passwords or when client applications add passwords to it themselves.
As a first thing several months ago we did a transparent translation layer for the KWallet DBus interface, so now the “KWallet” service became just a translation layer between the kwallet api and the secretservice one.
The old kwalletd service instead became “ksecretd” now providing only the SecretService interface, and that’s what we use by default now. however, it can be configured to use a different provider, so it can already be used with gnome-keyring or KeepassXC if the user wishes. In that case the user data will be migrated the first time.
Also I’ve written a new application called KeepSecret. It is centered around SecretService, with a much more modern UI compared to KWalletManager and works also much better on mobile, so we can have also a modern password manager on Plasma Mobile.

The last thing that we did so far is integration with a new SecretService provider on the block: oo7.
If oo7 is Just another SecretSerive provider, Won’t it “just work” in Plasma? Not quite, but that’s actually a good thing. Oo7 wants to properly integrate with the environment it runs in, so we need to build that integration.
When you use KWallet, KeepassXC, or gnome-keyring directly, they create their own password dialogs using their own toolkits and styles, therefore potentially looking a bit alien when run in a different environment than the one it it was designed for.
This is not ideal for evaluating options for a possible future replacement of KWallet (which piece by piece we are working towards), as we want the UI part completely integrated with the Plasma desktop.
Instead, oo7 is built on the assumption that the environment it runs on will provide its own dialogs, a bit like the portal system for services like screen sharing and file picking.
This requires active integration both on the Plasma part and the oo7 part, but on the other hand it will look native on Plasma, Gnome, and any other platform that implements the integration hooks. And that’s with the added benefit of sharing the password storage if someone every now and then goes desktop environment hopping.
On the Plasma side we decided to employ a very small daemon which is launched only on demand with dbus activation. It will create the needed system dialogs, pass the user input back to oo7 and then quit when not needed anymore, so it won’t constantly use up system resources.
This is already available in Plasma 6.6: the code for it is here. It’s designed first for oo7, but it can be used by any daemon which wishes to provide native password dialogs, so we might start to use it also from other components in the future, either other SecretService providers or completely different things which have similar needs like Polkit.
On the oo7 part, Harald implemented the integration with its dbus interface, so with oo7 from main branch (or its next release) it can be used in place of KWallet (with all old applications still using the KWallet API using its backend as well), with all data migrated to it, and it will show native UI for its password dialogs… all the pieces of the puzzle slowly falling together 
Needless to say this is still at an experimental stage, but it’s an important milestone in getting more independent from the aging KWallet infrastructure.
Thursday, 29 January 2026
Welcome Kaidan 0.15.0! This release adds experimental support for calls. In addition, it contains some very useful improvements and lots of fixes.
Most of the work has been funded by NLnet via NGI Zero Entrust and NGI Zero Commons Fund with public money provided by the European Commission.
Audio/Video Calls
Kaidan has supported voice and video messages for a long time. Starting with this release, you can even have an audio or video call with a contact! An incoming call is indicated via a notification and you can either accept or reject it.
Please note that there are still some features missing and some setups may not work properly. Especially, calls are only supposed to work on Linux at the moment. But we wanted to share the current achievements with you to get some feedback! Our goal is to extend the A/V calls functionality and make it available on other operating systems in the future.
Notifications for Group Chat Replies
Formerly, you got a notification if someone mentioned you in a group chat while the corresponding setting was enabled. But you could miss replies to your messages. Kaidan notifies you now on receiving replies as well.
Message Input Field Focusing
In contrast to the soft keyboard on a mobile device, which needs to be opened each time you want to enter something, your keyboard is always reachable on a desktop device. Why not make use of that circumstance? Kaidan ensures that the most relevant message input field stays focused to allow entering text without an additional click into the corresponding field. That way, you can interact smoothly with the user interface and be more productive.
Advanced Message Highlighting
Kaidan 0.14 introduced highlighted messages if you opened their context menu. Messages are now also highlighted while they are being corrected or while you are choosing emojis to react to them. If another message was already highlighted before, that message is highlighted again once you sent the correction/reaction.
Integrated Search Field
With Kaidan, you can quickly search for chats and messages. But while searching for messages, the opened search bar reduced the space for messages. On mobile devices, the search bar even consumed unnecessary space within the chat list. Both problems are solved now! The search field is integrated into the main toolbar above the messages resp. the chat list. You can even focus each search field via an own keyboard shortcut to directly search without moving the cursor.
Password Manager Fallback
Since Kaidan’s last version, passwords are stored in a password manager if the system provides one. But there was no fallback yet. It is now possible to use Kaidan even if no password manager is available. In that case, the passwords are stored in an unencrypted file. Once Kaidan detects a password manager on start, the unencrypted passwords are automatically migrated to the password manager.
Changelog
There are several other improvements. Have a look at the following changelog for more details.
Features:
- Add support for audio/video calls (XEP-0166: Jingle, XEP-0167: Jingle RTP Sessions, XEP-0176: Jingle ICE-UDP Transport Method, XEP-0215: External Service Discovery, XEP-0320: Use of DTLS-SRTP in Jingle Sessions, XEP-0353: Jingle Message Initiation) (@melvo)
- Show busy indicator while saving captured image/video data (@melvo)
- Notify on receiving reply to own group chat message if ‘On mention’ notification setting is enabled (@melvo)
- Select file after opening in folder on Linux if supported (@melvo)
- Improve media capturing look/behavior (including preview after capturing image until image is saved) (@melvo)
- Restore focusing of last focused user interface elements (especially message input field) for various use cases (@melvo)
- Keep message bubble highlighted on reacting/correcting (@melvo)
- Allow to select message for correction via Ctrl+Up/Ctrl+Down (@melvo)
- Integrate search field into main toolbar increasing space for messages and, on mobile devices, even for chats in chat list (@melvo)
- Show message search field via Ctrl+Shift+F (@melvo)
- Display toolbar buttons on mobile devices exactly as on desktop devices (@melvo)
- Hide horizontal separator above top-most chat unless chat list is scrolled (@melvo)
- Store passwords in unencrypted file if no password manager is available or corresponding command-line option provided (@fazevedo)
- Migrate unencrypted passwords to password manager if available on start (@fazevedo)
Bugfixes:
- Fix overlapping message bubble tail (@melvo)
- Fix medium preview hovering if hidden drop area info is hovered (@melvo)
- Fix updating OMEMO 2 keys for all use cases (@melvo)
- Fix deadlock on logout during upload of multiple files (@melvo)
- Fix creating additional database connection on wrong thread (@melvo)
- Fix sending/resetting whether message is being composed for various corner cases (switching chat, logging out, disabling corresponding setting) (@melvo)
- Fix updating last message on receiving initial message after setting up existing account in Kaidan for first time (@melvo)
- Fix resetting draft message after canceling message correction (@melvo)
- Fix resending failed message reaction (@melvo)
- Fix selecting previously selected message after changing reactions (@melvo)
- Fix restoring message highlighting and cancel ongoing correction/reply on removing corresponding message (@melvo)
- Fix displaying last message sender in chat list after draft message removal (@melvo)
Notes:
- Kaidan requires Kirigami Addons 1.8 now
- Kaidan requires QXmpp 1.14 now
Download
Or install Kaidan for your distribution:
The docs-kde-org project currently relies on an old, hard forked version of dblatex, which is bundled directly within the repository. This makes maintenance difficult.
What’s dblatex?
From the man page: dblatex is a program that transforms your SGML/XML DocBook documents to DVI, PostScript or PDF by translating them into pure LaTeX as a first process. MathML 2.0 markups are supported, too. It started as a clone of DB2LaTeX.
My task is to swap the bundled dblatex with the one present in the upstream repos and make the PDF generation work reliably. Then switch the rendering backend from pdfLaTeX to XeLaTeX to support native unicode (to fix rendering issues for languages like Arabic, Chinese, Japanese, Korean, etc).
If that doesn’t work out, I’ll extract the dblatex fork into its own repository to ease maintenance.
Checkpoints to achieve
Swap our current fork and use the latest upstream version. Also compare these two.
Migrate from
pdfLaTeXtoXeLaTeXVerify our fixes and confirm if all the PDFs are being generated properly.
I’ll be sharing my progress and struggles (setting this website up was probably a struggle in itself) from time to time as I start this project. This work is part of Season of KDE, mentored by Johnny Jazeix.
Wednesday, 28 January 2026
I have a pile of hard drives. 3.5” Spinning rust. There’s like a dozen of them, some labeled cryptically (EBN D2), some infuriatingly (1) and some not-at-all. Probably most of them work. But how to effectively figure out what is on them? FreeBSD to the rescue.
Hotplug Just Works
All the drives are SATA. I do have an IDE drive, I use it for opening beer bottles. And an ST-225
for old-time’s sake. But SATA it is, and there’s spare SATA data- and power-cables dangling out the
side of my PC. This particular machine runs FreeBSD 14.3, and connecting a drive (data first, then power)
yields some messages in the system log. Old-school, the command to read these is still dmesg,
which prints:
ada3 at ahcich0 bus 0 scbus0 target 0 lun 0
ada3: <WDC WD3200AAKS-00SBA0 12.01B01> ATA-7 SATA 2.x device
ada3: Serial Number WD-WMAPZ0561055
ada3: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes)
ada3: Command Queueing enabled
ada3: 305245MB (625142448 512 byte sectors)
That matches information printed on the label of the disk (this drive is from 2007, has a 1 written on it in black marker – it may have been a drive in the English Breakfast Network server back then). It also tells me that the disk is registered with the system as ada3.
FreeBSD’s disk subsystem is a stack of “GEOM classes”. The geom(4) manpage tells me
that it is a modular disk I/O request transformation framework, but the important bit is geom(8), the command to query the disk subsystem.
Running geom disk list ada3 tells me what is known about disks involved with ada3. This actually doesn’t tell
me much I don’t already know:
Geom name: ada3
Providers:
1. Name: ada3
Mediasize: 320072933376 (298G)
Sectorsize: 512
Mode: r0w0e0
descr: WDC WD3200AAKS-00SBA0
lunid: 50014ee0aabd8fe3
ident: WD-WMAPZ0561055
rotationrate: unknown
fwsectors: 63
fwheads: 16
Well, actually this tells me that the dmesg and geom output are in mibi- and gibi-bytes, and that they’re consistent.
How about partitions on this disk, though? geom part list ada3 tells me (here I’ve removed several partitions, along with many other lines that are not very useful right now; the output is extensive):
Geom name: ada3
scheme: GPT
Providers:
1. Name: ada3p1
Mediasize: 819200 (800K)
efimedia: HD(1,GPT,a43a2da3-bb5f-11e5-8d81-f5e4d894ddb1,0x22,0x640)
label: (null)
type: efi
index: 1
2. Name: ada3p2
Mediasize: 315679277056 (294G)
efimedia: HD(2,GPT,a43c9069-bb5f-11e5-8d81-f5e4d894ddb1,0x662,0x24bff9c0)
label: (null)
type: freebsd-ufs
index: 2
So it is a GPT-partitioned disk, and at least one of the partitions is an “old-fashioned” UFS partition. That’s FreeBSD before ZFS became the de-facto standard filesystem (maybe just for me). This disk is simple to deal with (further notes below)!
After I’m done with the disk, I power it down first with
camcontrol standby ada3. I can hear the disk stop spinning
and then pull out the connectors (power first, then data). And move on to
the next disk. After disconnecting, dmesg confirms that I unplugged the correct drive:
ada3 at ahcich0 bus 0 scbus0 target 0 lun 0
ada3: <WDC WD3200AAKS-00SBA0 12.01B01> s/n WD-WMAPZ0561055 detached
(ada3:ahcich0:0:0:0): Periph destroyed
This way I can step through all of the drives in my pile and then jot down what disk does what (or, in rare cases, decide they can be zeroed out and re-used for something else).
Dealing with non-GPT disks
The scheme reported by geom part list is GPT if you’re sensible,
but of course it is possible to bump into MBR and BSD disklabels
as well. The geom subsystem abstracts all that away, and the only
realy difference is the names of devices.
Scheme BSD, also known as BSD disklabel,
gives you ada3a and ada3d, rather than numbered partitions.
It is possible to apply this to a whole disk. It is also possible to
have a BSD disklabel inside an MBR partition, but that’s a late-90s kind of setup.
Scheme MBR gives you numbered partitions, but FreeBSD calls these slices
instead of partitions and so you end up with ada3s1 instead of ada3p1.
Dealing with UFS
UFS partitions are pretty simple: mount them somewhere and things will be OK.
I go for read-only, and I have a /mnt/tmp for all my arbitrary-disk-mounting activity.
So mount -o ro /dev/ada3p2 /mnt/tmp it is (ada3p2 is the partition name found earlier).
This particular disk turned out to be my main workstation drive around 2017, with a handful of still-interesting files on it. Ones I would not have missed if I hadn’t looked, but it was nice to find a presentation PDF I gave to SIDN once-upon-a-time.
After looking, umount /mnt/tmp to unmount and release the disk.
After that, power-down and disconnect as described above.
Dealing with ZFS
Slightly newer disks might be ZFS. Here’s the partition information for one:
Providers:
1. Name: ada3p1
Mediasize: 250059309056 (233G)
label: backup0
type: freebsd-zfs
index: 1
It’s a GPT partition with a label, and ZFS on it. That means it’s part of a ZFS pool,
and is probably referred to within the pool by its label. Possibly by its ID.
In any case, ZFS needs to be imported, not mounted, because the filesystems
are contained as part of the storage pool. The command to discover what is
available is zpool import , which doesn’t actually import anything.
pool: zbackup
config:
zbackup ONLINE
gpt/backup0 ONLINE
That’s encouraging: the pool consists of a single drive and everything is online.
To make the filesystems in this pool available, I need to import it. I’ll
force it (-f, because it was probably untimely ripp’d from whatever machine it was
in previously), without mounting any of the filesystems in it (-N), readonly
(-o readonly=on) with a temporary name (-t zwhat), like so: zpool import -f -N -o readonly=on -t zbackup zwhat
After importing the pool, zfs list tells me what filesystems are available:
zwhat 36.2G 189G 25K /zwhat
zwhat/home 36.2G 189G 36.0G /tmp/foo/
I can mount a single ZFS filesystem just like a UFS filesystem.
The ZFS filesystem knows where it would want to be mounted (/tmp/foo, I have no
idea what I was doing back then), but we can treat it like a legacy filesystem:
mount -t zfs zwhat/home /mnt/tmp
After looking, umount /mnt/tmp to unmount and release the disk.
After that, power-down and disconnect as described above.
Dealing with Linux ext4
If the disk comes from a Linux machine, then it may have an ext4 filesystem on it. I still usually pick that when installing Linuxes. Here’s the partition information for one:
scheme: MBR
Providers:
2. Name: ada3s2
Mediasize: 64428703744 (60G)
rawtype: 131
type: linux-data
There is ext4 support in the FreeBSD kernel, although it is named ext2
(and some ext4 filesystems use unsupported features, and then it won’t mount).
But for simple cases: mount -o ro -t ext2fs /dev/ada3s2 /mnt/tmp does the job.
Dealing with linux-raid
I found two disks, both WD Caviar Blue, labeled EBN D1 and EBN D2 with similar layouts. Those are linux-raid disks, and this is something I can’t deal with in FreeBSD. Heck, I’m not confident I can deal with them under Linux anymore, either.
Providers:
1. Name: ada3s1
Mediasize: 493928031744 (460G)
efimedia: HD(1,MBR,0xa8a8a8a8,0x3f,0x398033d3)
rawtype: 253
type: linux-raid
Re-purposing Disks
KDE has a lovely partitioning tool, but I wouldn’t be me if I didn’t go for the command-line approach. Make sure the disk isn’t mounted anywhere, but is powered up.
Zero out the first gigabyte or so of the disk: dd if=/dev/zero of=/dev/ada3 bs=1M count=1024
I guess this isn’t strictly necessary, and geom warns during this operation that the
GPT is corrupt and the backup GPT (at the other end of the disk) should probably be used. Ignore that.
Destroy the partition table some more: geom part destroy -F ada3 , now it is really dead.
Make a new GPT partition table on the disk: geom part create -s gpt ada3
Start adding partitions to the partition table. I (now) use labels with the last digits of the drive’s serial-number. This drive gets a gigabyte of swap (just in case) and the rest is a ZFS partition which I can add to a pool later.
geom part add -t freebsd-swap -s 1G -l swap-159666 ada3geom part add -t freebsd-zfs -l zfs-159666 ada3
Why the labels-with-serial-numbers? Well, that’s so that I can subsequently create a ZFS pool
from labeled partitions, and it remains obvious where the parts of the pool come from
and also prevents name-collisions from naming everything backup0 and so.
I've been administering KDE's participation in the Google Summer of Code program for the last few years (and mentoring on some). This post is just some personal thoughts on the differences between what the KDE organization expects and what usually the applicants want (I'm not in everybody heads, it's assumptions from my experience). I don't provide any solution (because I don't have any) and there is no judgment (both point of views are valid), just a personal point of view.
Applicants point of view
GSoC is a individual competitive program which can be a huge boost to start a career. There are usually two major reasons for the applicants to participate in GSoC:
- the money.
- the experience and the line in the CV for real life work.
There is, for a lot of applicants, no genuine interest in the projects (at least at the beginning, the first interaction is often "I want to start contributing to KDE and prepare for GSoC"), and they mostly want a GSoC slot. Small digression, on one of my projects, two people already asked to contribute and if we were doing GSoC, but after telling them that contributions are welcomed and we will only propose a topic if we feel enough confidence that the contributor would stay after, they told us they preferred to choose another project.
Contributors consider GSoC as an end of their studies, not a project they want to contribute after: there is also a change of life to consider between university life and work life and a balance to achieve when starting the latter (which could be in a different town/country) which may be a reason for the drop of interest.
Organization point of view
GSoC is an opportunity to welcome new contributors to our community. The organization usually expects from GSoC:
- contributors willing to contribute regularly to their projects.
- implementation (partial or total) of the proposed ideas.
- having a positive return on investment (is the time spent mentoring worth the result?)
GSoC is mostly a step to have contributors learning about the projects, and contribute in the long-term. Long-term is purposely vague; what we expected for the GCompris project was the contributor would contribute at least one year and mentor for the next GSoC (so a loop was present, and applicants would also gain an experience on mentoring, while giving some relief to the other experienced mentors) but it can vary depending on the project.
For the return on investment, mentors do not consider it good having spent more than three months mentoring for projects they could have done in less time they spent to mentor the contributor. Helping someone grow is always personally rewarding but we still hope this person will also show us the results of the teaching by improving our projects in the future.
Impacts of the differences
There is a huge difference on the expectations. What can we do to reach a common ground where everyone is happy?
- Organizations cannot force anyone to contribute after the GSoC end.
- If money is the main motivation to stay, most organizations will not have money to hire applicants to work after (and do we want to hire someone only motivated by money? No, it's not OSS values, we love passion).
- Find ways to create a real interest for the organization. In KDE, we have the chance to have tons of projects with different topics (astronomy, education, digital painting, video editing, scientific plotting, games, desktop environment, system administration, internationalization, ...) where it is easy to participate to other projects from time to time and learn new things if we are curious enough.
- Be stricter on the entry point for organizations: explicitly say in the beginning that we expect a long-term relationship not just the equivalent of an internship. It should reduce the number of applicants and only keep the ones with a genuine interest (if applicants are honest of course).
- Organizations/Mentors could reduce their objectives of GSoC and consider that contributors are here to produce and spend less time on training/mentoring, expecting contributors already know the basics, but this would totally spoil the nature of the program.
Another track is to find the projects where contributors stay / don't stay and understand the difference. Most of the big KDE applications don't manage to keep their contributors, while smaller ones do. Maybe as a contributor, it's because it's more difficult to take decisions, feel included/listened on large projects because they have a high maturity level/long-term contributors and a well-defined vision? Whereas on smaller projects, there are fewer constraints from the existing environment and it feels more rewarding and motivating to contribute there?
To conclude, here are the statistics for KDE retention the last years:
| Year | Started | Completed | Active after 1 year | Active after 2 years | Active after 3 years |
|---|---|---|---|---|---|
| 2018 | 20 | 17 | 5 | 5 | 4 |
| 2019 | 24 | 22 | 9 | 8 | 8 |
| 2020 | 21 | 19 | 2 | 2 | 1 |
| 2021 | 16 | 15 | 8 | 6 | 3 |
| 2022 | 7 | 6 | 5 | 1 | 0 |
| 2023 | 9 | 7 | 3 | 3 | 2 |
| 2024 | 10 | 10 | 4 | 2 | - |
| 2025 | 15 | 12 | 6 | - | - |
That is, an average of 15 people sign up each year, of which
- an average of 90% finish
- 44% continued contributing 1 year later
- 28% continued contributing 2 years later
- 22% continued contributing 3 years later
We would of course love having more contributors staying at least one year but it's almost half and a quarter that stay active for a few years!
Today we're releasing Krita 5.2.15. This is a bug fix release with a number of crash fixes and workarounds to improve use with the Xiaomi Pad.
Changelog
- Fix crash when using a smudge brush (Bug 512243)
- Update GMic to 3.6.4.1 in krita/5.2 branch
- Fix crash when undoing liquefy (Bug 498696)
- Fix crash when an embedded profile is faulty (Bug 509875)
- Fix loading of TIFF files with JPEG compression
- Force SVG gradients to work in premultiplied alpha mode, counter to specification (Bug 502118, more info in commit)
- Fix Transform and Move shortcuts conflicting Timeline arrow key actions (Bug 513855)
- Don't compress touch events matched to shortcuts
- Treat 3+-finger-touch cancels as ends (Bug 510993)
- Prevent rotation notice jitter around zero
- Allow combining zoom and rotation popup messages
- Disable context menu on overview widget (Bug 514238)
- Make touch scrolling not trigger menu (Bug 513413)
- Xiaomi stylus button and curve fixes (handle pageup and down) (more info in commit )
- Steeper tablet curve for Xiaomi devices (more info in commit)
- Don't flicker window on Xiaomi devices
- make xcodebuild an archival build to avoid unwanted debug entitlements.
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.
ⓘ Note
We are no longer making 32-bit Windows builds.
- 64 bits Windows Installer: krita-5.2.15-setup.exe
- Portable 64 bits Windows: krita-5.2.15.zip
- Debug symbols. (Unpack in the Krita installation folder)
Linux
Note: starting with 5.2.11, the minimum supported version of Ubuntu is 22.04.
⚠️ Warning
Starting with 5.2.11 has updated the AppImage runtime, which is known to be incompatible with the old versions of AppImageLauncher. Developers of the AppImage runtime suggest to remove or update AppImageLauncher. See this report: Issue 121 More AppImage troubleshooting info is available here: FUSE
- 64 bits Linux: krita-5.2.15-x86_64.AppImage
MacOS
Note: We're not supporting MacOS 10.13 anymore, 10.14 is the minimum supported version.
- MacOS disk image: krita-5.2.15.dmg
Android
We consider Krita on ChromeOS as ready for production. Krita on Android is still beta. Krita is not available for Android phones, only for tablets, because the user interface requires a large screen.
Source code
md5sum
For all downloads, visit https://download.kde.org/stable/krita/5.2.15/ and click on "Details" to get the hashes.
Key
The Linux AppImage and the source .tar.gz and .tar.xz tarballs are signed. You can retrieve the public key here. The signatures are here (filenames ending in .sig).
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.
To give you an idea of the chaos, here is how the menus were jumping around before the fix:





My initial thought was that this would be a five-minute fix-just tweak an XML file and move on. I was very wrong. My first instinct was to nuke the cache and blindly shuffle tags around in the .rc files, hoping the UI would magically fix itself. It didn't. After wasting a day treating symptoms and trying to brute-force a solution, I had to admit I was just guessing. I closed my IDE and decided to actually figure out how the UI was being generated.
After diving into the KXMLGUI documentation, I realized I wasn’t fighting a single XML file. I was fighting a dynamic merge of six different files happening in real-time. Whenever you switch tabs, KXMLGUI actively merges and removes XML definitions. The problem was that the main lokalizemainwindowui.rc file used generic tags. These acted like open doors with no assigned seating. Whichever tab loaded last got to decide where its menu items went. Implicit design was giving us random results.
At first, I thought about centralizing all the menu visibility in C++, but that would ruin KXMLGUI's distributed design and require a massive refactor. Instead, I decided to enforce a strict "Global Skeleton" in the main XML file. By hardcoding the menu structure using index="N" attributes, I could create a reservation system.
<MenuBar>
<Menu name="file" index="1"><text>&File</text>...
<Menu name="project" index="4"><text>&Project</text>...
<Menu name="tools" index="6">...
<Menu name="settings" index="7">...
<Menu name="edit" index="2"><text>&Edit</text><MergeLocal/></Menu>
<Menu name="go" index="3"><text>&Go</text><MergeLocal/></Menu>
<Menu name="merge" index="5"><text>S&ync</text><MergeLocal/></Menu>
</MenuBar>With the skeleton in place, I went through the child files (projectmanagerui.rc, translationmemoryrui.rc, filesearchtabui.rc) and updated them to respect these exact indices. The real trick here was giving tabs empty menus for sections they didn't even use.
<MenuBar>
<Menu name="tools" index="6">...
<Menu name="edit" index="2"><text>&Edit</text></Menu>
<Menu name="go" index="3"><text>&Go</text></Menu>
<Menu name="merge" index="5"><text>S&ync</text></Menu>
</MenuBar>By defining an empty menu with the correct index, KXMLGUI is forced to keep that menu on the menubar. Even if there are no actions inside it, the menu header holds its ground. This preserves the layout and stops the adjacent menus from sliding left and right when you switch contexts.
After updating the .rc files, adding one missing action (edit_approve_go_fuzzyUntr), and recompiling, the UI was rock solid. No more jumping menus, and all the keyboard shortcuts remained fully intact.





Lokalize Menubar Fix - Merge Request











