Skip to content

Monday, 13 July 2026

This is a weekly update from my Google Summer of Code 2026 project with KDE, improving effect widgets in Kdenlive, a free and open source video editor.

MR !911 opened and reviewed

Opened the Gradient widget MR this week, closing issue #1064 and referencing #2206. Jean-Baptiste reviewed it and flagged a few things.

Fixing the gradient render bug

The gradient bar was rendering as a flat, empty rectangle, only the stop handles below it showed color. Root cause: the native QStyle::drawPrimitive(PE_Frame, ...) call added for frame styling was painting its interior background after the gradient fill, covering it completely under Breeze's style. Fixed by reordering the paint sequence, frame first, then the checkerboard-for-alpha and gradient fill inside the frame's content rect, so nothing gets overpainted.

Before: Gradient bar rendering as flat empty rectangle

After: Gradient bar showing correct multi-color gradient

Missing 32-stop cap at the model layer

The widget already capped stops at 32, but AssetParameterModel's parsing path for ParamType::GradientEditor had no equivalent check. A hand-edited or corrupted project file could bypass the widget entirely and load more than MLT's gradientmap filter supports. Added truncation at the model level so both layers enforce the same limit independently.

Handle visibility fix

The first stop's handle (black) was nearly invisible against Kdenlive's dark theme. Added a stroke around each unselected handle using the palette's text color at 50% opacity, so dark-colored stops stay visible regardless of theme.

RGBA tooltip on hover

Added a small tooltip showing a stop's exact RGBA value on hover, requested during review.

Gradient widget showing RGBA tooltip on hover

Midterm evaluation

Submitted July 10.

What's next

MR !911 is rebased on current master and pushed with all review fixes; waiting on another look from Jean-Baptiste.

The openQA-based testing system has recently been integrated into KDE Linux (hooray!), and I thought it was about time I did a little write-up.

The nature of KDE Linux, in which the whole system ships as a single signed image rather than a pile of packages, is (in theory) wonderful for reliability. However, this raises an uncomfortable question: how do we make sure that image actually works before we ship it to people? OpenQA is the answer!

TL;DR: we boot each build in a virtual machine, run tests that interact with it to ensure the system installs and upgrades properly and that desktop functionality works. Once the tests pass, the user gets an end-to-end tested image. This replaces the rather rudimentary basic-test machinery, which simply booted up the live image and checked if the boot was blessed and if any units failed.

The test flow

A single build goes through three stages.

install-system takes the live ISO, boots it in a VM, and runs a real installation onto an empty virtual disk, just like a real user would. sanity-test then boots that freshly installed disk and verifies the system actually comes up and behaves. In between, while we're testing the upgrade path in parallel, an upgrade-system stage installs the previous release and upgrades it to the current build to check whether the previous release can actually be upgraded to the new build. Each stage hands its disk to the next.

They're wired together as a dependency chain, so in the openQA web interface the whole run shows up as a single connected graph. If installation fails, the later stages don't bother running, as there's nothing to test.

Our CI pipelines now approximately look like this:

CI flowchart. Imaging failures upload to CI artifacts, while successful images run parallel openQA test and upgrade jobs before gated publishing.

Interesting architectural tidbits

We do a few things differently compared to your stock-standard openSUSE or Fedora openQA instances.

Selenium testing instead of needle testing

Normal openQA tests operate through "needles". These aren't sewing needles; rather, they're screenshots of the virtual machine in some desired state with some JSON metadata attached. This metadata defines certain areas to match or ignore, and the test code can click matched areas. While needles are certainly effective at interacting with the system exactly how a user would, they have drawbacks. It's quite annoying to make and constantly update needles, as well as keep them from breaking every time there are slight changes in user interfaces.

Luckily for us, we already have a battle-tested way of interacting with user interfaces for testing: selenium-webdriver-at-spi . It's already widely used across unit tests in KDE projects, hence our decision to use it affords us a lot more flexibility, maintainability, and consistency. It also enables app developers to run their own tests on KDE Linux with openQA down the track.

Essentially, we have a Python unittest script on the system that we're testing (see the sysext section below for details), which attaches itself to an application. It then interacts with the app by leveraging the AT-SPI2 accessibility API to send clicks and read the screen, in a similar vein to screen-reading software such as Orca.

Ephemeral workers in CI jobs

openQA instances usually have long-running workers that are hosted on servers. It's a bit of a painful ordeal to get all that infrastructure up and running. On top of that, hosted workers need to do an upload-download rigmarole involving large assets from the server, such as the .iso files and the generated hard disk. This makes things very slow for no good reason.

We already have CI runners that work perfectly well for this and can be spun up when needed, giving us effortlessly simple scaling. So, we spin up an openQA worker container in a CI runner, which submits jobs to the openQA server. It has its own UUID, which is shared with the job, so the worker running in CI is always assigned the right job.

