Skip to content

Monday, 16 May 2022

MeeraNew is the default Malayalam font for Fedora 36. I have just released a much improved version of this libre font and they are just built for Fedora 36 & rawhide; which should reach the users in a week of time. For the impatient, you may enable updates-testing repository and provide karma/feedback.

Fig. 1: MeeraNew definitive-script Malayalam font version 1.3.

Two major improvements are present in version 1.3

  1. Improved x-height to match RIT Rachana, the serif counterpart. This should improve readability at default font sizes.
  2. Large improvements to many kerning pairs including the above-base mark positioning of dotreph (0D4E) character (e.g. ൎയ്യ), ി (0D3F), ീ (0D40) vowel symbols (e.g. ന്റി), post-base symbols of Ya, Va (e.g. സ്ത്യ) etc.

The font source and OTF/TTF files can be downloaded at Rachana website or at GitLab.

Sunday, 15 May 2022

For FreeBSD things, there are four bug lists I keep track of; those are the “important bits” for me. It’s my bugs, and CMake bugs, and desktop bugs, and KDE bugs. Four lists, and sort-of-easy to query from FreeBSD’s bugzilla. I sometimes post to the socials a “daily buggle” of the counts of those lists. That started as a spoof of Wordle posts (I prefer Worldle myself) but has now grown to a tool of its own.

Here are the four bug lists I care about:

  • My bugs, which is bugs I have filed or been assigned. Stuff that is important for me personally.
  • CMake bugs, which are bugs that mention CMake. These may be CMake bugs, or may be ports-that-need-CMake attention.
  • Desktop bugs, bugs assigned to the desktop@ team. This might be desktop-basic infrastructure, or might be GNOME things because there’s no dedicated GNOME team.
  • KDE bugs, bugs for the KDE team. This includes CMake, Qt, KDE Frameworks, KDE Plasma and KDE Gear.

There is some overlap between the lists: CMake bugs are often on the KDE list as well.

Each of these bug lists can be read in CSV mode, leading to a format of one-line-of-headers and then a single line per bug. So for obtaining bug counts, I could use curl, then pipe to wc -l and subtract 1. Or Python. Or, who knows, awk and kio-fuse to read the web query as a file into awk. There anre many possibilities, so I arbitrarily chose Rust to implement a tool to do the fetching for me.

I’ve been intending to learn a little Rust for some time. Not particularly for production use, but as a what-is-this-about project it’s fine. It’s been a long time since I picked up a new programming language and I notice that something like Rust by Example just pisses me off. Along that path lie terrible copy-paste programs, and since I wrote way too much unwrap() in this program, I suspect I’m Doing It Wrong as well.

Buggle is my little project for doing Bugzilla queries (for FreeBSD anyway) and then Twitting about it. It’s also my project for learning some Rust. Probably it should grow something more Free Software friendly, like Matrix-posting, instead.

I’m not sure that Buggle is usable for anyone else: it needs tokens (both for the application and for user access) which I have stored locally.

I’m not sure that Buggle is usable for anyone else: it feels like largely glue code, written over four days of pointedly-not-reading-enough-documentation, (about the language) and feeling frustrated by the documentation that there is (for the libraries). At this point I certainly Have Opinions (and a 1.9GB build directory). I’ll be returning to Rust some other time. In the meantime, Buggle will be tweeing about my C++ bug-counts.

Saturday, 14 May 2022



Commercial release announcement: 

OpenSource release announcement:


I want to personally extend my gratitude to the Commercial users of Qt for beta testing Qt 5.15.4 for the rest of us.


The Commercial Qt 5.15.4 release introduced some bugs that have later been fixed. Thanks to that, our Patchset Collection has been able to incorporate the reverts for those two bugs that affected Android and Windows and the Free Software users will never be affected by those!

Time for another KDE Frameworks 6 update! Since the last one we made significant progress on getting Plasma to build, which also clears the way for properly styled and platform integrated Qt6-based applications.

KDE Frameworks

Since about a month ago the second to last Framework is also building with Qt 6 and has CI coverage for that. This was plasma-framework, which enabled a lot of progress in the Plasma modules build on top.


There’s also plenty of changes going into applications to prepare for the transition to 6. This is usually done in the same fashion as for Frameworks and Plasma, alongside the 5 code without compromising that, to identify potential issues/risks/challenges as early as possible.

For some applications like Kate this has meanwhile even progressed to a somewhat working state, as described in a post by the Kate team.


Of the 51 Plasma repositories relevant for Plasma 6, 29 have already CI coverage for 6, another 10 are building but depend on still pending changes or other modules not available in the CI yet. For a more detailed overview, see this tracking task.

For the rest of the Plasma modules it’s mostly down to the following remaining issues:

  • Use of the removed QDesktopWidget, in particular creative uses such as workarounds for old problems that need careful case by case assessment and occasionally some archaeology.
  • Other removed API in Qt 6 or KF6 without a straightforward replacement. This can be seemingly simple cases like the QNetworkAccessManager::NotAccessible enum, or more complex things like KServiceTypeTrader.
  • A few remaining cases of low-level OpenGL or event handling code in KWin.


If you want to help, here’s a quick summary on how to build with Qt 6 again, given you are familiar with building with Qt 5.

The main difference is the need for the following additional CMake arguments:


This might seem a bit redundant and unnecessarily cumbersome, and indeed not all of those arguments are needed by all modules. But it’s easier to just use the superset everywhere. And of course all of that will go away once we switch to 6 exclusively.

If you are using kdesrc-build, that also provides configurations for several modules sets already. Those not only contain the necessary build options, but also list the modules that are expected to build already. Include kf6-qt6-build-include instead of kf5-qt5-build-include to use those.

