Tuesday, 11 March 2025
The last maintenance release of the 24.12 cycle is out.
The last maintenance release of the 24.12 cycle is out.
Today I’m going to talk about something a bit different. Maybe very different!
After six years at Blue Systems GmbH, I’ve had the privilege of working daily with some of the finest and most ethical engineers I’ve ever known; lots of people whose names you probably recognize, because they’re some of the biggest contributors to Plasma and KWin, and regularly appear in This Week in Plasma.
Starting earlier this month, about a dozen of Blue Systems’ current people — myself included — have moved over to a new company named Techpaladin Software that’s co-owned by me and someone else you probably know: David Edmundson!
No, this isn’t some kind of hostile takeover or internal corporate backstabbing. Rather, it’s the result of a mutual decision made between the owner of Blue Systems, myself and David Edmundson, and Blue Systems’ other personnel who are moving over.
Practically nothing changes for KDE: Techpaladin will sponsor almost all of the same people Blue Systems did, and they will continue to enjoy the same wide latitude to improve KDE software for a living with a high level of personal and professional freedom. Techpaladin will be a KDE e.V. Patron, too. Keeping this transition as smooth as possible was a major goal here!
I’m incredibly grateful to Blue Systems for the personal and professional opportunities I’ve had over the past six years. Working on KDE for a living has been one of the greatest privileges I’ve ever been blessed with — undoubtedly the most satisfying years of my career, and I have Blue Systems to thank for it.
Yeah for real! To be honest, in the beginning of this process, I was as surprised to learn about the opportunity as you may be while reading about it right now.
Now, I’ve been a business owner before, but admittedly only at a smaller scale, running a two-person 3D printer company from 2011 through 2014. In fact, some of you who were around for the early days of 3D printing and the RepRap project might remember a company bearing the similar name of “Techpaladin Printing“. That’s right, this was my company! Back then, we helped fellow community members people build MendelMax 3D printers (you can find an archived build guide of mine linked to on that page) from our parts and kits, starting with a humble order of 250 plastic Igus bushings — which at the time could only be purchased in commercial quantities, not at retail. It was my first serious exposure to FOSS (and FOSH!) principles in action, and also where I first fell in love with the movement.
Techpaladin is a much bigger business, of course — with a headcount of over a dozen spread across 7 countries and 2 continents, more complicated accounting, and a co-owner. There are a lot of moving parts; the setup process has been challenging for sure. But I think we’re up to the task!
And you should buy my new cryptocoin, too!
But seriously, setting up this enterprise has refocused my conviction that while organizing a business is real work that can be done well or poorly and should not be discounted, the true value in a company is generated by the workers — and those workers should be the overwhelming beneficiaries of that value. I’m still me, and my primary goal remains to propel KDE to world domination! Techpaladin is simply a new and powerful arrow in that quiver, particularly on the topic of helping people make careers out of KDE — a topic near and dear to my heart.
On a personal level, I fully intend to continue working on KDE software in my technical and organizational capacities, in addition to my new tasks managing the business. For example, you can see I’m still publishing This Week in Plasma, still doing technical work, still reviewing other people’s merge requests, and still triaging bug reports.
I’m sure I’ll make some dumb mistakes as I find my way on this journey, and be deservedly criticized for them. When that happens, I’ll try my best to learn from them and do better in the future. So thanks in advance for bearing with me!
Like Blue Systems, Techpaladin is a software consultancy, and clients can pay for work on KDE software. And we’re inheriting Blue Systems’ contract with Valve Inc. as our first client! So Techpaladin will continue to maintain and develop large amounts of KDE software relevant to the Steam Deck.
Why yes, as a matter of fact! If you’d like to sponsor a bug fix — or a new feature, or custom development work of any kind — do get in touch. Techpaladin draws from the same deep well of top Plasma talent that Blue Systems did.
Not at the moment. We just got started, but if things go well, we will be open to hiring! If and when that time comes, I’ll announce it publicly.
Isn’t it!? The world is a weird place, and if there’s anything I feel like it’s been trying to teach me over the past five months, it’s that you can’t really predict anything. I think all you can do is be flexible in the face of events, and try to make a positive difference within the sphere of what you do have influence over, so that’s what I’m aiming for here.
Thanks as always for your time, everybody, and let’s continue to propel KDE to ever greater heights together. Today I’m feeling even more optimistic that the absurd goal of getting KDE software onto every device on the planet is actually doable!
In the previous blog, you learned all about moving items within a single view, to reorder them.
In part 2, we are still talking about moving items, and still about inserting them between existing items (never overwriting items) but this time the user can move items from one view to another. A typical use case is a list of available items on the left, and a list of selected items on the right (one concrete example would be to let the user customize which buttons should appear in a toolbar). This also often includes reordering items in the right-side list, the good news being that this comes for free (no extra code needed).
Moving a row between treeviews, step 1
Moving a row between treeviews, step 2
Moving a row between treeviews, step 3
Example code for flat models and example code for tree models.
To allow dragging items out of the view, make sure to do the following:
☑ Call view->setDragDropMode(QAbstractItemView::DragOnly)
(or DragDrop
if it should support both).
☑ Call view->setDragDropOverwriteMode(false)
so that QTableView
calls removeRows when moving rows, rather than just clearing their cells
☑ Call view->setDefaultDropAction(Qt::MoveAction)
so it's a move and not a copy
To implement dragging items out of a model, you need to implement the following:
class CountryModel : public QAbstractTableModel
{
~~~
Qt::ItemFlags flags(const QModelIndex &index) const override
{
if (!index.isValid())
return {}; // depending on whether you want drops as well (next section)
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
}
// the default is "return supportedDropActions()", let's be explicit
Qt::DropActions supportedDragActions() const override { return Qt::MoveAction; }
QMimeData *mimeData(const QModelIndexList &indexes) const override; // see below
bool removeRows(int position, int rows, const QModelIndex &parent) override; // see below
};
More precisely, the check-list is the following:
☑ Reimplement flags()
to add Qt::ItemIsDragEnabled
in the case of a valid index
☑ Reimplement supportedDragActions()
to return Qt::MoveAction
☑ Reimplement mimeData()
to serialize the complete data for the dragged items. If the views are always in the same process, you can get away with serializing only node pointers (if you have that, e.g. for tree models) and application PID (to refuse dropping onto another process). Otherwise you can encode the actual data, like this:
QMimeData *CountryModel::mimeData(const QModelIndexList &indexes) const
{
QByteArray encodedData;
QDataStream stream(&encodedData, QIODevice::WriteOnly);
for (const QModelIndex &index : indexes) {
// This calls operator<<(QDataStream &stream, const CountryData &countryData), which you must implement
stream << m_data.at(index.row());
}
QMimeData *mimeData = new QMimeData;
mimeData->setData(s_mimeType, encodedData);
return mimeData;
}
s_mimeType
is the name of the type of data (make up a name, it usually starts with application/x-
)
☑ Reimplement removeRows()
, it will be called after a successful drop. For instance, if your data is in a vector called m_data
, the implementation would look like this:
bool CountryModel::removeRows(int position, int rows, const QModelIndex &parent)
{
beginRemoveRows(parent, position, position + rows - 1);
for (int row = 0; row < rows; ++row)
m_data.removeAt(position);
endRemoveRows();
return true;
}
☑ Call view->setDragDropMode(QAbstractItemView::DragDrop)
(already done if both views should support dragging and dropping)
To implement dropping items into a model (between existing items), you need to implement the following:
class DropModel : public QAbstractTableModel
{
~~~
Qt::ItemFlags flags(const QModelIndex &index) const override
{
if (!index.isValid())
return Qt::ItemIsDropEnabled;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable; // and optionally Qt::ItemIsDragEnabled (previous section)
}
// the default is "copy only", change it
Qt::DropActions supportedDropActions() const override { return Qt::MoveAction; }
QStringList mimeTypes() const override { return {QString::fromLatin1(s_mimeType)}; }
bool dropMimeData(const QMimeData *mimeData, Qt::DropAction action,
int row, int column, const QModelIndex &parent) override; // see below
};
☑ Reimplement supportedDropActions()
to return Qt::MoveAction
☑ Reimplement flags()
For a valid index, make sure Qt::ItemIsDropEnabled
is NOT set (except for tree models where we need to drop onto items in order to insert a first child).
For the invalid index, add Qt::ItemIsDropEnabled
, to allow dropping between items.
☑ Reimplement mimeTypes()
and return the name of the MIME type used by the mimeData()
function on the drag side.
☑ Reimplement dropMimeData()
to deserialize the data and insert new rows.
In the special case of in-process tree models, clone the dragged nodes.
In both cases, once you're done, return true, so that the drag side then deletes the dragged rows by calling removeRows()
on its model.
bool DropModel::dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent)
{
~~~ // safety checks, see full example code
if (row == -1) // drop into empty area = append
row = rowCount(parent);
// decode data
const QByteArray encodedData = mimeData->data(s_mimeType);
QDataStream stream(encodedData);
QVector<CountryData> newCountries;
while (!stream.atEnd()) {
CountryData countryData;
stream >> countryData;
newCountries.append(countryData);
}
// insert new countries
beginInsertRows(parent, row, row + newCountries.count() - 1);
for (const CountryData &countryData : newCountries)
m_data.insert(row++, countryData);
endInsertRows();
return true; // let the view handle deletion on the source side by calling removeRows there
}
Example code can be found following this link.
On the "drag" side:
☑ Call widget->setDragDropMode(QAbstractItemView::DragOnly)
or DragDrop
if it should support both
☑ Call widget->setDefaultDropAction(Qt::MoveAction)
so the drag starts as a move right away
On the "drop" side:
☑ Call widget->setDragDropMode(QAbstractItemView::DropOnly)
or DragDrop
if it should support both
☑ Reimplement supportedDropActions()
to return only Qt::MoveAction
When using QTableWidget
, in addition to the common steps above you need to:
On the "drag" side:
☑ Call item->setFlags(item->flags() & ~Qt::ItemIsDropEnabled);
for each item, to disable dropping onto items.
☑ Call widget->setDragDropOverwriteMode(false)
so that after a move the rows are removed rather than cleared
On the "drop" side:
☑ Call widget->setDragDropOverwriteMode(false)
so that it inserts rows instead of replacing cells (the default is false
for the other views anyway)
☑ Another problem is that the items created by a drop will automatically get the Qt::ItemIsDropEnabled
flag, which you don't want. To solve this, use widget->setItemPrototype()
with an item that has the right flags (see the example).
When using QTreeWidget
, you cannot disable dropping onto items (which creates a child of the item).
You could call item->setFlags(item->flags() & ~Qt::ItemIsDropEnabled);
on your own items, but when QTreeWidget
creates new items upon a drop, you cannot prevent them from having the flag Qt::ItemIsDropEnabled
set. The prototype solution used above for QTableWidget
doesn't exist for QTreeWidget
.
This means, if you want to let the user build and reorganize an actual tree, you can use QTreeWidget
. But if you just want a flat multi-column list, then you should use QTreeView
(see previous section on model/view separation).
If the user should be able to choose between copying and moving items, follow the previous section and make the following changes.
On the "drag" side:
☑ Call view->setDefaultDropAction(...)
to choose whether the default should be move or copy. The user can press Shift to force a move, and Ctrl to force a copy.
☑ Reimplement supportedDragActions()
in the model to return Qt::MoveAction | Qt::CopyAction
On the "drop" side:
☑ Reimplement supportedDropActions()
in the model to return Qt::MoveAction | Qt::CopyAction
The good news is that there's nothing else to do.
On the "drag" side:
☑ Call widget->setDefaultDropAction(...)
to choose whether the default should be move or copy. The user can press Shift to force a move, and Ctrl to force a copy.
Until Qt 6.10 there was no setSupportedDragActions()
method in the item widget classes (that was QTBUG-87465, I implemented it for 6.10). Fortunately the default behavior is to use what supportedDropActions()
returns so if you just want move and copy in both, reimplementing supportedDropActions()
is enough.
On the "drop" side:
☑ Reimplement supportedDropActions()
in the item widget class to return Qt::MoveAction | Qt::CopyAction
The good news is that there's nothing else to do.
While writing and testing these code examples, I improved the following things in Qt:
In the next blog post of this series, you will learn how to move (or copy) onto existing items, rather than between them.
The post Model/View Drag and Drop in Qt - Part 2 appeared first on KDAB.
Back this month with another update on the progress for our new design system in Plasma.
This update includes:
– Icon selection and request to submit bugs
– Icon review and changes
– Plasma Sprint updates
If you would like to participate in an open design project like ours, learn more about it here: https://community.kde.org/Get_Involve… Learn more about our organization:
• Facebook: KDE Community
• Twitter: @kdecommunity
• Mastodon: @kde@floss.social
• LinkedIn: KDE • Reddit: r/kde
• Lemmy: KDE Community
• Instagram: @kdecommunity
• YouTube: KDE Community
• PeerTube: KDE Channel
#FigmaIcons #IconDesign #FigmaTutorial #LearnFigma #FigmaTips #UIUXDesign #GraphicDesign #VectorArt #FigmaDesign #IconCreation #FigmaForBeginners #FigmaWorkflow #DigitalDesign #FigmaCommunity #FigmaIconDesign #DesignWithFigma #UXDesignTips #FigmaTipsAndTricks #IllustrationDesign #IconDesignTutorial #penpot #opensource #opendesign
Welcome to a new issue of "This Week in KDE Apps"! Every week we cover as much as possible of what's happening in the world of KDE apps. This time we will cover the past two weeks as I was traveling last weekend.
Last week we released KDE Gear 24.12.3, which concludes the 24.12 series of KDE Gear. 25.04.0 is right around the corner, with only a few days left before the beta and feature freeze. Aside from the numerous bug fixes and polishing going on, we also had some pretty big changes in Krita regarding advanced text editing options, KDevelop with support for the LSP protocol, some big UI changes in Dolphin, and a complete rewrite of systemDGenie.
Balló György added improvements to many Kirigami projects for when they run with the software rendering backend. Projects that have been improved include Kirigami and Kirigami Addons, but also many apps like Tokodon, Kaidan, Angelfish and more.
Volker wrote a small report about the recent improvements to KDE Apps on Android. You can find it on his blog.
We fixed an issue in KIO SFTP support where symlinks would be truncated (Kishore Gopalakrishnan, 25.04.0. Link), and another in KIO SMB support where shared resources from other computers on multiple LANs and virtual LANs were not displayed when using WSDD (Harald Sitter, 24.12.3. Link).
Another thing that got fixed was an issue where the report bug button would not open the report URL (Carl Schwan, KF 1.12.0. Link).
Balló György fixed restoring the hidden Elisa instance on file opening (Balló György, 25.04.0. Link), and Jack Hill fixed the spacebar play/pause action, as it was not being triggered when specific buttons had the focus (Jack Hill, 25.04.0. Link).
Pedro Hernández added an option to display hidden files (Pedro Hernandez, 25.04.0. Link), and we changed how image size integers were displayed to make them clearer in all languages. Previously, we displayed 1,024x1,024
. Now it is 1024x1024
.
Bart De Vries properly implemented single instance behavior (Bart De Vries, 25.04.0. Link).
Okular now supports, in addition to S/MIME based signatures, PGP/GPG based signatures. PGP signatures have the advantages that it is a lot easier to get a PGP key than a S/MIME key. Note that this feature is not yet enabled by default and for the moment only works between Okular users (Sune Vuorela, 25.04.0. Link).
Darby Johnston added support for OpenTimelineIO export and import using the C++ library. This allows importing and exporting projects files to/from other video-editing applications that implement this open standard (Darby Johnston supported by KDenlive fundraiser, 25.04.0. Link).
Wolthera van Hövell implemented basic support for the font-feature-settings CSS property in Krita. This allows tweaking the rendering of text based on OpenType font features (Wolthera van Hövell, Link). Wolthera wrote an excellent blog post on this topic, as well as covering the support of font variants mentioned two weeks ago. You can find the post on her blog.
Maciej Jesionowski added a global pen tilt direction offset, which can be helpful to make the brushes feel the same for right- and left-handed users (Maciej Jesionowski, Link).
The process of porting Krita to Qt6 is making good progress: the macOS version now compiles (Freya Lupen. Link), and the implementation of the tablet switching API for Windows is now using Qt APIs instead of a custom implementation (Dmitry Kazakov, Link).
In other news, Carl Schwan fixed the menubar visibility state being saved as non visible if the global menu option is turned on. This become an issue when turning off the global menu, as Krita's menubar wouldn't appear again (Carl Schwan, Link).
Allen Winter improved the agent selection dialog. Now the Ok button is only enabled when an item is selected and the search text field has a placeholder (Allen Winter, 25.04.0. Link).
Shubham Shinde added support for displaying holidays in the week view and the month view. Note that it is possible to disable this feature (Shubham Shinde, 25.04.0. Link 1, link 2 and link 3).
Tobias Fella fixed decrypting files with very long paths on Windows (Tobias Fella, 25.04.0. Link).
Milian Wolff optimized some code in Qt related to timezones to improve the performance of some serialization in Akonadi. (Milian Wolff, Qt 6.8. Link)
Volker Krause unified the formatting of temperature ranges and dynamic depending on the home country. Similarly, imperial speed units are shown for countries that use them (Volker Krause, 25.04.0. Link 1 and link 2).
Again Itinerary has increased the number of ticket types it supports and now handles multi-page 12go PDF tickets and Ghotel reservation emails.
Joshua Goins moved the "Explore rooms" button from the hamburger to the space drawer (Joshua Goins, 25.04.0. Link), added a dialog explaining what to do next when tapping "Verify this device" (Joshua Goins, 25.04.0. Link), and made joining remote rooms more reliable (Joshua Goins, 25.04.0. Link). Joshua also fixed a bug where emoji autocompletion would destroy the current message draft (Joshua Goins, 25.04.0. Link).
Meanwhile, James Graham improved the handling of switching link previews on and off (James Graham, 25.04.0. Link).
Niels Thykier added built-in support for the debputy
language server. This is used when writing Debian package (Niels Thykier, 25.04.0. Link).
Meanwhile, Joshua Goins improved the titles of terminal tabs and assigning an icon to them (Joshua Goins, 25.04.0. Link). Joshua also improved the UI of the compiler explorer integration. This includes polishing some strings, adding tooltips and fixing some padding issues (Joshua Goins, 25.04.0. Link).
KDevelop now support the Language Server Protocol (LSP) in addition to the native support for C++, PHP and Python. This reuses Kate's plugin, so, at the moment, it is only available when Kate is also installed (Igor Kushnir and Sven Brauch, 25.04.0. Link).
Jonathan Marten fixed a crash when double clicking on a terminal scroll bar (Jonathan Marten, 25.04.0. Link).
Natsumi Higa fixed the extraction of timestamps from 7-Zip archives, which now includes nanoseconds (Natsumi Higa, 25.04.0. Link).
Dolphin is having its looks tweaked and has a new icon with an actual picture of a dolphin inside it! (Darshan Phaldesai, 25.04.0. Link).
In the same vein, Akseli Lahtinen added a background to the navigation bar of Dolphin and Gwenview (Akseli Lahtinen, KF 6.12.0. Link).
And Nate Graham added a nicer split icon to the toolbar (Nate Graham, 25.04.0. Link).
In other Dolphin news, Akseli Lahtinen fixed a crash when opening a new tab with search (Akseli Lahtinen, 24.12.3. Link).
systemDGenie was completely rewritten using QML. The new version also relies a lot less on blocking DBus calls (Carl Schwan, 1.0.0. Link).
Xuetian Weng sorted a security issue and passwords copied from the KWallet Manager are no longer visible in the clipboard history of Plasma (Xuetian Weng, 25.04.0. Link).
Balló György fixed the font size of the result view. The font size was stored as point size, but passed as pixel size, causing that the actual font size is smaller than it should be (Balló György, 25.04.0. Link). Balló also fixed the background color of some views when switching to a dark theme (Balló György, 25.04.0. Link).
Max Brazhnikov Added support for non-latin alphabets (Max Brazhnikov, 25.04.0. Link).
Hy Murveit added an altitude graph to the scheduler table (Hy Murveit, Link)
Mark Penner made the text elide in the RSS entry list so that the buttons are always visible (Mark Penner, 25.04.0. Link), and Balló György set the default format to import and export feeds as OPML (Balló György, 25.04.0. Link).
José Rebelo added the possibility of filtering out notifications from the Android work profile (José Rebelo, Link).
Kai Uwe Broulik added an option to explore in Filelight (Kai Uwe Broulik, 25.12.0. Link), and icons to the context menu entries (Kai Uwe Broulik, 25.12.0. Link).
Balló György fixed the windows activation when the current window is in the system tray (Balló György, 25.04.0. Link).
Fabio Bas added a setting for desktop scale and device scale (Fabio Bas, 25.04.0. Link), while Fabian Lesniakd disabled Kerberos support completely, since it turned out that having a broken support for it was worse than no support at all (Fabian Lesniak, 25.04.0. Link).
Balló György fixed the name of the generated optimized images, and now the suffix is appended before the file extension (Balló György, Link).
This blog only covers the tip of the iceberg! If you’re hungry for more, check out Nate's blog about Plasma and be sure not to miss his This Week in Plasma series, where every Saturday he covers all the work being put into KDE's Plasma desktop environment.
For a complete overview of what's going on, visit KDE's Planet, where you can find all KDE news unfiltered directly from our contributors.
The KDE organization has become important in the world, and your time and contributions have helped us get there. As we grow, we're going to need your support for KDE to become sustainable.
You can help KDE by becoming an active community member and getting involved. Each contributor makes a huge difference in KDE — you are not a number or a cog in a machine! You don’t have to be a programmer either. There are many things you can do: you can help hunt and confirm bugs, even maybe solve them; contribute designs for wallpapers, web pages, icons and app interfaces; translate messages and menu items into your own language; promote KDE in your local community; and a ton more things.
You can also help us by donating. Any monetary contribution, however small, will help us cover operational costs, salaries, travel expenses for contributors and in general just keep KDE bringing Free Software to the world.
To get your application mentioned here, please ping us in invent or in Matrix.
Make sure you commit anything you want to end up in the KDE Gear 25.04
releases to them
Next Dates
March 13 2025: 25.04 Freeze and Beta (25.03.80) tag & release
March 27, 2025: 25.04 RC (25.03.90) Tagging and Release
April 10, 2025: 25.04 Tagging
April 17, 2025: 25.04 Release
https://community.kde.org/Schedules/KDE_Gear_25.04_Schedule
Here’s an overview of recent work around the Android platform support for KDE Frameworks and KDE applications. Since the last update there have been improvements in localization and packaging, and an encounter with a bizarre calling convention issues deep down in the Android stack.
Starting with SDK 33 Android allows apps to opt-in to application-specific language settings. That is, you can select a different language for an application than for the platform itself. This is for example useful when using a language the application doesn’t support.
For this to work applications need to indicate which languages they support, which can be
done with minimal changes to the build.gradle
file:
android {
...
androidResources {
generateLocaleConfig true
}
}
As well as adding android/res/resources.properties
with the following content:
unqualifiedResLocale=en-US
See also this example in Itinerary.
We fixed bundling (MR 488) and loading (MR 135) Qt’s own translation catalogs, and applied the same fallback language fixes described last time for those as well (MR 136).
This should fix some small but somewhat prominent gaps in the translation coverage, such as standard dialog button texts.
The foundational changes to support language changes during application runtime have
meanwhile landed in both Qt and KDE Frameworks. To benefit from this
make sure your application is using the new API for setting up its KLocalizedQmlContext
:
KLocalization::setupLocalizedContext(&engine);
More QML API has also been updated to support this, such as the formatting functions in KCoreAddons (MR 474).
Android has a system setting to force a 24h time format even in locales that would
otherwise use an AM/PM format. With Qt 6.8 this is considered by QLocale
, ie.
all its date/time formatting functions will automatically follow this
(CR 600295).
We have reworked the APK version code generation to comply with the various ordering constraints posed by Android, F-Droid and Google Play also when building APKs for multiple architectures in parallel in the CI system.
APK version codes need to:
Our previous approach managed to only guarantee the first constraint, for all others it depended in which order the CI was building things, ie. it was effectively random. Additionally, the version code logic was copy/pasted into all applications.
Starting with KDE Frameworks 6.12 this has been improved by ECM providing a Gradle include file with version code computation that satisfies all of the above constraints (MR 513, MR 514).
What remains in the application build.gradle
file then is the following:
apply from: '../ecm-version.gradle'
...
android {
...
defaultConfig {
...
versionName ecmVersionName
versionCode ecmVersionCode
manifestPlaceholders = [versionName: ecmVersionName, versionCode: ecmVersionCode]
}
}
The Qt version used for CI/CD builds and thus also the release APK packages has been updated to 6.8. What sounds like and should be a relatively straightforward process was unfortunately unusually bumpy.
There has also been work towards updating to SDK 35 and NDK 27, by fixing numerous build errors across the stack caused by the newer versions (list of MRs).
We aren’t quite there yet though, as the changes to window insets/edge-to-edge mode in Android 15 might require new API in Qt 6.9 to prevent our application from rendering behind to Android status bar. Attempts to find a workaround for this led to discovering the following issue.
For interfacing with Android’s Java-based platform API Qt heavily relies on the Java Native Interface (JNI), a way for C++ and Java code to call each other. JNI is very fundamental for Android and Java in general and is decades old technology, ie. usually not a thing you’d expect to change or break.
And yet, that’s exactly what we observed under certain conditions in December last year: When calling native functions from Java code with floating point arguments on Android 15 and x86_64 the arguments arrived corrupted on the native side. One of the calls affected by this was passing the screen geometry to Qt, which arrived there as negative values. That is physically impossible of course, and resulted in all kinds of spectacular UI breakage.
This is particularly tricky to track down as for normal debugging tools the breakage happens behind the scenes of a method call, something that is usually seen as an atomic step not able change any data. Instead it gets you into the dark magic of platform-specific calling conventions.
While we still haven’t managed to pinpoint the change in Android causing this, the best guess at this point
is that an optimization in Android’s JNI implementation missed (or intentionally ignored) that
the way floating point arguments are passed to native functions differs between regular and va_arg
functions
on x86_64. The JNI specification suggests that the latter is supposed to work as well, and that’s the thing
that broke here.
That combination is probably quite rare, x86_64 is practically only
relevant for the emulator, and you’d only use va_arg
functions as a last resort in generic code normally.
And that’s what Qt did in Q_DECLARE_JNI_NATIVE_METHOD
.
For the full story see QTBUG-132410. If you look at the names and times there, the Qt chief maintainer himself implementing a fix on Christmas Day gives you an idea of the severity of this.
CR 613563 reproduced the issue in the Qt CI,
CR 613552 works around it by replacing the
use of va_arg
functions with clever template magic.
We still have plenty more to do regarding Android platform integration. The currently probably most pressing issues are the following I think:
If you are interested in Android integration for KDE applications, feel free to join us in the #kde-android Matrix channel!
Welcome to a new issue of "This Week in Plasma"! Every week we cover as much as possible of what's happening in the world of KDE Plasma and its associated apps like Discover, System Monitor, and more.
This week we took a break from new features and put on our bug-fixing hats, squashing a very large number of bugs and annoyances, because it's important not to break things when you move fast! Some nice UI refinements landed as well.
You can now control whether a window has a titlebar and frame from its Task Manager context menu, like you can with various other window tweaks. (Kai Uwe Broulik, link)
The Digital Clock widget now shows a nicer-looking font picker dialog when you customize the text style of the clock; we went back to the older style after Qt 6 changed the default to something that isn't as suitable for our purposes. (Nate Graham, link)
Improved the way screens are presented to remove the technical information in cases where it isn't needed to distinguish screens from one another. (Oliver Beard, link)
It's once again possible to configure the lock screen's clock to disappear when the rest of its UI fades out, providing once again for the possibility of a screensaver-like experience. (Kai Uwe Broulik, link)
Bluetooth devices are no longer inappropriately shown in the System Tray popup when Bluetooth is disabled but the wireless adapter is still powered on, which is a state that some devices can get into. (Vlad Zahorodnii, link)
Improved the ordering of search results in the "Add keyboard layout" dialog. (Bharadwaj Raju, link)
Fixed two serious issues that could make KWin crash on login or fail to allow login at all on systems with certain types of monitor arrangements, on distros that ship user software with asserts turned on. (Xaver Hugl, link 1 and link 2)
Finally figured out and fixed for good the issue that could cause the lock screen to sometimes be all black on X11. (David Edmundson, link)
Fixed a subtle way the screen locker could fail to respond to keyboard actions with certain configurations applied. (David Edmundson, link)
Fixed one of the top 20 Plasma crashes — this one a case of crashing after waking from sleep. (Fushan Wen, link)
Fixed a strange crash that could happen when configuring Plasma to have multiple "Notifications" widgets. We traced it to a Qt bug and implemented a workaround in Plasma, and then the Qt bug was also fixed! (Marco Martin and David Faure, link)
Fixed a case where Plasma could crash when closing apps by middle-click (this is off by default) on the Task Manager while their window previews were visible. (Harald Sitter, link)
The names of some NVIDIA GPUs are once again shown correctly in Info Center, after this regressed due to a related change to show nicer GPU names didn't work 100% for all GPUs. (Harald Sitter, link)
Fixed a recent regression that made it harder to see release notes for updateable Flatpak and Snap apps in Discover. (Ismael Asensio, link)
Fixed a recent regression that made the "Legacy X11 app scaling" setting not take effect immediately, as it was supposed to. (Xaver Hugl, link)
Rapidly clicking the "Next" or "Previous" buttons on the calendar in the "Calendar" and "Digital Clock" widgets now switches to the appropriate month, year, or decade. (Matthias Tillman, link)
Disabling animations globally no longer makes it impossible to configure panel widgets while in panel edit mode using their hover pop-ups. (Nate Graham, link)
Fixed two color scheme issues: one that would make menu text look wrong with creative color schemes that have headers colored differently from the rest of the window, and another that would let an old color scheme's header colors briefly remain visible after changing the color scheme. (Evgeniy Harchenko and David Redondo, link 1 and link 2)
Fixed some visual glitches visible on blurred Plasma widgets that some people were experiencing with some GPUs when using the new "Prefer color accuracy" setting. (Xaver Hugl, link)
KRunner no longer becomes an unreadable mess when the text you enter is so long that it starts to overflow off the right edge. (Nate Graham, link)
Fixed a keyboard accessibility issue on System Settings' "KWin Rules" page. (Ismael Asensio, link)
Fixed keyboard navigation working incorrectly in the "Application Dashboard" widget when using a right-to-left language. (Christoph Wolk, link)
Discover no longer tries and fails to uninstall end-of-life Flatpak runtimes that are still in use by apps, displaying an ugly and un-actionable error message in the process. (Harald Sitter, link)
Fixed a small visual glitch in the Global Menu widget seen when moving the pointer between open menus. (Niccolò Venerandi, link)
Implemented support for battery charge thresholds on more devices. (Jakob Petsovits, link)
Further improved the way colors are displayed on screen when using Night Light on systems with Intel GPUs. (Xaver Hugl, link)
Forcing "Adaptive Sync" to be on no longer reduces the refresh rate of certain screens under certain circumstances. (Xaver Hugl, link)
Added little warning messages when you disable power management, complying with new EU regulations taking effect in two months. This is what happens when you become important, folks! (Kai Uwe Broulik, link)
Copying text in LibreOffice Writer no longer inserts anchor links into it, shown by little gray brackets around letters. This isn't a new thing, and not really a bug, either; it was happening for ages and ages, but nobody ever noticed until a recent change in LibreOffice to surface these links visually. (Fushan Wen, link)
Fixed a couple of behavioral anomalies when manually manipulating windows in the stacking order. (Jarek Janik, link 1 and link 2)
Fixed a memory leak found in Plasma. (Fushan Wen, link)
The kscreen-doctor
tool can now be used to toggle HDR mode on and off, in addition to its existing abilities to enable or disable it. (Xaver Hugl, link)
Put a lot of effort into reducing Plasma's log spam caused by binding loops and other warnings. (Christoph Wolk, link 1, link 2, link 3, link 4, link 5, link 6, link 7, link , link )
KDE has become important in the world, and your time and contributions have helped us get there. As we grow, we need your support to keep KDE sustainable.
You can help KDE by becoming an active community member and getting involved somehow. Each contributor makes a huge difference in KDE — you are not a number or a cog in a machine!
You don’t have to be a programmer, either. Many other opportunities exist:
You can also help us by making a donation! Any monetary contribution — however small — will help us cover operational costs, salaries, travel expenses for contributors, and in general just keep KDE bringing Free Software to the world.
To get a new Plasma feature or a bugfix mentioned here, feel free to push a commit to the relevant merge request on invent.kde.org.
So, after my last blog post, I ended up taking another few months to get the fonts branch just right, but now we have font resource that can be tagged, filtered and searched upon.
After that, I needed my next text editing project to be a bit more manageable. Given that I had already made some head start on it at the beginning of last year, I continued with UI for the OpenType features.
Usually, OpenType features are explained away as “that’s for ligatures and stuff”, which, while not incorrect, is maybe a little simple. “It enables advanced typographic features” is a little more correct, but it makes OpenType feature support sound less rudimentary than it really is these days.
What might be more clear is to think of a font file as a mapping between input characters and their glyphs. This is fine for simple Latin. But what if you want to show Arabic connected? Well, then you need a second table to keep track of the glyphs for start, middle and end of a word, and substitute the correct glyph as necessary.
Or maybe you want to have kerning, so that A and V nest into each other nicely. Another table for that then, that keeps track of the position adjustment between two consecutive glyphs.
How about small caps? Substitution table. Dynamically placing diacritics? Positioning table. Cyrillic has different glyph traditions in Serbia and Bulgaria, similarly for Han script use in East-Asia: Substitution table. Han script is usually typeset in mono space, but when two brackets follow one another, they often have extraneous white space that should be removed: Positioning table. These are all OpenType features.
The more you look into it, the more it becomes clear that if you want your text layout to support more than plain English, you will need to allow these extra tables to be used and read through. This is in short what Harfbuzz does for us. You can enable and disable these features by taking their name (A 4 letter tag), and indicating to Harfbuzz you want them enabled for a given section by sending a number (0 for off, 1 for on… and 2, 3, 4, […] 256 for indicating which alternate you’d like if the font has multiple alternates available for that feature).
Some of these features are enabled by default, and the basic text layout will process them just fine. However, others are optional, and within CSS all of them can be turned off and on at the typesetters’ wish. Which brings us to the widgets.
There’s two types of CSS opentype toggles. The first of these are the font-variants
, which have a somewhat confusing name in this day and age of OpenType variable fonts, but at the time they were named font-variants were limited to Small Caps, and expected to be separate font files.
The font-variant features more of a guidance suggestion, meaning that you turn them on or off for a piece of text, unrelated to whether the current font actually supports the feature in question. The idea being that you could set a different font elsewhere in the text, and that if this font supports those features, they could be controlled this way.
This means that the UI for these features is somewhat straight forward and unopinionated, being a collection of drop-downs and check boxes. I renamed them “glyphs:” in the UI to avoid confusion with Variable fonts, which is also possible because the majority of them represented which glyphs are being used.
font-variants
only cover the most common features, and as of writing, there’s over 120 registered OpenType feature tags. CSS allows controlling this via the second type of properly “font-feature-settings”. A property that wants you to be very specific about which tag you want to enable, and whether you want to have it not just enabled, but also which sub index of the feature you would like to enable.
Now, there’s a bit of a problem here: 120 features is a bit much. Furthermore, two of those registered features, Character Variants and Stylistic Sets, are registered 99 and 20 times respectively, meaning the total is closer to over 230 features. And, further furthermore, fonts may have custom OpenType feature tags.
And that’s not the only problem: Access All Alternates, Stylistic Alternates and Stylistic Sets are very common features, but the way they are configured in CSS as a font-variant
feature is somewhat complex, and to have each manually enabled inside the OpenType Features
widget is going to feel very clunky for artists.
For these reasons, I ended up building two controls for this CSS property. A main widget for the text property docker that allows artists to enable and disable any OpenType feature that can be found inside the font, and the second being a glyph palette, that allows artists to select alternate glyphs.
The glyph palette was actually made first, so lets go over that. It is in effect a character selection map that allows artists to select alternates to the current glyph or to any glyph inside the font. Filtering can be done with Unicode blocks and search.
It uses KoFontGlyphModel, a QAbstractItemModel, that collects all the available characters inside the font, as well as their Unicode variations (Unicode variations are an extra code point added behind a character to indicate it needs to be a specific version of that glyph. It’s main use is to ensure people’s names are written with the correct glyph variant).
It then takes the locale of the text, and uses those to go over the OpenType tables with Harfbuzz. The locale of the text, or “text language” is necessary because some OpenType features are only available for certain locales. Furthermore, the aforementioned Character Variants and Stylistic Sets may have been named inside the font, meaning that it also takes the interface languages to get the correct name for the current localization of Krita.
Of course, using these alternate names means we need default names first. Which is why I also spend some time on creating a factory where each known OpenType tag is stored with its proper name from the official registry and a hand written summary of the feature for the tool tip. These can now be localized.
Then when we have the feature, we go over the glyphs marked by the table and if that glyph coheres with a Unicode code point, add the table as a potential sub glyph for that Unicode value.
Now here another problem rears its head: We need to know which glyph coheres with which Unicode code point, and while for basic values that isn’t a problem, it is when decomposition comes into play.
Decomposition in this case, is a feature that allows for replacing a given glyph with two other glyphs. A reverse ligature, if you will. It is frequently used to match Unicode decomposition: Ä according to Unicode can be decomposed into A (U+0041) and ◌̈ (U+0308, combining diaeresis). So then, the glyph for Ä can be decomposed into those two glyphs. Afterwards, OpenType allows positioning that diaeresis accurately with the mark positioning feature. This is useful, because we can then take that A glyph, and use things like the Small Caps feature, or a Stylistic Set to turn it into a small A or a decorative A, and as long as these alternate glyphs have been configured for mark positioning, they’ll by themselves support Ä.
So that’s pretty neat. But the problem is that Harfbuzz doesn’t provide enough information for me to discover how a glyph gets decomposed. Meaning that for fonts that are structured this way, I can’t tell whether style sets or the like can be applied to these glyphs, so these don’t show up in the character map. I have a similar problem with ligatures, but that is also compounded by having trouble with the user interface.
For the glyph palette, the way you use it is either by using the glyph alternates, where double clicking one will replace the current grapheme (that’s a set of Unicode values that is often treated as the smallest editable chunk of text) with one that either has the appropriate Unicode variation selectors attached, or one that has the appropriate OpenType features enabled.
The other option is to use the character map, which is much like character maps in other software, allowing you to scroll over all available Unicode values in a font, and sorting them by Unicode block, or searching them. Clicking on a glyph with variants ops out a context menu with the glyph alternates.
The glyph palette itself is written with QML, but because the rest of Krita is not in QML, it is embedded into a QQuickWidget, that is inside a QDialog, which in turn means the context menu needed to be inside a QQuickWidget inside a QPopup, because QQuickWidget will clip any QML pop-up items. QML side, we use DelegateModel to show the child indices of a given character map index.
I’m not sure yet how ligatures would be handled here, maybe list them for each glyph, or maybe have a separate model that shows up underneath the glyph alternates and only shows for the current text. There’s also the fact that stylistic alts and the like can apply to ligatures, so that’s another thing to consider. A similar issue is with emoji zero-width-joiner sequences. This is stuff like “fireman + woman + Fitzpatrick skin tone modifier 5” = . This is typically implemented as a kind of ligature as well, and while Unicode keeps a list of these, I’d prefer to get them from the font.
For the “OpenType features” control in the text properties docker, we reuse the glyph model, but this time its only to figure out which features are available in the font. Because CSS allows for font fallback, we only do this for the first font, but also allow setting any other officially registered OpenType feature on or off. It also shows a sample for the given feature. This widget is mostly useful for the stylistic sets and the positioning features.
Now, setting up the glyph model can get quite slow, so some trade-offs were established:
One of the things that struck me when writing the original svg text layout post a few years back is that a decade ago, you’d really boast about your OpenType support, but nowadays, OpenType support is so rudimentary, it didn’t make sense to dwell on it in that post. This might also be a consequence by how easy Harfbuzz makes using OpenType these days.
That meant I really wanted to get the UI for this feature nice. There was a big post over a decade ago by a UI designer doing UI for free software, where he went into extensive detail about how most software implementing controls for OpenType features is really bad at communicating whether the feature does anything. I think I managed to somewhat get that part working right.
Still, the glyph palette could use more love, and I really need to sit down for the whole ligature UI issue. I’m pretty happy with it none the less, and it is very hackable, meaning that it doesn’t necessarily need to be me personally improving it.
I do need to really get going on that language selector though…
The code for retrieving the OpenType tables was largely based on Inkscape’s, and then extended. Inkscape doesn’t test on language, and only tests for substitution features, while we test on both substitution and positioning features. Similarly, Inkscape’s was written in a time when Harfbuzz could only give information about whether a feature could be turned only on or off, but not whether it had multiple alternates, so it is not yet able to do that.
Of interest is that Inkscape does show a few ligatures, but the only reason those are visible is that there’s a handful of ligatures that are encoded into Unicode in the “Alphabetic Presentation Forms” block. Fonts that implement ligatures tend to also setup these Unicode values, but this is not self-evident, which is why I’d prefer not doing this.
(As a random factoid: Adobe’s Smart Quote feature will use these Unicode encoded ligatures when the font isn’t able to provide them via OpenType.)
I did manage to get ligature samples by simply testing every combination of glyphs that Harfbuzz could tell me were probably relevant to a given table, but this was slow, leading to a 5~ second initialization time on a feature heavy font like Junicode. Maybe the glyph model code can be at some point modified to allow incremental loading, though that wouldn’t provide me a quick sample text in the text properties docker…
I feel I should probably mention that OpenType isn’t the only technology that provides shaping. Apple’s Advanced Typography Tables (ATT) and the Graphite shaping language are existing alternatives, but OpenType is far more popular than either, and the CSS working group doesn’t give much guidance on how to use anything but OpenType.
Qt currently has two UI toolkits: QML and QWidget. The former uses the terminology “Item” instead of “Widget” to refer to UI controls. I find this somewhat difficult to get used to, so when I don’t prepend a widget name with Q, assume that I mean a generic UI control. I think most people never even consider what the different UI bits are called, so usually it isn’t a problem.
Let’s go for my web review for the week 2025-10… somehow this one is really packed with content. Brace yourselves!
Tags: tech, culture, streaming, vendor-lockin
Looks like I’m a digital packrat of some sort! There are reasons behind it and it’s well explained.
https://www.404media.co/the-digital-packrat-manifesto/
Tags: tech, blender, foss, movie
Behind the movie this is a big win for Blender. It proves Blender is viable for full length movies at this point. The movie was nice too. :-)
https://www.reuters.com/lifestyle/flow-wins-best-animated-feature-film-oscar-2025-03-03/
Tags: tech, foss, politics, culture
Interesting piece, we indeed need to move beyond from the “for hackers by hackers” mindset. I don’t even think it was really the whole extent of the political goals when the Free Software movement started. Somehow we got stuck there though.
https://tante.cc/2025/03/03/who-is-free-software-for/
Tags: tech, web, search, attention-economy
I admit I’m more and more tempted to pay for my search service as well. It’s unfortunately not FOSS… But it’s not like the alternatives are better there either anyway.
https://timharek.no/blog/kagi-review/
Tags: tech, journalism, politics
In case it wasn’t clear yet that the tech industry was eminently political, this editorial drives the point home. It’s also a good reminder that it’s been the case for a long while.
https://www.techdirt.com/2025/03/04/why-techdirt-is-now-a-democracy-blog-whether-we-like-it-or-not/
Tags: tech, self-hosting, infrastructure, cloud
Or why you need to own at least some part of your infrastructure.
https://mental-reverb.com/blog.php?id=15
Tags: tech, browser, attention-economy, privacy, microsoft
The writing was on the wall. This is an unsurprising development but Edge users should know where it’s going…
https://www.neowin.net/news/microsoft-begins-turning-off-ublock-origin-and-other-extensions-in-edge/
Tags: tech, web, browser, webassembly
Is it the future of web browsers? Maybe… I’m not sure this would be a good thing though.
https://joeyh.name/blog/entry/WASM_Wayland_Web_WWW/
Tags: tech, ai, machine-learning, culture, criticism
Sure it makes generating content faster… but it’s indeed so bland and uniform.
https://hey.paris/posts/genai/
Tags: tech, ai, machine-learning, gpt, cognition, neuroscience, science, research
Friendly reminder that AI was also supposed to be a field about studying cognition… There’s so many things we still don’t understand that the whole “make it bigger and it’ll be smart” obsession looks like it’s creating missed opportunities to understand ourselves better.
https://arstechnica.com/science/2025/03/ai-versus-the-brain-and-the-race-for-general-intelligence/
Tags: tech, ai, machine-learning, gpt, nlp, data
This is one of the handful of uses where I’d expect LLMs to shine. It’s nice to see some tooling to make it easier.
https://simonwillison.net/2025/Feb/28/llm-schemas/
Tags: tech, cpu, amd, security, complexity
Nice exploration of the microcode patching flaw which was disclosed recently. This gives a glimpse at the high level of complexity the x86 family brings on the table.
https://bughunters.google.com/blog/5424842357473280/zen-and-the-art-of-microcode-hacking
Tags: tech, system, hardware, kernel
Nice post explaining the need of ACPI or Device Tree and how they are leveraged by kernels.
https://blogsystem5.substack.com/p/hardware-autoconfiguration
Tags: tech, filesystem, system, performance, multithreading, linux, apple
Nice performance comparison of file handling in multithreaded context. It’s surprising how slow MacOS seems to be there.
https://lemire.me/blog/2025/03/01/how-fast-can-you-open-1000-files/
Tags: tech, multithreading, safety
Another illustration that with race conditions all hell can break loose. It’s not only about data corruption or deadlocks. This case is explored in depth which is nice, also compared across several languages.
https://josephmate.github.io/2025-02-26-3200p-cpu-util/
Tags: tech, git, tools, version-control
There are pros and cons to using a forge, same thing when not using a forge. Let’s not forget you don’t have to use one though. Also this piece mentions git bundles which I didn’t know about, it looks interesting.
https://www.chiark.greenend.org.uk/~sgtatham/quasiblog/git-no-forge/
Tags: tech, static-analyzer
Looks like an interesting toolkit to make your own code checkers.
Tags: tech, programming, rust
A long piece which explore the reasons why Rust is likely not the best pick for enterprise software. It’s niche is clearly system programming but beyond that and because of its qualities in that space it quickly become a sharp and dangerous tool.
https://www.bartoszsypytkowski.com/is-rust-a-good-fit-for-business-apps/
Tags: tech, rust, programming, memory
This is an important concept in Rust… but clearly it’s harder to grasp than you’d expect.
https://ntietz.com/blog/rust-lifetimes-learning/
Tags: tech, data, programming, science
Interesting class of data structures with funny properties. Looks like there’s a lot to do with them.
https://blog.startifact.com/posts/succinct/
Tags: tech, python, programming
Nice little Python trick using bidirectional generators.
https://mathspp.com/blog/binary-search-as-a-bidirectional-generator
Tags: tech, language, translation, complexity
Translation and localisation is a complex topic too often overlooked by developers. This is a modest list of widespread misconceptions. If you get in the details it get complex fairly quickly.
https://www.lexiconista.com/falsehoods-about-languages/
Tags: tech, problem-solving, debugging
An excellent article, that troubleshooting skill is really important in many fields… In particular software engineering. It’s hard to teach and learn but it makes all the difference.
https://www.autodidacts.io/troubleshooting/
Tags: tech, programming, craftsmanship, technical-debt
Makes sense, the “boyscout rule” has a psychology impact as well.
https://blog.danieljanus.pl/2025/03/02/cleaner-codebase/
Tags: tech, engineering
It like this parallel. The bigger the endeavour, the more complexity… And that will require thinking in very different ways for each order of magnitude.
https://taylor.town/next-two-zeroes
Tags: tech, engineering, management, leadership
There’s clearly a tension on that topic and the expectations from engineering managers tend to change over time. I like the proposed answer here and the distinction made between writing code and being in the code.
https://www.theengineeringmanager.com/growth/should-managers-still-code/
Tags: neuroscience, cognition, research
Interesting study even though it bears some important limitations. Still it seems to indicate that one shouldn’t rest on its laurels and keep practicing cognitive skills even when older (actually might have to get started in the 20s latest).
https://www.science.org/doi/full/10.1126/sciadv.ads1560?af=R
Bye for now!