This saves us from the bandwidth rigmarole because all the assets are generated and consumed within the one container, so we can simply keep all the assets on the worker and never upload them to the server. As a result, we save a lot of storage space on the openQA server, so we can run it with fairly minimal hosting requirements.

The use of systemd system extensions to inject tests

How do we actually get our Selenium tests on the system, you may ask? Enter the humble system extension , or sysext, for short.

We include a few things in our sysext:

  • The Python unittests themselves.
  • A bootstrap script with some system configuration, so we have an appropriate environment set up for testing.
  • A venv, so we can make use of the Python ecosystem. This is created in the bootstrap script.

All of this is packaged up into an EROFS .img file, which we mount to the worker's VM. This is then automounted by an associated udev rule in upstream KDE Linux, with the bootstrapping script being triggered by an associated service shortly afterward.

Since we have the capability to inject tests and configuration into the system, we're able to test things that would otherwise be impossible to test with needles. For example, we test if essential desktop processes have ever crashed, if any systemd services failed, if networking works, and if commands we ship with KDE Linux work properly. All of these tests leverage direct access to the innards of the system.

Interaction with the system through SSH

To actually poke at the system and have the worker run these tests sequentially, we need some way of interacting with the system. openQA provides some facilities to interact with a serial terminal, but this proved to be very fragile and unreliable, with buffering issues everywhere.

Instead, we set up SSH with our sysext and use the facilities provided by the Python library Fabric to run all our tests in a robust manner.

Each test runs in a transient systemd service created by systemd-run. This runs the test as the intended user, groups its processes in a cgroup, gives it an isolated journal stream for output, and returns its service exit status synchronously. The harness can then collect the unit's journal even when the test fails, and we keep everything neat and tidy.

Staging images before we publish, and how we test updates

To prevent users from downloading an image that still needs to be tested, we create a staging directory on storage.kde.org, scoped to the imaging stage's job ID, that stores the built artifacts in a directory tree. It has a layout that mirrors the public-facing tree, so we can simply merge it in once tests pass.

However, this throws a spanner in the works when we try to test system upgrades because we obviously can't upgrade to an image that hasn't been published yet!

To fix this, the solution is simple. In the sysext, we simply point systemd-sysupdate to the staging directory we've already created. This has some drawbacks, though. For the moment, we can't test delta updates through kde-linux-sysupdated. That shouldn't be too difficult to fix in the near future, but we're waiting on KDE Linux to be entirely hosted on storage.kde.org before we jump on that. The bigger issue here is that we really don't have a good way of testing updates from the chunk store. A better story for this still needs to be worked out, but for the time being the upgrade test is good enough.

What's to come

We have a few things we're aiming towards:

  • As mentioned above, testing delta/chunked upgrades.
  • Leveraging openQA to allow app developers to test their own apps atop KDE Linux.
  • Generalizing all our openQA glue so other projects can use the architecture we've built.
  • By extension, porting the aforementioned glue from admittedly fragile bash scripts to Python or some other more appropriate language.
  • Testing installs using manual partitioning and Full Disk Encryption.

…and probably many more things that we haven't thought of yet. Exciting times!

The past three weeks were a mix of cleanup, debugging, completing the work concerning UI and understanding TMView( since I did not look into it during proposal period) and TMTab again to review my design choices and see if I'm going in the right direction.

Cleaning up TMManager and getting checkboxes working

First up was cleaning TMManagerWin, reformatting, removing now obsolete references and code. With that done, I resumed work on the per-project TM selection checkboxes.

The checkboxes are backed directly by DBFilesModel rather than a separate proxy layer. Overriding flags(), data(), and setData() on the existing model was the way to go. Qt's view renders the checkboxes automatically once Qt::ItemIsUserCheckable is set and Qt::CheckStateRole returns a value. Check state persists to ProjectLocal::selectedTMs() immediately on every toggle via saveCheckedState(), and reloads on project open via a Project::loaded connection.

One non-obvious issue I stumbled into and fixed myself was cleanupSelectedTMs(), which removes stale entries for TMs that no longer exist on disk, was being called immediately when Project::loaded fired. But DBFilesModel populates asynchronously via QFileSystemModel scanning the TM directory. The fix was deferring cleanupSelectedTMs() using QTimer::singleShot(), the same pattern used elsewhere in the codebase for async model population. loadCheckedState() itself runs immediately since it only reads from config and doesn't need the model to be populated. This was a subtle timing issue that only surfaced when testing with an actual project and multiple TM databases. In fact, cleanupSelectedTMs() itself wasn't thought of when planning.

After testing this end-to-end and verifying the .local config file was being written and read correctly, I merged this in.