Both approaches assume you do have Qt 6, from distribution packages or self-compiled, and you point CMake to that if it’s not in the default search location.

Also for both cases, a few words of caution:

  • This is only meant to support the transition to 6, and is only aimed at people actively working on this. It is still far away from being practically usable.
  • Co-installability isn’t available yet, in parts this uses the same names and install locations as a 5 installation. Put it into a separate prefix.
  • Interference from Qt-based dependencies that don’t support multiple major Qt versions yet has to be expected, this often shows in form of build errors due to mixing Qt 5 and Qt 6. You might need to comment out the corresponding find_package() calls locally for now.
  • Being able to build does not imply being able to run. This is especially true for QML based code at this point.

That’s not meant to scare you away, just to manage expectations :) If you want to help, give it a try!

Google Open Source Peer Bonus

Our ongoing Frameworks 6 effort got nominated for the Google Open Source Peer Bonus award, alongside the work of many other FOSS contributors.

For some reason this has my name next to it despite being a big team effort. Anyway, I took care of the involved paperwork and made sure the price money has been transferred to KDE e.V..


To participate, here are the most important coordination and communication channels:

This week we have a little bit of everything! Hopefully everyone should be able to find something to like:

15-Minute Bugs Resolved

Current number of bugs: 68, down from 70. 0 added and 2 resolved:

When Discover’s window is narrow/mobile mode and you search for something, the search field now disappears as expected when you resize the window to be wider (Matej Starc, Plasma 5.24.6)

System Settings’ sidebar view now remains visually in sync when the page shown by the main panel is changed by something else, such as opening a different page from KRunner (Nicolas Fella, Plasma 5.24.6)

Current list of bugs

New Features

Elisa is now able to display lyrics embedded in files that are using the LRC format, and automatically scroll the lyrics view as the song plays! (Han Young, Elisa 22.08)

There is now a user-facing option to control Tablet Mode! It retains its current default value of “switch automatically when relevant” which is only available on Wayland, but you can now additionally force it to be always on always off, and those options work on X11 too! (Marco Martin, Plasma 5.25):

System Monitor now has an option to make a page start loading data as soon as the app is opened–rather than as soon as the page is accessed–and the default History page now uses it by default (Arjen Hiemstra, Plasma 5.25)

Bugfixes & Performance Improvements

Yakuake no longer inappropriately opens on the active screen when configured to always open on a specific screen (Jonathan F., Yakuake 22.04.1)

When using Gwenview’s Crop tool with a fixed aspect ratio, changing the values in the size spinboxes now works properly (Alban Boissard, Gwenview 22.08)

Fixed a semi-common way that Plasma could crash when you remove a panel that has a System Tray widget on it (Fushan Wen, Plasma 5.24.6)

In the Plasma Wayland session, KWin no longer crashes when you hit Alt+Tab while the context menu for a window titlebar is visible (Xaver Hugl, Plasma 5.24.6)

The Overview effect no longer shows your panels, confusing you into thinking they’re interactive when they’re really not (Marco Martin, Plasma 5.24.6)

In the Plasma Wayland session, when something is recording your screen, the icon that appear in your system tray to notify you of this now appears in the visible part of the tray where you’ll actually see it, instead of only in the popup where it would be missed and fail to achieve its purpose in life (Aleix Pol Gonzalez, Plasma 5.24.6)

System Monitor Widgets now load handmade presets correctly. Note that you will need to remake your presets for this to work (Arjen Hiemstra, Plasma 5.24.6)

When you’ve set Discover to restart automatically after installing updates, now it only does so if all of the updates were applied successfully (Aleix Pol Gonzalez, Plasma 5.24.6)

In the Plasma Wayland session, when a KDE app is activated from another KDE app, the activated app now raises itself, just like it does on X11. This also makes the launch feedback animation work for apps launched from Kickoff, KRunner, and other pieces of KDE software! (Aleix Pol Gonzalez, Plasma 5.25) Note that when an app is activated and does not raise as you would expect, if either (or both) of the apps is a 3d-party app, it’s because that app needs to implement the xdg_activation_v1 Wayland protocol

In the Plasma Wayland session, a severe visual glitch experienced by users of NVIDIA GPUs has been fixed (Erik Kurzinger, Plasma 5.25)

In the Plasma Wayland session, hitting Meta+V to show a menu of the clipboard contents now shows an actual menu at the actual cursor position, rather than a standalone window in the center of the screen (David Redondo, Plasma 5.25)

In the Plasma Wayland session, you can now activate global shortcuts while dragging a window (Arjen Hiemstra, Plasma 5.25)

The Digital Clock applet’s “Copy to Clipboard” menu item now respects whether you’re using 24-hour time or 12-hour time (Felipe Kinoshita, Plasma 5.25)

Icon previews are once again shown for files on NFS or NTFS drives, the Trash, Plasma Vaults, KDE Connect mounts, and other non-local locations (David Faure, Frameworks 5.94). Note that this means preview generation can once again cause slowdowns and freezes in Dolphin when accessing those locations if they are slow, and we are working on a better way to avoid this without throwing the baby out with the bathwater by disabling previews entirely!

When you drag-and-drop an image onto your desktop and choose “Set as Wallpaper”, it will now automatically switch to the correct wallpaper plugin that supports single image wallpapers if you were currently using something different (Fushan Wen, Frameworks 5.95)

User Interface Improvements

When you provide incorrect authentication credentials on the lock or login screens, the whole UI now shakes a bit (Ivan Tkachenko, Plasma 5.25):

Tabs in GTK apps using the Breeze GTK theme now match the tab styling in Qt and KDE apps (Artem Grinev, Plasma 5.25)

Menubars and areas that use the menubar color in GTK apps using the Breeze GTK theme now use the header color as expected, if you’re using a color scheme with header colors (Artem Grinev, Plasma 5.25):

Toolbar buttons with icons and toolbar buttons without icons now share the same text baseline, so their text will always align vertically (Fushan Wen, Plasma 5.25):

In the Plasma Wayland session, multi-finger touchscreen gestures (Did you know that KWin has touchscreen gestures?) now follow your fingers just like touchpad and edge swipe gestures do! (Xaver Hugl, Plasma 5.25)

In the Plasma Wayland session, actions that trigger when you touch a screen edge are now disabled by default while there are any full screen windows, which improves the UX for games where you touch screen edges a lot (Aleix Pol Gonzalez, Plasma 5.25)

The Dictionary widget now shows you an appropriate error message when it can’t fetch the definition (Fushan Wen, Plasma 5.25):

The weather widget no longer shows decimals for its temperature display when used on a Panel (me: Nate Graham, Plasma 5.25):

On System Settings’ Login Screen (SDDM) page, the “Halt command” and “Reboot command” text fields are now editable, so you can type in a command by hand, or add a command-line argument to it if you’d like, instead of only being able to choose a command using the Open dialog (Someone going by the pseudonym “oioi 555, Plasma 5.25)

…And everything else

This blog only covers the tip of the iceberg! Tons of KDE apps whose development I don’t have time to follow aren’t represented here, and I also don’t mention backend refactoring, improved test coverage, and other changes that are generally not user-facing. If you’re hungry for more, check out, where you can find more news from other KDE contributors.

How You Can Help

If you’re a developer, check out our 15-Minute Bug Initiative. Working on these issues makes a big difference quickly!

Otherwise, have a look at to discover ways to be part of a project that really matters. Each contributor makes a huge difference in KDE; you are not a number or a cog in a machine! You don’t have to already be a programmer, either. I wasn’t when I got started. Try it, you’ll like it! We don’t bite!

Finally, consider making a tax-deductible donation to the KDE e.V. foundation.

Saturday, 14 May 2022

KDE today announces the release of KDE Frameworks 5.94.0.

KDE Frameworks are 83 addon libraries to Qt which provide a wide variety of commonly needed functionality in mature, peer reviewed and well tested libraries with friendly licensing terms. For an introduction see the KDE Frameworks release announcement.

This release is part of a series of planned monthly releases making improvements available to developers in a quick and predictable manner.

New in this version


  • [Timeline KIO] Don’t announce that we can write

Breeze Icons

  • Add view-left-new action
  • New debug step icons

Extra CMake Modules

  • Drop lib prefix when building for Windows (MinGW)
  • Allow ecm_add_{qt,}wayland_{client,server}_protocol take targets
  • ECMQueryQt: always use CMake target to find the qmake/qtpaths binary
  • KDEGitCommitHooks: only configure pre-commit hook if needed


  • Make replace not block because of missing item removal
  • Add ResultModel::forgetResources method

KDE Doxygen Tools

  • only bootstrap when explicitly asked for
  • Add a dummy install target to cmake




  • Create UIDs if necessary (bug 339726)


  • Fix filtering of plugin in KPluginWidget
  • Check executables exist in PATH before passing them to QProcess
  • KPluginModel: Add method to get KPluginMetaData config object for given plugin id
  • KPluginDelegate: Add configTriggered signal
  • Refactor QML components of MPluginSelector to have less dependencies and have better layout
  • KPluginModel: Add isSaveNeededChanged singal
  • Import AboutPlugin dialog from QML
  • Expose proxy sort model as private QML API
  • Create QML version of KPluginSelector
  • Allow consumers to get sort proxy model
  • Export the KPluginModel class & make it usable from QML


  • KConfigGroup: fix writePathEntry/readPathEntry roundtrip for symlinks
  • Support storing QUuid


  • KCommandBar: remove installed event filter in destructor (bug 452527)
  • [kcolorschememanager] Rework and improve auto theme switching (bug 452091)
  • [kcolorschememanager] Don’t save colors on application start
  • Move kstatefulbrush implementation to its own file
  • fix: KRecentFilesAction saveEntries and loadEntries use the correct group when no group is passed
  • Add move constructor and assignment operator for KColorScheme
  • Make it clear that KStandardAction::name gives you ascii


  • KPluginMetaData: Fix setting of MetaDataOption when building without deprecations
  • processlist: don’t call procstat_getpathname() at all (FreeBSD)
  • ListOpenFilesJob: avoid creating the processlist on FreeBSD multiple times


  • Add PlaceholderMessage to GridView KCMs


  • Check executables exist in PATH before passing them to QProcess
  • Create and install version header file
  • exiv2extractor: add support for Canon CR3 raw image


  • Add BUILD_RUNTIME option (default ON)
  • x11: Implement deactivation
  • Add KGlobalAccel::globalShortcutActiveChanged