Studying TMView's querying and why it can't help TMTab

Before touching TMTab's query logic, I spent time understanding how TMView (the suggestions dock widget in the editor) does its querying since my mentor suggested that it's querying might help designing something similar for TMTab's multi-TM quering.

TMView uses SelectJob which operates on TMEntry structs, it does fuzzy word-level matching, scores results, and is designed specifically for the suggestions workflow. It fires secondary DB queries only when the primary project DB scores below a threshold.

This is fundamentally different from what TMTab needs, it uses ExecQueryJob which runs SQL query against a DB and hands the cursor to QSqlQueryModel. The two systems aren't interchangeable, so the multi-DB approach for each has to be designed separately I guess. For TMView, the change is relatively small, loop selectedTMs() and fire one SelectJob per DB. For TMTab, it might turn to be little complex.

Removing the dbName combobox

With the TM list in TMManagerWin now showing checkboxes for selection, the dbName KComboBox in the search panel is redundant, users select which TMs to query via checkboxes, not a dropdown. I removed it from queryoptions.ui and cleaned up all references in tmtab.cpp, but some of them need workaround. The openFile() (RemoveFileJob) gets a TODO, to be fixed properly once multi-DB results carry their source DB name.

Debugging with GDB and Dr Konqi

My mentor reported a crash when opening the QA dock widget in the TM tab. This was a good opportunity to learn proper debugging with GDB, Dr Konqi, and reading backtraces.

After investigating, this appeared to be a preexisting bug unrelated to my changes. It's probably data-dependent and only triggers with specific content in the TM results view at the moment the QA dock repaints. It didn't reproduce on my machine. I might work on it later when I have time.

The years old chats on QtForum and StackOverflow were helpful throughout. Qt itself is so well documented!

TM Tab Redesigned

I'm looking forward to see how translators would like the TMTab's glow up when the project is completed and all the changes get merged.

Sunday, 12 July 2026

I just finished reading Thom Holwerda’s hilarious article on OSnews about being paid to use Windows 11 for a month from the perspective of being a “switcher” moving away from Linux. It’s a great read; I encourage everyone to stop right now and go read it!

In a nutshell, it’s truly amazing how bad the modern Windows user experience is when you’re accustomed to anything else:

  • Missing drivers
  • Black screens
  • Broken sleep/wake
  • Ads and intrusive AI in apps
  • No visual consistency
  • An update experience that’s fragmented, slow, and frustrating

My extended family includes a lot of Mac users, and I can tell you it’s barely better there. They suffer from:

  • Limited hardware selection
  • Devices that deliberately skimp on storage space to push people towards paid cloud storage subscriptions from Apple
  • Ugly and low-contrast UIs
  • Terrible window management
  • Slow and unresponsive apps
  • Poor integration with 3rd-party services

We’re ready

I’ve been saying for years that Linux is ready for normal usage. We often lament our bugs and failures, but under-estimate just how bad the competition is.

The reason why Windows and MacOS are so prominent is not because they’re better, but rather because of their inertia and wide distribution on retail hardware. If people can’t buy Linux computers in Best Buy and Mediamarkt, we’ll never get there.

Inertia takes care of itself over time with success. But we can do something about distribution: we can continue to make our software pre-installation ready. I’ve been talking about this since my first Akademy talk in 2018, and KDE has made amazing progress in just 8 years.

It’s clearly working, too.

Successes

This is why I get so excited about Valve’s new Steam Machine console/PC running KDE Plasma. Five years ago, I got excited about the Steam Deck. And I’m excited about Tuxedo Computers and Kubuntu Focus for shipping KDE Plasma on all of their computers out of the box. For an up-to-date list, see https://kde.org/hardware.

I hope that in due time, I’ll be excited about Framework Computer and Slimbook shipping a Plasma-based OS out of the box, too. 😎 And someday after that, Razer. I think they’d be receptive. And then Lenovo, HP, Dell, and Asus. I don’t believe this is far-fetched.

When people buy one of these devices, are they going to experience some Linux-specific bugs and annoyances? Yes, it’s inevitable. Nothing is perfect. But what we offer is good. Better, even. Better for users and better for hardware vendors.

What’s left

Is there more to do? Yes. We need a stronger 3rd-party software ecosystem, including Linux versions of more popular pro apps. A bit more Wayland work to close the remaining gaps. Operating systems that are safe and full-featured out of the box. Better documentation. More companies capable of offering professional support. And so on.

But all of this is happening! Isn’t that amazing? I find it amazing. Here we all are, offering the world a better option as some of the world’s largest companies are in stage 2 or 3 of the enshittification process. And we can help. It’s so cool.

Saturday, 11 July 2026

Take this new Kamoso icon for example.