KDE GUI Addons

  • Un-pluginify modifierkeyinfo
  • Add plugin for wayland keystates


  • Add QML API for the sun and moon computations
  • New function for plasma to generate holidays without astro seasons (bug 445324)
  • Report intermediate lunar phases as well
  • Category added as parameter
  • Add functions for holiday only
  • Remove double entries and correct indian- (bug 441275)


  • KF5I18nConfig: Add missing find_dependency call


  • avif: prepare for breaking change in libavif
  • XCF: Support to QImageIOHandler::Size option
  • psd: Fix crash on broken files
  • psd: duotone read
  • psd: Don’t crash with broken images
  • psd: Header depth has to be 8 for CM_INDEXED color_mode
  • psd: Protect against broken images
  • avif: lossless support
  • psd: Don’t assert on broken files
  • PSD: Performance improvements and support to missing common formats


  • Temporarily revert “Consider slow files as remote files in previewjob”
  • KFileWidget: set standard zoomIn/Out keyboard shortcuts
  • KFileWidget: allow icon sizes to go up to 512 (bug 452139)
  • PreviewJob: consider all the available thumbnail cache pool sizes
  • dropjob: Extract Ark data in ctor (bug 453390)
  • dropjob: upstream ark behaviour from various file view implementations
  • KFileWidget: KF6, fix view size glitch on initial show
  • Don’t put job/ioworker on hold after getting the mimetype (bug 452729)
  • Don’t build kio_trash on Android
  • Remove unused Blkid dependency
  • Mark setSubUrl for cleanup in KF6
  • KCoreDirLister: modernise for loops
  • [KUrlNavigatorPlacesSelector] Disconnect setupDone signal when done
  • [KUrlNavigatorPlacesSelector] Do storage setup also when requesting a new tab (bug 452923)
  • [KFilePlacesView] Pass widget to QStyle::styleHint
  • Revert “Replace He with They in Doc not found page”
  • KFileItemDelegate: Add a semi-transparent effect to the icons of hidden files
  • [WidgetsAskUserActionHandler] Use WarningYesNo for permanently deleting files
  • [KDirOperator] Use QSortFilterProxyModel::invalidate() instead of ‘fake resorting’
  • KFilePlacesView: use animations only if QStyle::SH_Widget_Animation_Duration > 0 (bug 448802)
  • Replace He with They in Doc not found page
  • KFilePlacesModel: make it more accessible from QML
  • KUrlNavigator: offer open in new window action too (bug 451809)
  • Prepare KCoreDirLister::matches(Mime)Filter to be private
  • KDirOperator: do not overwrite standard back actions
  • KFilePlacesView: Improve touch support
  • KCoreDirLister: handle dir permission change in non-canonical paths
  • KCoreDirLister: handle file removal in non-canonical paths
  • KRecentDocument: fix erroneous messages about overwriting
  • KRecentDocument: ensure the path to the XBEL file existss (for CI)
  • Fix ~KTcpSocket crash with libc++ (e.g. FreeBSD)


  • ScrollablePage: Stop duck-typing QML types
  • SwipeListItem: Expose the width of overlayLoader
  • Dialog: Unbreak standardButton() method
  • ApplicationItem: Fix Shortcut’s warning about sequence vs. sequences
  • ApplicationItem: Clean it up a bit
  • columnview: Fix memory leak caused by QQmlComponent::create
  • columnview: Remove m_attachedObjects
  • AbstractApplicationItem: Fix copy-pasta mistake
  • correctly hide the bottom floating buttons when ther eis a page footer
  • ToolBarPageHeader: Do not assign undefined to real values
  • ColumnView notifies for contentChildren when page is removed (bug 452883)
  • ActionToolBar: fix moreButton visibility (bug 449031)
  • LoadingPlaceholder: remove redundant explanation
  • Improve ListItemDragHandle
  • Add LoadingPlaceholder component
  • AboutPage: Prevent infinite loop (bug 447958)
  • PlaceholderMessage: add types
  • Introduce TabletModeChangedEvent
  • [doc]: Remove double inheritance arrow for Kirigami.PagePoolAction


  • Fix assertions in KDescendantsProxyModel (bug 452043)
  • Fix punctuation/whitespace of runtime rate-limited deprecation warnings


  • Action: simplify expression for engine property
  • Deprecate KNS3::QtQuickDialogWrapper::exec (bug 450702)
  • qtquickdialogwrapper: Fix memory leak caused by QQmlComponent::create (bug 452865)
  • Use Kirigami.LoadingPlaceholder component
  • Delete our own custom PlaceholderMessage
  • Dialog: Port to Layouts
  • Dialog: use a real ToolBar for the footer instead of a homemade one
  • Dialog: Add a little separator line between footer and content
  • Convey lack of hotness visually in placeholder message


  • Don’t send alpha channel if pixmap has none

KPackage Framework



  • Add avatar image provider


  • KPtyProcess: call childProcessModifier() of parent class first


  • Use ECM_MODULE_DIR instead of ECM_DIR/../modules


  • Make Qt::Gui dependency for deprecation free builds internal
  • Deprecate public KConfigGroup include of AbstractRunner class


  • KService: Do not link KCoreAddons and KConfig publicly when building without deprecations
  • kservice.h: Wrap public KCoreAddons includes in deprecation macros


  • fix vector init in commands()
  • inc ui file version after action name fixes
  • EmulatedCommandBarTest: port from processEvents to QTRY_VERIFY
  • create commands and motions once
  • avoid storing instance in commands/motions
  • avoid cursor move on insert of line at EOF on save (bug 453252)
  • use proper name for selection menu
  • Multicursors: Use shorter actions names
  • Multicursors: Move current cursor to end of line when cursors are created from selection
  • more deprecation fixes for Qt 6
  • Fix completion leaks, don’t use null parent
  • Add option to show folding markers on hover only
  • Paint using path once instead of painting multiple rects
  • Fix background visible through selection with custom painted selection
  • vimode: add another motion command for moving down one line
  • Fix help link for editing command line
  • Fix crash when ModeMenuList wasn’t init but we try to reload it (bug 452282)
  • Enable auto-brackets by default
  • Improve Color theme config page


  • Don’t use GenericDataLocation on Android


  • client: implement plasma-surface openUnderCursor
  • Fix include path in the generated pkgconfig file
  • [plasmawindowmanagement] Add resourceName


  • Use KDatePickerPopup in KDateComboBox
  • Add support for custom date word maps, as done in KDateComboBox
  • Share date range support between KDateComboBox and KDatePickerPopup
  • Allow to change KDatePickerPopup modes at runtime
  • Implement date word actions as done in KDateCombobox
  • Build the date picker menu dynamically on demand
  • Add KDatePickerPopup
  • KPageDialog: Add a new face type with a flat list of small icons


  • ui_standards.rc: add tag so kate can insert a menu between Edit and View
  • Fix saving of state config if one has autosave enabled (bug 451725)
  • Replace OS-specific system information code with QSysInfo (bug 450862)


  • WirelessNetwork: Fix reference access point for the active network

Plasma Framework

  • IconItem: Allow specifying a custom loader
  • plasmastyle: Import PlasmaCore in MenuStyle
  • Don’t assert if the theme is not found, just warn
  • desktoptheme: Install plasmarc
  • plasmaquick: Fix memory leak caused by QQmlComponent::create
  • Revert “Prevent tooltips from being incorrectly dismissed” (bug 439522)
  • wallpaperinterface: Add some APIs needed for wallpaper accent color support
  • Fix use-after-free in ContainmentInterface (bug 451267)
  • Fix osd dialog position (bug 452648)
  • mark plasmapkg as nongui executable
  • Fix check for argument length in DataEngine loader (bug 452596)
  • desktoptheme: Convert desktop to json files
  • desktoptheme: Separate config from theme metadata
  • Convert desktop files of plugins to json
  • examples: Convert desktop files of KPackages to json
  • Keep PlasmaComponents.Highlight on its former behaviour (bug 452555)
  • Dialog: Do not update layout parameters while hidden (bug 452512)
  • Wrap KPluginInfo includes in deprecation wrappers
  • PlaceholderMessage: Remove Kirigami references
  • PlaceholderMessage: add types
  • PC3 toggle controls: fix odd heights misaligning indicators (bug 447977)
  • Fix search field left padding when icon is hidden
  • ExpandableListItem: deprecate contextmenu and allow actions+custom view
  • Deprecate DataEngine related code in Plasma::PluginLoader
  • Plasma::Theme: Port last KPluginInfo usage
  • Plasma::Theme: Allow packages to ship metadata.json file, move config to separate file
  • Add include needed by Qt6 forgotten in d74a8286e1


  • Remove duplicate header between .h/.cpp file
  • Fix out-of-bounds read on the Aztec special char table
  • Enable macOS support
  • Fix PrisonScanner target name
  • Consider flipped video frames when computing the barcode positioon
  • Add barcode scanner component for barcode scanning from live video


  • Port to ecm_add_qml_module


  • Remove infoChanged signal from KQuickStyleItem
  • Replace connect to self in KQuickStyleItem with direct method calls
  • Recalculate metrics when tablet mode changes
  • Fix use of a no longer existing id


  • udev/cpuinfo_arm: Add missing CPU ID

Syntax Highlighting

  • cmake.xml: Updates for CMake 3.23
  • Fix haxe rawstring escaping

Security information

The released code has been GPG-signed using the following key: pub rsa2048/58D0EE648A48B3BB 2016-09-05 David Faure Primary key fingerprint: 53E6 B47B 45CE A3E0 D5B7 4577 58D0 EE64 8A48 B3BB

Friday, 13 May 2022

Let’s go for my web review for the week 2022-19.

NVIDIA Releases Open-Source GPU Kernel Modules | NVIDIA Technical Blog

Tags: tech, gpu, nvidia, foss

At last! Maybe we can finally dream of NVIDIA turning into a good citizen on our platforms?

Wireless is a trap |

Tags: tech, wifi, bluetooth, complexity

Indeed, we loath wires… but going wireless has its own set of issues. It never completely breaks but it can easily degrade for no apparent reason which could be anywhere in the stack.

Complexity is the mind killer

Tags: tech, complexity, simplicity, xp, craftsmanship

I definitely agree with this. Managing complexity is our trade.

Scapy: low level packet hacking toolkit for Python – Trickster Dev

Tags: tech, python, networking, security

Looks like a very interesting toolkit for low level network related or security related operations.

I’m All-In on Server-Side SQLite · Fly

Tags: tech, databases, sqlite, backend

The tone of the article isn’t exactly to my liking, sounds “too good to be true” at times ignoring important details driving the choices (despite some warnings early on). Still, depending on the amount of data stored in your database, SQLite looks increasingly viable on the server, replication even coming down the road.

Modeling Finite State Machines with Rust | Ramnivas Laddad

Tags: tech, safety, type-systems, rust

I like it when type systems can express this kind of constraints. It clearly allows to catch mistakes early in the development cycle.

Bottled water monopolist admits recycling is bullshit

Tags: ecology, lobbying, plastics

The best waste is the one you didn’t create in the first place. If you still had doubts that recycling plastics is a scam, it’s definitely something to read. It was again a trick to turn into a “personal responsibility” something which was a collective failure.

Bye for now!

Thursday, 12 May 2022

Some time ago, I wrote a post about integrating Qt’s associative containers with the fancy new C++ features, range-based for loops with structured bindings.