Most people will see a "webcam" with a overly large lense. Some people might notice the reflections. Almost nobody will notice the tiny details inside the lens itself, the subtle changes in materials, the little bits of visual noise that stop things from feeling too artificial, or the writing around the lense repeating KAMOSOLENS 2026. And yet....

Which naturally raises the question… why bother?

Its not like users are going to zoom into a 256 pixel icon and start inspecting reflections like art critics examining a renaissance painting, (I realy wish you dont 🙂 ). Most of these details exist below the threshold of conscious perception. People don't really see them. At least not directly.

And yet I still think they matter.

The older I get the more I like to think details are a expression of love, of care. The kind of care that makes people do things that make absolutely no rational sense.

I grew up in Portugal and over here mothers have a particular way of saying "I love you". They don't usually say it. Instead they spend two days preparing enough food to feed a small village and then look personally offended when you stop eating after the third serving. The food is the message. The effort is the message. The ridiculous amount of work nobody asked for is the message.


So inevetably I think design works in much the same way.

When somebody spends hours polishing an animation that users will only experience for half a second, when somebody redraws an icon because one highlight feels wrong, when somebody obsesses over spacing differences measured in single pixels, they are saying "I care".


Now make no mistake, as a user I often feel exactly the same level of care in very minimalistic interfaces. Simplicity and care are not opposites. Some of the most thoughtful designs I know are also some of the simplest.


But sometimes overly minimal, dare I say bland, interfaces communicate something else .... disinterest. The feeling that only the minimum amount of work was invested so a feature could exist.

I think users only get to see the final thing, and as a user I find it difficult to care more about something than I believe its creators cared about it.

Thats why details matter to me. Not because people consciously notice every reflection, shadow or hidden joke buried inside an icon, but because details are little traces left behind by the people who made it.

Evidence that somebody cared enough to spend time on things they didnt strictly need to spend time on. And I think people notice that (or I hope they do).


As Plans for Oxygen in Plasma 6.8.

The biggest one is probably the work being done to make Oxygen play much nicer with Kirigami applications. Hopefully the Union effort will enable us to finally start to port things over and tackle some of the rough edges.There is also the usual stream of icons, fixes and random details that somehow consume far more time than they have any right to :)I'm also hopeful we can make some progress on icon selection options. No promises yet... but its definitely on the list of things I would like to see happen. at lest the UI.

So stay tuned, Oxygen continues to slowly move forward. Which is honestly more than i expected when i started by "just fixing a bug"... heee...

Welcome to a new issue of This Week in Plasma!

This week was busy! We’ve got some great new features to share, improved theming compatibility, UI improvements, bug fixes… and lots more! This is one of those weeks with a bit of something for everyone ­— even people who are picky about software dependencies. Take a look:

Notable new features

Plasma 6.8