That post inspired KDAB’s own Giuseppe D’Angelo to add the asKeyValueRange member function to both QHash and QMap. Now it’s possible to iterate over them with a simple range-based for loop, like so:

    for (auto [key, value] : map.asKeyValueRange()) {
        // ...

The second part of my previous post demonstrates how we can iterate over Qt SQL results using a range-based for loop as if it were an ordinary collection. In addition, it announces this second part of the post that shows you how to add the support for structured bindings into the mix.

Structured Bindings, Revisited

Recall that structured bindings allow us to decompose structures such as std::pair and QPair, so that we can give more intuitive names to the fields in those structures than the first and second names provided by both pair types:

    auto [x, y] = mousePosition();

In the previous example, when the range-based for loop iterates over map.asKeyValueRange(), it takes each key-value pair from the map and assigns the name key to the first element of the pair and the name value to the second element.

Internally, the pair is stored in an invisible variable, and the names key and value just refer to the fields inside of that variable.

Behind the scenes of structured bindings

Out-of-the-box, structured bindings can also be used with arrays, tuple-like types, or, a bit less useful outside of generic programming, with ordinary user-defined structures:

    std::tuple<bool, QString, QString> employee;
    auto &[active, name, team_name] = employee;

    Employee employees[2];
    auto &[first_employee, second_employee] = employees;

    struct Employee {
        bool m_active;
        QString m_name;
        QString m_team;
    Employee employee = ...;
    auto &[active, name, team_name] = employee;

Structured Bindings Support for Custom Types

It is also possible to make our own types decomposable with structured bindings, by making sure our types implement the so-called tuple protocol or, in other words, by making our types look like tuples.

Imagine we don’t want the m_active member variable to be seen when using structured bindings on the previously defined Employee type. Instead, we just want to be able to bind m_name and m_team:

    auto &[name, team_name] = employee;

In order to specify how our type should be decomposed with structured bindings, we need to define a few things:

  • into how many values an instance of our type can be decomposed;
  • the type of each of those values;
  • a getter for each of those values.

Tuple-like Employee

The first part of the tuple protocol is simple — we need to specialize the std::tuple_size template for our type Employee. Since we only want to bind m_name and m_team, the size of our tuple-like type will be 2.

    #include <utility>


    namespace std {
        struct tuple_size<::Employee> {
            static constexpr std::size_t value = 2;

The next step is to specialize the std::tuple_element template:

    namespace std {
        struct tuple_element<0, ::Employee> {
            // The type of m_name
            using type = QString;

        struct tuple_element<1, ::Employee> {
            // The type of m_team
            using type = QString;

The value we defined in the std::tuple_size specialization tells the compiler how many values it will get when it decomposes an instance of Employee, and the types we defined in the std::tuple_element specializations are the types of those values. In our case, both values are QStrings.

The last step is to create a get function template. It can be a member of Employee, but it can also be a free function (non-member) template.

     template <std::size_t Idx>
     auto& get(Employee& employee) {
         if constexpr (Idx == 0) return employee.m_name;
         if constexpr (Idx == 1) return employee.m_team;

It’s worth noting that this implementation will not accept const objects and you’ll need to provide a get implementation that takes a reference to a const Employee, if you want to support those as well.

Decomposing QSqlRecord

Now that we know what we need to implement in order for our types to be usable with structured bindings, we can try to do it with QSqlResultIterator, which we implemented in part 1 of this blog post.

As a reminder, in the first part of the post, we implemented the QSqlResultIterator class that can be used to iterate over all results of a QSqlQuery. We also implemented operator[] on it, which allows us to access fields in a result.

    class QSqlResultIterator {
        // ...
        QVariant operator[] (int index) const
            return m_query.value(index);

We can use this to base the get function template on. To demonstrate that get doesn’t need to be a free function, we will implement it as a member of QSqlResultIterator:

    class QSqlResultIterator {
        // ...
        template <std::size_t Idx>
        QVariant get() const
            return m_query.value(index);

The remaining things that need to be implemented are the specializations of std::tuple_size and std::tuple_element.

Since all values in QSqlResult are QVariants, specializing std::tuple_element is trivial. For any index we’re given, we just need to set type = QVariant:

    namespace std {
        template<std::size_t Idx>
        struct tuple_element<Idx, QSqlResultIterator> {
            using type = QVariant;

The std::tuple_size, on the other hand, is tricky. SQL queries are a runtime thing, and we need to know the number of fields in a record at compile time. This means that we need to allow the user to explicitly define the number of fields in a record when creating the QSqlResultIterator. One way to do it is to make QSqlResultIterator a class template with one std::size_t parameter:

    template <std::size_t FieldCount>
    class QSqlResultIterator {
        // ...

This will allow us to define everything we need to allow QSqlResultIterator to be used with structured bindings:

    template <std::size_t FieldCount>
    class QSqlResultIterator {
        template <std::size_t Idx>
        QVariant get() const
            return m_query.value(index);

        // ...

    namespace std {
        template<std::size_t FieldCount>
        struct tuple_size<QSqlResultIterator<FieldCount>> {
            statuc constexpr std::size_t value = FieldCount;

        template<std::size_t Idx, std::size_t FieldCount>
        struct tuple_element<Idx, QSqlResultIterator<FieldCount>> {
            using type = QVariant;

We could even add a few static_asserts that would check that Idx is less than FieldCount everywhere.

Broken Range-based For Loop Use-case

When we added the FieldCount template parameter to QSqlResultIterator, we broke the use-case we had in the part 1 of this post. We now require FieldCount to be specified explicitly when an instance of QSqlResultIterator is created, and we are not creating it anywhere explicitly.

As a reminder, the QSqlResultIterator was instantiated by the range-based for loop which called begin on the QSqlQuery instance we passed to it:

    for (auto result: query) {
        // ...

It happened behind the scenes and we cannot control how begin is called by the range-based for loop to be able to pass in FieldCount somehow.

Or, can we?

We can write a simple wrapper similar to what we did for asKeyValueRange. Then, instead of begin being defined for QSqlQuery directly, it would be defined for that wrapper, and it would be able to create QSqlResultIterator with the proper FieldCount value.

It could look something like this:

    template <std::size_t FieldCount>
    class QSqlResultRange {
        QSqlResultRange(QSqlQuery query)
            : m_query(std::move(query))

        QSqlResultIterator<FieldCount> begin()
            return { m_query };

        QSqlResultSentinel end() const
            return {};

        QSqlQuery m_query;

Then we can use it as follows:

    for (auto [active, name, team] : QSqlResultRange<3>(query)) {
        // ...

Adding Types to the Mix

So far, we’ve implemented a range object that allows us to iterate over SQL results using a range-based for loop with structured bindings.

In the previous example, we get bindings active, name and team that all have QVariant type.

Can we improve the type-safety of this code, considering our almost always storing concrete types in a database and having to unwrap all QVariants, manually, is tedious and error prone?

Can we specify that the range object returns a bool and two QStrings in each iteration?

As usual in C++, the answer here is a resounding yes. The only thing that we need to do is replace all occurrences of the FieldCount parameter with a variadic pack of types, which will allow us to specify the exact types we expect to get in each resulting row of an SQL query.

In order avoid mixing these with the previously defined types, we’ll add Typed to the names of classes we’ve created so far.

    // We want to allow the user to specify the types
    // of the fields in an SQL row
    template <typename ...Types>
    class QSqlResultTypedIterator {
        // The constructor and all the basic functions
        // we had in QSqlResultIterator remain unchanged

        QSqlResultTypedIterator(QSqlQuery& query)
            : m_query(query)

        QSqlResultTypedIterator& operator++()
            return *this;

        bool operator!=(QSqlResultSentinel sentinel) const
            return m_query.isValid();

        QSqlResultTypedIterator& operator*()
            return *this;

        // The only one that differs is the tuple-compatible
        // get member function. It can return different types
        // depending on the provided index.
        template <size_t Idx>
        auto get() const
            using ResultType = std::tuple_element_t<Idx, std::tuple<Types...>>;
            // We can assert that the type stored inside of QVariant
            // is the type that we expect to be in it.

            // .value returns a QVariant. Then we call .value
            // on said variant to convert it to the desired type.
            return m_query.value(Idx).value<ResultType>();

        QSqlQuery& m_query;

    namespace std {
        // The tuple_size for QSqlResultTypedIterator is the
        // number of types inside of Types... which we can
        // easily get with sizeof...(Types)
        template<typename... Types>
        struct tuple_size<QSqlResultTypedIterator<Types...>> : public integral_constant<size_t, sizeof...(Types)> {};

        // The simplest way to implement tuple_element on our type
        // is to just base it on the implementation of std::tuple itself.
        // When we are asked for tuple_element<Idx, QSqlResultTypedIterator<Types...>>,
        // we will just replace QSqlResultTypedIterator with std::tuple,
        // and return tuple_element<Idx, std::tuple<Types...>>
        template<std::size_t Idx, typename... Types>
        struct tuple_element<Idx, QSqlResultTypedIterator <Types...>>:
               tuple_element<Idx, std::tuple              <Types...>>

    // The complex part was in the QSqlResultTypedIterator, and the
    // range object remains as simple as QSqlResultIterator was.
    // The only change is that FieldCount is replaced by Types... everywhere
    template <typename ...Types>
    class QSqlResultTypedRange {
        QSqlResultTypedRange(QSqlQuery query)
            : m_query(std::move(query))

        QSqlResultTypedIterator<Types...> begin()
            return { m_query };

        QSqlResultSentinel end() const
            return {};

        QSqlQuery m_query;


This was a lengthy post to follow, and it had a lot of non-trivial code for something as simple as being able to write:

    for (auto [active, name, team] : QSqlResultTypedRange<bool, QString, QString>(query)) {
        qDebug() << "active(bool):" << active;
        qDebug() << "name(QString):" << name;
        qDebug() << "team(QString):" << team;

While this might not look like it is worth doing, remember that this is something you need to write only once and you will use it a lot, if you have an application that is SQL-heavy.

It will make your code more easy-to-read and as type-safe as possible when SQL is concerned, since the debug builds will assert that you are not trying to coerce values of one type into being something that they are not, when crossing the border between SQL and C++.

It is also easily extendible, to allow the user to skip the conversion from QVariant to a specific type by skipping the .value<ResultType>() part when the user-specified QVariant is the desired type, or to support using wrapper types such as std::optional when you have fields in an SQL table that can be NULL.


About KDAB

If you like this article and want to read similar material, consider subscribing via our RSS feed.

Subscribe to KDAB TV for similar informative short video content.

KDAB provides market leading software consulting and development services and training in Qt, C++ and 3D/OpenGL. Contact us.

The post Structured Bindings with Qt SQL appeared first on KDAB.

Over 120 individual programs plus dozens of programmer libraries and feature plugins are released simultaneously as part of KDE Gear.

Today they all get new bugfix source releases with updated translations, including:

  • dolphin: The terminal panel will keep in sync with quick folder changes now, Commit, #391380, #416690
  • kate: Fix crash on session restore, Commit, #453152
  • kalendar: Fix ’next week’ button in the week’s view Commit

Distro and app store packagers should update their application packages.

Monday, 9 May 2022

We’re past the soft feature freeze of the next Plasma release, so it’s a good time to step back and a have look at the work that has been done in KWin during 5.25 development cycle.

Gesture improvements

Credits: Eric Edlund, Marco Martin, Xaver Xugl

A lot of focus has been put into improving gesture integration in the Wayland session. In 5.24, the desktop grid effect got support for real-time gestures. In 5.25, the support for real-time gestures has been expanded. Effects such as slide, window aperture (animates windows when transitioning to the “show desktop” mode), and overview now support animations that “follow fingers.”

The slide effect follows fingers when switching between virtual desktops using gestures

Merge of kwayland-server and kwin

Credits: me

That’s not a user-facing change, but it’s really important to KWin developers. Some history trivia. KWin used to contain Wayland glue code, eventually it was split in a separate KDE Frameworks library called KWayland. The idea was to provide reusable components that can be useful not only to KWin but also other Wayland compositors. The split is better described in

At the beginning, things were good. If you need to implement a Wayland protocol, add corresponding wrappers in KWayland and then implement the protocol in KWin. However, being KDE Frameworks started presenting problems. KDE Frameworks provides strong API and ABI compatibility guarantees, which is very compelling for consumers but it can be a major source of headache for developers. For example, if a few bad design decisions were made, you cannot simply go back and correct the mistakes, you are going to live with that until the next major version release when it’s okay to make breaking changes. That’s what happened in KWin and KWayland, we made a couple of bad design choices that fired back at us and eventually resulted in a period of technical debt.

As a way out of technical debt, we made a hard decision to split the server side out of KWayland in a separate library called KWaylandServer, which provided no API or ABI compatibility guarantees between minor releases, but some between patch releases. Most of the client APIs in KWayland were deprecated too.

The split of the server side from KWayland in a separated library was a huge relief and it massively accelerated KWin development pace, that had user-facing effects too. Plasma on Wayland session started receiving less complaints (around Plasma 5.18 – 5.20 or so) from users because we were free to change KWin and KWaylandServer the way we thought was the best.

However, KWaylandServer also started showing cracks. The first problem is that it didn’t gain a strong user base. Its the only user was KWin and there weren’t any signs of new users. The second problem is that we gradually switched to qtwaylandscanner so we ended up writing wrappers for wrappers. The third problem is that wayland protocol implementations cannot exist in vacuum and they need to communicate with other compositor components, e.g. renderer; because no such components were present in KWaylandServer, we had to add glue code that made things more complicated. Also, perhaps we tried to fix a wrong problem by providing a library with Qt friendly wrappers for libwayland. Things such as the DRM backend or the scene graph are far more challenging to implement and maybe we should put focus onto making them reusable instead of wrappers.

Regardless, a year or so ago we agreed that it’s worth bringing server-side wayland code back into KWin. In 5.25, we were finally able to do the merge. That allows us to simplify many wayland protocol implementations, fix some design issues and a few known bugs.

Present Windows and Desktop Grid effects rewritten in QML

Credits: Marco Martin

We started experimenting with implementing some fullscreen effects in QML in 5.24. In order to continue that effort, the Present Windows and Desktop Grid effects were rewritten in QML. The main advantage of QML is that we will be able to build more complex scenes without significantly sacrificing maintainability, for example blurring the desktop background only takes a couple of QML lines of code, in C++ it would be a lot more! The main focus with the rewrite was put on keeping feature parity between C++ and QML versions of Present Windows and Desktop Grid.

Desktop Grid implemented in QML
Present Windows (now called “Window View”) effect implemented in QML

Compositing improvements

Credits: Xaver Xugl, me

We continue pushing forward with our ambitious goal to make KWin utilize hardware output planes better and make it more efficient. Significant amount of work in 5.25 has been put into refactoring the DRM backend and compositing abstractions. Unfortunately, we won’t be able to get everything we wanted in 5.25, but hopefully Plasma/Wayland users will start benefiting from this work in the next Plasma release, i.e. 5.26.

As a part of the scene redesign goal, we made handling of invisible windows more efficient on Wayland. For example, if an invisible window wants to be repainted for whatever reason, KWin is going to ignore that request. It’s not an issue on X11, but it was challenging to implement that behavior on Wayland the “right way.” Also, if painting code in a Wayland application is driven by frame callbacks, KWin won’t send frame callbacks anymore if the window is invisible, e.g. minimized or on a virtual desktop that is not current, thus no precious CPU or GPU resources will be wasted.

Screencasting improvements

Credits: Aleix Pol Gonzalez

KWin/Wayland got a new screencasting mode that allows capturing a rectangular region on the screen. For example, this can be useful for building screen recording tools, etc.

New blend effect

Credits: David Edmundson

The blend effect provides an eye-candy animation when switching between dark and light themes.

Fixed Aurorae decorations having “sharp” corners

Credits: Michail Vourlakos

The blur effect is applied to the region beyond top-left corner

If you use a decoration theme powered by Aurorae decoration engine, then the decoration borders may not be as round as they are supposed to be. It’s been a long standing bug caused by the blur effect and lack of enough metadata in Aurorae decoration themes

The blur effect is applied as expected in 5.25

Window management refactors

Credits: Nils Fenner

KWin used to have a strange window class hierarchy that always created confusion among new contributors.

KWin used to use the word “client” to refer to managed windows, i.e. the ones with frames, but the word “client” means a totally different thing in the Wayland world, it represents the other endpoint connected to the compositor, e.g. an application. The word “toplevel” also means different things in KWin and the xdg-shell protocol, which is used by practically all Wayland applications to create “normal” windows and popups.

Toplevel and AbstractClient classes were merged into the base Window class with a far more intuitive name. That makes the class hierarchy simpler, and hopefully removes an obstacle for new contributors.

fbdev backend was dropped

The fbdev backend was in a bit-rotten state. With the emergence of simpledrm kernel driver, we decided to drop the fbdev in favor of the DRM backend, which is actively maintained.

Closing words

5.25 is going to be the biggest release by the scale of changes within recent years, which is both great and terrifying, so it’s more than ever important that as many as possible people give us feedback about the upcoming beta. Please join us at, which is going to be held on May 26th in, to help us to make this release smooth and amazing. 🙂