Spectacle now gives you the option to record audio during screen recordings! It can grab audio from the microphone, audio that the system is outputting, or both. (Khudoberdi Abdujalilov, KDE Bugzilla #474798)

Audio recording options in Spectacle

System Monitor can now measure VRAM usage as a percentage of the total, just like it can for regular RAM. (Beck Thompson, ksystemstats MR #135)

The 13-month Ethiopian calendar joins the growing ranks of supported alternate calendars! (Eyobed Awel, kdeplasma-addons MR #1079)

Ethiopian alternate calendar

Notable UI improvements

Plasma 6.6.6

Improved the responsiveness of the brightness slider in the Brightness & Color widget. (Marco Martin, powerdevil MR #650)

Plasma 6.7.3

The Vietnamese lunar calendar now displays its text in Vietnamese even if your system language is set to something else, which is more consistent with other alternate calendars. (Trần Nam Tuấn, KDE Bugzilla #521787)

Vietnamese alternate calendar with text written in Vietnamese

The feature to show alternative characters when you press and hold a key on the keyboard now triggers after 600 milliseconds of holding, rather than 200. This should make it much harder to accidentally activate. (Kristen McWilliam, plasma-keyboard MR #157)

You can now interact with the Overview and Custom Tiling overlays using a drawing tablet stylus in a Wayland session. (Nicolas Fella, KDE Bugzilla #468396 and KDE Bugzilla #522677)

Plasma 6.8

Comboboxes in Plasma now use the active Plasma theme to style their popups, rather than using a hardcoded Breeze-style appearance. And their menu highlights no longer animate in and out, either, which matches the appearance everywhere else. (Filip Fila, libplasma MR #1547 and libplasma MR #1550)

System Settings’ Remote Desktop page no longer looks somewhere between “very awkward” and “broken” with a small and narrow window size, like on a phone. (Nick Haghiri, krdp MR #208)

System Settings’ “Report a Bug in the Current Page” feature now works for pages that didn’t come from KDE but still list a bug reporting URL. (Antti Savolainen, systemsettings MR #412)

Auto-login now works in Plasma Login Manager on operating systems with older versions of systemd, like KDE neon. (David Edmundson, KDE Bugzilla #522006)

Brightness on external monitors now changes more quickly after you adjust the brightness slider in the Brightness & Color widget. (Kylie CT, KDE Bugzilla #498913)

Frameworks 6.29

When using the default qqc2-desktop-style system (as opposed to when testing the upcoming Union system), list and grid view highlights in QML-based KDE software now respect the visual styling of the active app style, rather than having a hardcoded Breeze-style appearance. In addition, password fields no longer change in height for certain fonts when you type the first character into them. (Evgeniy Harchenko, qqc2-desktop-style MR #521 and qqc2-desktop-style MR #524)

The Breeze icon theme now includes an icon for Android app bundle files. (Tobias Zwick, KDE Bugzilla #508430)

Montage of Android app bundle icons against light and dark backgrounds

The large fancy Kirigami tab bars seen in QML-based KDE software now switch the active tab when you scroll over them or press one of the standard tab-switching keyboard shortcuts — just like tab bars in QtWidgets-based apps do. (Tobias Ozór, kirigami MR #2123)

Notable bug fixes

Plasma 6.6.6

The Choose Application window no longer percent-encodes some characters in filenames, which looked pretty ugly. (David Redondo, KDE Bugzilla #521748)

The Media Frame widget no longer displays every other image in a somewhat sharpened and crunchy manner. (Marco Martin, KDE Bugzilla #521534)

Plasma 6.7.3

Fixed a recent regression that broke closing windows in the Overview overlay by middle-clicking them. (Xaver Hugl, KDE Bugzilla #522015)

Fixed a few remaining minor layout regressions in the Color Picker widget, so now it should always have the same size as it did in Plasma 6.6. (Tobias Fella, KDE Bugzilla #522377)

Fixed a recent regression in an X11 session that made icons of all running Flatpak apps appear unnecessarily in the System Tray. (David Redondo, KDE Bugzilla #522864)

Plasma no longer crashes if you disable the Calendar Events plugin in one Digital Clock widget when there are more than one of them with that plugin enabled. (Shouvik Kar, KDE Bugzilla #520465)

When the system is configured to automatically switch global themes at certain times of day, this switchover now takes place as expected even if the computer happened to be turned off when the transition would have taken place. (Vlad Zahorodnii, KDE Bugzilla #511740)

Plasma 6.8

Fixed a glitch related to scrolling in System Monitor’s Configure Columns popup, which is now a traditional window instead. (Arjen Hiemstra, KDE Bugzilla #517723)

In the Networks widget, connecting to a network you don’t have permission to edit no longer mistakenly makes all other available networks look connected. (Sergey Katunin, KDE Bugzilla #461028)

Frameworks 6.29

Fixed a subtle regression that prevented overriding settings set at the vendor/distro level (e.g. via a /etc/xdg/kwinrc file) that differed from Plasma’s own default settings. This affected Kubuntu and Fedora, which turned on Wobbly Windows and Plasma Keyboard, respectively. (Nicolas Fella, KDE Bugzilla #519481)

Typst documents once again show a fancy icon when using the Breeze icon theme, fixing an issue where this stopped happening after the official MIME type for Typst files was changed upstream of KDE. (Boris Jurcaga, breeze-icons MR #554)

Montage of Typst icons against light and dark backgrounds

Notable in performance & technical

Plasma 6.6.6

Using a udev rule to set the LIBINPUT_CALIBRATION_MATRIX property now works as expected in a Wayland session. (Nicolas Fella, KDE Bugzilla #521464)

Plasma 6.8

Spectacle no longer requires the fairly chunky OpenCV software library; we found a way to implement an adequately-performant blur effect without it. (Noah Davis, spectacle MR #561 and kquickimageeditor MR #53)

How you can help

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.

Would you like to help put together this weekly report? Introduce yourself in the Matrix room and join the team!

Beyond that, you can help KDE by directly getting involved in any other projects. Donating time is actually more impactful than donating money. 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 out by making a donation! This helps cover operational costs, salaries, travel expenses for contributors, and in general just keeps KDE bringing Free Software to the world.

To get a new Plasma feature or a bug fix mentioned here

Push a commit to the relevant merge request on invent.kde.org.

Friday, 10 July 2026

Let’s go for my web review for the week 2026-28.


Chat Control 1.0: EU Council forces messenger scans via fast-track

Tags: tech, europe, surveillance

This is a shady move once more… They really want to extend this security apparatus. We could hope there were enough MEPs to vote against this… but it’s not been the case.

https://www.heise.de/en/news/Chat-Control-1-0-EU-Council-forces-messenger-scans-via-fast-track-11353659.html


You paid me, a long-time Linux user, to use Windows 11 exclusively for a month: here’s how it went

Tags: tech, windows, funny

Funny experiment. If you’re a Linux user pondering going back to Windows it’ll likely cure you. Goodness the install experience is abysmal and that’s just the beginning of the troubles. Of course it has a good side as well but it feels fairly limited.

https://www.osnews.com/story/145459/you-paid-me-a-long-time-linux-user-to-use-windows-11-exclusively-for-a-month-heres-how-it-went/


Democratizing Abandonware

Tags: tech, ai, machine-learning, gpt, copilot, slop, flatpak, codereview

The data set is rather small but the trend is really bad. So much reviewer time wasted due to AI slop… this time on the Flathub side.

https://geopjr.dev/blog/democratizing-abandonware


I am not a tool

Tags: tech, ai, machine-learning, gpt, copilot, ethics, foss

Really this kind of AI push is a bad move from employers, especially when interacting with FOSS communities so much. This forces people to pass the ethical issues onto volunteers…

https://eng.hroncok.cz/2026/07/07/ai-tool


Bosses Horrified as “AI Native” College Graduates Hit the Workplace

Tags: tech, ai, machine-learning, gpt, productivity, education

How is going this social experiment at scale? Not well I’d say… And some in those cohorts will end up in positions of power, that’s when it’ll become really “interesting” I guess.

https://futurism.com/future-society/college-critical-thinking-ai


Local, CPU-Friendly, High-Quality TTS with Kokoro

Tags: tech, ai, machine-learning, speech

This keeps being a very interesting TTS model. Looks like it’s getting simpler to deploy too.

https://ariya.io/2026/03/local-cpu-friendly-high-quality-tts-text-to-speech-with-kokoro/


Cpp2Rust: Automatic Translation of C++ to Safe Rust

Tags: tech, c++, rust, compiler

Still need some work I’d say but this is interesting research. Transpiling C++ to Rust is getting more accessible. It need some improvements on the optimisation side to be more generally usable.

https://web.ist.utl.pt/nuno.lopes/pubs/cpp2rust-pldi26.pdf


Physically Based - The PBR values database

Tags: tech, shader, pbr, physics

Cool resource to have the right values for various PBR materials.

https://physicallybased.info/


How I’m using CSS View Transitions on this blog

Tags: tech, html, css, animation

A good reminder that you can go a long way to specify transitions with just CSS nowadays.

https://blog.omgmog.net/post/how-im-using-css-view-transitions-on-this-blog/


Size does matter, actually

Tags: tech, web, performance, complexity

There are ways to have a lighter web. It leads to interesting techniques too.

https://nh3.dev/blog/05-bloat


98% isn’t very much

Tags: tech, reliability, statistics

Can you rely on something? Indeed, if it fails “only” 2% of the time it can mean a lot of failures… you better handle the edge cases and degrade gracefully.

https://whynothugo.nl/journal/2026/07/03/98-isnt-very-much/


a software engineering interview question I like: computing the median

Tags: tech, hr, interviews, complexity

I like this kind of questions as well. It’s more interesting to aim for something simple to start with than a puzzle. Even topics considered simple have several layers of complexity.

https://krisshamloo.com/blog/007


The Lion, The Witch, and the audacity of recruiters

Tags: tech, hr, interviews

Whatever the hiring process, show some respect to the candidate. It’s the least you can do for them.

https://hauleth.dev/post/the-lion-the-witch-and-the-aduacity-of-recruiter/


The myth of mind uploading

Tags: tech, scifi, science, philosophy

A long piece, but digs in details on why “mind uploading” really can’t be a thing.

https://plus.flux.community/p/the-myth-of-mind-uploading



Bye for now!

Thursday, 9 July 2026

Introduction

At this year’s LLW we held a workshop to finally come up with something that all present could agree was a solution to the problem that client-side1 JavaScript, CSS etc. gets distributed to the user without proper (or typically any) license and copyright information.

I first presented a short summary of my initial controversial proposal as well as the feedback obtained at FOSDEM, LLW and other sources. Then we discussed in a group consisting of OSPO leaders, FOSS lawyers and FOSS developers on what would be a good solution. Thankfully, we were able to rely quite a bit on the outcomes of a similar “REUSE-ify JS/CSS” workshop at LLW 2025.

To my big surprise, we pretty quickly came to an agreement what such a solution could look like.

In contrast, it was no surprise that the final solution had very little in common with my initial controversial proposal from 2024. So please forget about that one if it is still causing you high blood pressure.

Solution

TL;DR

  1. apply REUSE.software best practices, just as you would with writing in any other programming language
  2. use a tool of your choice to generate either:
    • an SBOMSPDX, CycloneDX, or whatever you prefer
    • an attribution file, of whatever kind you prefer
    • whatever document/file/webpage you feel is the most appropriate way to fulfill your licensing obligations
  3. make sure that the file/page from 2. is linked in a <link rel="license" href=""> HTML tag in the HTML <head>
  4. create something in the web UI to present this link too, using a <a rel="license" href=""> HTML tag in the HTML <body>

Explanation

Just use REUSE

The first step should be pretty self-evident to any regular reader of my blog. REUSE.software has become the de facto standard for marking source code with licensing and copyright information. It essentially takes the SPDX (ISO/IEC 5962:2021) standard and implements it directly in source code2.

The big difference between this and the initial proposal is that the wrap-all-files-as-snippets hack is not needed – good riddance!

So, just follow the simple instructions on REUSE.software.

Create a compliance document

Regarding the second and third step, already at LLW 2025 we identified that it would be much better to ship a file/document alongside, instead of keeping tags in minified source code. Some companies already reported doing something similar, but not in any standardized way – and that they would very much be in favour of having a convention to follow.

When debating, we quickly came to the conclusion, that different organizations would have different tools3 and different processes on how to generate and handle license compliance artifacts. So we decided to leave the details of what exactly constitutes the best format to each project and organization, and concentrate on the how part instead (see subsection below).

Some options that were brougt up for you to consider:

  • SPDX 2.x SBOM (in a variety of formats)
  • SPDX 3.x SBOM
  • CycloneDX SBOM
  • tool-generated “attribution” file4 – typically in HTML format; typically lists components as PackageURL, their copyright holders and licenses
  • manually written “attribution” document/notice

Distribute the compliance document to machines

And now for the “how” part.

As SBOM are typically primarily machine-readable, it would make sense to use a standard way of communicating said SBOM.

Luckily, the HTML standard already provides for something like this in the headers.

We can simply use a <link> tag with rel=license and the appropriate MIME type.

Where the rel=license attribute specifically is very topical:

license

Valid on the <a>, <area>, <form>, <link> elements, the license value indicates that the hyperlink leads to a document describing the licensing information; that the main content of the current document is covered by the copyright license described by the referenced document. If not inside the <head> element, the standard doesn't distinguish between a hyperlink applying to a specific part of the document or to the document as a whole. Only the data on the page can indicate this.

So this could look something like:

<head>

    <link
        rel="stylesheet"
        href="/static/client/styles-global.8f1bfba40e45c550.css"
        fetchpriority="high"
        />
    <link
        rel="preload"
        href="/static/client/inter-latin.9a3b1bc220d426ef.woff2"
        as="font"
        type="font/woff2"
        crossorigin="anonymous"
        fetchpriority="low"
        />
    <script
        data-cfasync="false"
        data-report-only="on"
        data-prompt="0"
        src="https://transcend-cdn.com/cm/d556c3a1-e57c-4bdf-a490-390a1aebf6dd/airgap.js"
        >
    </script>

<!-- NB: this is the one we’re looking for: -->
    <link
        rel="license"
        href="sbom.spdx.json"
        type="application/spdx+json"
        fetchpriority="high"
        />

</head>

With this in place, if you wanted to check a compliant website/webapp for licensing and copyright information relevant to the software (and styling) your web browser is downloading, all you would need to do is have some software check for the appropriate <link rel="license"/> and download or parse it.

Distribute the compliance document to humans

Understandably, you may5 also want to make it easy for humans to be able to see which licenses apply.

Again, we quickly came to the conclusion that different web apps have different technical or UI capabilities, and different organizations have different approaches too. So anything too rigid would not work.

But what we can do is to create some guidance on how to leverage the above. And, hoo boy, are we in luck today! The <a> HTML tag can also use the rel="license" attribute.

Some ideas on where to put the link though:

  • just a link somewhere, e.g. in the footer
  • (small) banner to pop-up the information
  • an entry in a menu

Note as well, that nothing prevents us from having more than one rel="license" element, so we can serve different formats at the same time this way. Indeed, we could even serve an SBOM (or other licensing document) for each component separately, if we wanted.

As most humans will not readily consume SBOM, let us expand the above example a bit:

<head>
    <!-- A machine-readable SBOM in JSON format -->
    <link
        rel="license"
        href="sbom.spdx.json"
        type="application/spdx+json"
        fetchpriority="high"
        />
    <!-- A human-readable HTML ”attribution” document -->
    <link
        rel="license"
        href="attribution.html"
        type="text/html"
        fetchpriority="high"
        />
</head>
[…]
<body>
[…]
    <footer>
        <!-- A human-readable notice in the footer, linking to the “attribution” document -->
        This website is licensed under 
        <a rel="license" href="https://creativecommons.org/licenses/by/4.0/">CC-BY-SA-4.0</a>
        with the client-side software and styling under several FOSS licenses – the information to which, you can get in
        <a rel="license" href="attribution.html" type="text/html">human-readable</a> and 
        <a rel="license" href="sbom.spdx.json" type="application/spdx+json">machine-readable</a> form.
    </footer>
</body>

Prioritizing the delivery of licensing documents (optional)

Some German colleagues suggested that in their jurisdiction it may be important that license is shared at the exact same time as the content it covers. This raised the question of whether this compliance document should be forcefully pushed to the user’s/visitor’s browser and if so, when.

As the web development continues to be penny-pinching white-space6 in order to have webpages load faster, this is likely to be a show-stopper if we made it obligatory to fetch an SBOM before (or at the same time as) loading JS and CSS.

So the suggestion is, again, to leave it to each project and organization to decide.

Our old friend <link> has some features that help us here too.

You may have noticed in the above example that we used the fetchpriority="high" HTML attribute. As its name implies, this causes the compliance document to load in the browser sooner than other elements.

If you feel this is not fast enough either, you could even try out the rel=preload attribute in combination with <link as="">. But, to be honest, I would expect some big ire from the web developers if you did that, and there seems to be no ideal as="" to “preload as” either, because license is not an option there.

On the flip-side, if you are of the persuasion that licensing information should not hinder the speed the website loads, you could also set fetchpriority="low" instead. Do not come crying to me if a German court decides that you have made a grave mistake, though.

Example

Above I showed how this would look like in HTML itself. Here is a super-simple7 example of how it could look like.

Copyright and licensing

This website is licensed under CC-BY-SA-4.0 with the client-side software and styling under several FOSS licenses – the information to which, you can get in human-readable and machine-readable form.

What about?

Garbage in = garbage out

Did we solve everything now? Is there finally peace on earth and cancer is eradicated? Of course not.

The original sin of developers simply not storing (enough) copyright and licensing information in their software is still here.

But what we have achieve with this, is to provide a solution on how to easily, without much extra work and tooling:

  • store this data – just use REUSE.software as in every other programming language; and
  • provide this data – serve the results in <link rel="license"> and <a rel="license">

Of course, this still leaves work to actually mark all the front-end code with REUSE/SPDX tags, but at least that is fairly easy to do and has a growing following in both the community and industry alike.

So, please, consider this as a call for tagging your web front-end code with REUSE.software. It really is quite easy, I promise!

Size of the website

How does this proposal affect the size of the website and the speed of its loading, you wonder?

I have not done any tests this time round, but unless I heavily misunderstand how HTML (and HTTP) work:

  • the minified JS/CSS itself will not increase a bit;
  • you can tweak the “speed” of your webpage loading by setting the fetchpriority attribute to either
    • low, if you prefer the page to load faster but and OK with the risk; or
    • high if you are risk averse and OK with the page loading slower.

Also see the file-size analysis in my previous blog post on this topic for some actual PoC and tests.

Conclusion

I think we finally cracked it!

This is the plan.

The building blocks already exist.

Now we just need to build it together – each in their own little corner of the web, little by little :)

hook out → well, that was a long journey…

P.S. If you were part of this project and wanted to be attributed, please let me know. Since a lot of it was done in meetings under the Chatham House Rule, I did not attributed without explicit agreement.


  1. Also known as “browser-side” JavaScript/CSS

  2. In fact, SPDX’s Annex H: Specifying SPDX information in source files (a.k.a ”SPDX File Tags”) is there because of REUSE and was developed alongside the version 2 of REUSE specification. 

  3. In case you are looking for a simple tool to generate SBOMs from a REUSE-compliant code base, the easiest way is to simply use REUSE’s own reuse tool. For more tooling suggestions check out Open Source Tooling for Open Source Compliance

  4. For example, you could use the ScanCode toolkit to generate an “attribution” file or FOSSology to generate a “notice“ file. 

  5. Arguably, this is the more important part. 

  6. IMHO, a much bigger loading speed increase could be achieved, by just not bundling everything and the kitchen sink in the JS “required” to parse a website, but what do I know … 

  7. The example uses an SBOM that is completely unrelated to this website too. It is just for demonstrative purposes. I also skipped the <head> part, as I did not want to make my blog show bogus licensing info everywhere. 

Myself and others have been contributing to Koko under the banner of Techpaladin Software. Here’s what we’ve been up to over the past year.

Qt for MCUs 2.12.2 LTS has been released and is available for download. This patch release provides several bug fixes and other improvements while maintaining source compatibility with Qt for MCUs 2.12 (see Qt for MCUs 2.12 LTS released). This release does not add any new functionality however as part of a continuous effort to scale Qt for MCUs to more platforms new Tier-2 board Nuvoton Gerda-4L is now available.