Skip to content

Monday, 31 August 2026

Welcome to this edition of This Month in KDE Linux, dedicated to KDE’s next-generation operating system.

Here’s how KDE Linux evolved in August:

Data safety

A major data safety project reached a state of usability!

First, Hadi Chokr transformed users’ home folders into Btrfs sub-volumes and turned on automatic Btrfs snapshots for all user files.

Then, Bharadwaj Raju integrated the new kio-snapshot system he’s been working on and added support in Dolphin.

Now you can easily view and roll back to older versions of your files, even without an off-device backup:

Three snapshots of a file named “Family trip ideas.md” from different points in time

This doesn’t replace a backup, of course! But it does amount to a sort of homedir-level undo feature that can keep your data safe from accidental deletions, or other destructive changes that are less catastrophic than a disk failure or having the device lost or stolen. And these snapshots will be useful to use as backup sources, so you’re not trying to back up a moving target.

Another few layers in the data safety onion, shall we say!

CJKV input support by default

Nate Graham finished the project to make Chinese, Japanese, Korean, and Vietnamese text input work out of the box. Now everything needed to type in these languages is pre-installed, and all you have to do is turn it on.

QA & testing

Thomas Duckworth and Bhushan Shah continued to develop, refine, and maintain KDE Linux’s automatic QA system, which continued to pay dividends this month. The system caught multiple complex integration issues introduced accidentally in commits made to KDE software — all of which are now fixed, so users of other operating systems will never have to experience them.

Security

Yago Raña Gayoso removed an unnecessary override that gave everyone in the wheel group default access to the Docker daemon’s socket.

Nate Graham fixed an oversight that let blacklisted kernel modules into the unified kernel images.

Bugs fixed

Harald Sitter fixed an issue that could make updates fail right after the update was published, or when run on machines with weak CPUs or slow network connections.

Hadi Chokr fixed an issue with user-visible version numbers of KDE Linux builds not including the intended level of precision.

Documentation

Nate Graham added quick links to KDE Linux’s official documentation right there in the launcher menu’s “Help” section.

Kickoff widget’s “Help” category showing entries for “Documentation” and “Help & Support”

Nate Graham also documented how to free up disk space, added a dedicated “Help & Support” page to the website, and added a link to the project’s news feed.

Philip Grant refined and documented a way to integrate KeePassXC with the Flatpak packaging of Firefox and Chromium (and their derivative browsers).

Julius Künzel fixed the styling of the standard Hugo alert bubbles, and Nate Graham ported the docs to use them.

Grab bag

Paul Brown added a neat feature to the set-up-systemd-extension tool that lets you create new extensions at different locations and with different names.

Hadi made the installer report its progress in a more granular way, so there’s less waiting around and wondering if the installation process got stuck.

Bhushan Shah removed the “UEFI shell” entry from the bootloader menu, since it was useless for practically everyone, and now the menu is less cluttered.


How you can help

KDE Linux is making steady progress towards its Beta milestone, and is now 85% of the way there.

There’s lots to do! If you’re a fan of the project, please help out; there are many ways:

We are happy to announce the summer release of Kdenlive 26.08. Continuing the efforts from the last version, the core team has been focusing mostly on stability - fixing bugs and crashes while also doing lot's under the hood improvements.

This release comes with 11 crash fixes as well as improvements to the undo/redo stack for compositions and sequence creation. Work has also been done to modernize the codebase in the Qml loader for Clips and Compositions.

The majority of the new, nifty and shiny additions and enhancements in this release were made by new contributors! This seems to have become a tradition in 2026, and we couldn’t be happier about it.

Highlights

Timeline

Automatic Track Creation

Added functionality to automatically create audio tracks when adding a clip to the timeline in case there are not enough. Implemented by Vineet Tiwari.


Reorder Tracks

Added a long awaited ability to reorder tracks. Implemented by Vineet Tiwari.


Markers At Gaps

Added option to add markers at gaps between timeline clips. Implemented by Yash Bavadiya.


Playhead Snapping When Dragging

ALT + drag the time cursor (playhead) in the timeline ruler, it now snaps to nearby snap points like clip edges, guides, markers, and zone in/out. Implemented by Yash Bavadiya.


Copy Selection To New Sequence

It works similarly to "Create sequence from selection" except that it does not remove the clips from the original sequence and replace them with the new sequence clip. Implemented by Vineet Tiwari.


Clip Color Configuration

Added an option to configure colors for video, audio, title, image, and slideshow clip types.

Color Clip Configuration

Playhead/Mouse Zoom

Added a button in the Status Bar to toggle between zooming to the mouse cursor position or the playhead position. Implemented by the mrfantastic.


Multi-Clip Speed Changes

Added the ability to change the playback speed of multiple clips at once either by directly Ctrl + dragging in the timeline or by using the Clip Speed tool. Implemented by Vineet Tiwari.

Title Editor

Snapping

Added snapping in the Title Editor. Implemented by chocolateimage.


Rounded Corners

Rectangles now can have rounded corners. Also notice the draggable spinbox ability to change the radius. Implemented by chocolateimage.


Copy/Paste

Added the ability to copy and paste elements in the Titler. Implemented by chocolateimage.


Automatic Clip Replacement

Added option to automatically replace a title clip in the timeline with the new title clip being edited. Implemented by Eduardo Guedes.


Miscellaneous

Additive Soloing

Added the ability to do additive soloing in the audio mixer by shift clicking. Implemented by Patrick Williamson.


Adjustable Rotation Anchor

Added the ability to set the rotation anchor in the Transform effect. Implemented by Jean Baptiste Mardelle.


Other Noteworthy Changes

  • Updated effects with text (GPS Text, Dynamic Text, Timer) to allow for more font properties. Implemented by Bernd Jordan.
  • Rectangular alpha mask is now animatable. Implemented by Jean Baptiste Mardelle.
  • Added ability to use math expressions in effects values. Implemented by Jean Baptiste Mardelle.
  • Drawbox and Delogo effects use the newly implemented feature to draw a rectangle directly on monitor. Implemented by Jean Baptiste Mardelle.
  • Added the frei0r Color Enhance effect. Implemented by Bernd Jordan.
  • Added option to add rendered video to project bin in the Render Widget. Implemented by Jaimukund Bhan.
  • Multi-cam Editing: Added functionality to insert clips to timeline using the clip's timecode from their metadata (if they contain it). Implemented by Jaimukund Bhan.
  • Ability to open video, audio, image files from file managers or CLI environments with Kdenlive. Implemented by Yash Bavadiya.
  • Added webp support for image sequences. Implemented by Farid Abdelnour.

Give back to Kdenlive

Releases are possible thanks to donations by the community. Donate now!

Need help ?

As usual, you will find very useful tips in our documentation website. You can also get help and exchange your ideas in our Kdenlive users Matrix chat room.

Get involved

Kdenlive relies on its community, your help is always welcome. You can contribute by :

  • Helping to identify and triage bugs
  • Contribute to translating Kdenlive in your language
  • Promote Kdenlive in your local community

For the full changelog continue reading on kdenlive.org.

We're excited to announce the release of version 1.16.0 of the Qt Extension for Visual Studio Code! This release brings:

  • QML Profiler and Trace Viewer to profile your QML applications directly from VS Code
  • A new Welcome page with browsers for Qt examples and Qt Academy courses
  • Better PySide support with QML Live Preview and uv virtual environments

For once, something on this blog that isn’t C++.

Harmonicon is a rhythm game for blues harmonica. Notes scroll toward a hit line and you play on an actual harmonica, into your microphone, and the game listens.

The idea

The harmonica is cheap, fits in a pocket, and it hides everything: the reeds are inside, your tongue and throat do most of the work, and nothing about the instrument tells you whether the note that just came out is the note you meant. You can practise a bend wrong for a month quite happily.

Let the instrument be the input. Harmonicon captures the microphone, runs pitch detection on it in real time, and scores what you actually played against the chart. Every note you score is a note you genuinely hit.

Playing a song

The 2D play mode: a lane per harmonica hole, with notation and a tab readout above

The default view is one lane per hole: ten for a diatonic, twelve for a chromatic, taken from whatever the chart was written for. Blue notes are blows, orange are draws, and the number on each is the hole you need. Above the lanes there’s the phrase in standard notation and as harmonica tab, because those are the two ways harmonica players actually read music, and the panel on the right tells you which harp to pick up and which position you’re playing in.

There’s also a 3D view, which is the same game rendered around a harmonica model that moves with the beat.

The 3D play mode: notes travelling down toward an animated harmonica model

Getting away from charts

Charts are good for learning a song and bad for learning to play. The Jam Session mode drops the scoring entirely and gives you a rolling 12-bar blues to improvise over.

Jam Session: a 12-bar chord grid on the left, a live-tinted hole map on the right

The useful part is the hole map on the right. As the backing moves through the bars, each hole recolours: gold if it’s a chord tone of the bar sounding right now, green if it’s elsewhere in the blues scale, dim if it’s going to sound wrong. You follow the colour instead of trying to recall theory at tempo, and the theory arrives later, on its own.

Lessons

The lessons list, grouped into units from fundamentals to jazz

There’s a curriculum underneath all of this, grouped into units and gated by prerequisites — from getting one clean single note out of the thing, through bends and articulation, up to improvising over a blues. Some lessons are scored drills. A few aren’t scoreable at all: tongue blocking sounds identical to puckering from the microphone’s point of view, so that one is instruction you mark as done and the game trusts you.

Under the hood

Rust, with Bevy for the engine and cpal for audio capture. The interesting problem is the pitch detection, which is why there are five algorithms to chose from: FFT, YIN, pYIN, MPM and NMF.

Status

There’s a lot in it — a bending trainer, an in-game song editor with MIDI import, adaptive difficulty, A–B looping, latency calibration, a spectrogram — but “early/experimental” is an honest label rather than modesty.

It’s MIT licensed and the code is at github.com/tcanabrava/harmonicon. If you own a harmonica and a microphone, that’s the entire hardware requirement.

Sunday, 30 August 2026

And I think it’s pretty nice

Friday, 28 August 2026

Welcome to a new issue of This Week in Plasma!

This week saw the first stirrings of support for QtWidgets-based apps in KDE’s new Union theming system, which is a very exciting milestone.

But that’s not all! This week is also packed with UI improvements, performance improvements, bug fixes, and a few more features, too.

Plasma 6.8 is rapidly shaping up, and all this work reflects it. Check it out:

Notable new features

Plasma 6.8

The new Union theming system has gained initial support for styling QtWidgets apps! (Akseli Lahtinen, union MR #270)

Dolphin file manager styled with Union
I’m sure you can see numerous visual glitches in the screenshot above. This is a first draft with many known visual bugs, and we’ll work on getting those smashed as quickly as possible. But still, very exciting! The Union theming system is coming together nicely. Read more about it on Akseli’s blog.

Plasma’s built-in RDP server now supports adjusting its quality level to the network’s available bandwidth to keep the frame rate as consistent as possible. (Nick Haghiri, krdp MR #238)

Plasma’s Strongswan VPN support now allows the use of EAP-TTLS authentication. (Wyllian Bezerra da Silva, plasma-nm MR #636)

Notable UI improvements

Plasma 6.7.5

Discover now only offers to open and install .deb packages on operating systems natively supporting that package format. (Aleix Pol Gonzalez, plasma-desktop MR #3957)

Plasma 6.8

When you copy a password or other piece of text that the app says is a secret, the clipboard history UI now makes this clear rather than hiding it and letting you wonder why nothing appeared there. (Tobias Fella, KDE Bugzilla #508326)

Warning about sensitive data on the clipboard

The indicator that a screen recording is in progress now only appears if it actually is in progress, which handles the case of apps that open screen recording sessions early, but start the recording later. (David Redondo, xdg-desktop-portal-kde MR #597)

KWin’s Overview effect is now a little bit easier to open with a four-finger swipe touchpad gesture. (Remy Farley, kwin MR #9486)

All of the text for calendar events in the Digital Clock widget is now selectable. (Nate Graham, KDE Bugzilla #433668)

System Settings’ Drawing Tablet page now has a less awkward design for the dialog window to choose what the buttons on your tablet’s pen do. (Joshua Goins, KDE Bugzilla #524720)

New New
Old Old

The Bluetooth widget now shows its “Configure” button in the same place that all other widgets do, for better functional consistency. (Tomáš Hnyk, KDE Bugzilla #516134)

Connecting to an enterprise Wi-Fi network for the first time now takes you immediately to the place where you can enter your credentials, instead of making you navigate there manually. (Ramil Nurmanov, plasma-nm MR #635)

Clicking a System Tray icon that opens a widget can no longer make that icon immediately disappear; now, it will always stay visible until the widget’s popup closes, giving you the opportunity to click on it a second time to close the popup. (समीर सिंह Sameer Singh, KDE Bugzilla #521115)

Using the clipboard’s “Keep the selection and clipboard the same” setting no longer unnecessarily disables other settings. (Tomáš Hnyk, KDE Bugzilla #492840)

If your system is in such a poor state that there are many crashes, your System Tray no longer fills up with dozens of little sad face icons; now only one appears, and clicking on it will show the full list in its own window. (Tobias Fella, KDE Bugzilla #420443)

Frameworks 6.30

In-window dialogs in Kirigami-based apps are now better highlighted against the rest of the window content when using a dark theme. (Marco Martin, KDE Bugzilla #447965)

System Monitor graphs now request “tabular numerals” for the legends when using a font that supports them, improving alignment. (Christoph Wolk, kquickcharts MR #109)

New New
Old Old

Notable bug fixes

Plasma 6.6.7

Fixed a security issue that made the screen locker fail to lock if you manually configured it to turn off the screen after the “don’t require password to unlock” period. (Xaver Hugl, KDE Bugzilla #523504)

Plasma 6.7.5

Fixed a pretty bad bug that made Discover get stuck while checking for updates when its Snap backend was present, but there were no upgradeable Snap apps. (Dustin Trumps, KDE Bugzilla #524077)

Fixed a case where non-KDE apps running in Plasma could sometimes crash when you closed a dialog. (Balló György, KDE Bugzilla #523039)

Fixed a recent regression that impaired pointer movement in VMs using non-accelerated graphics drivers. (Base Devel, KDE Bugzilla #524280)

Using a right-to-left language like Arabic or Hebrew no longer prevents force-quitting processes or apps in System Monitor. (Jakob Petsovits, KDE Bugzilla #522233)

Fixed a weird little bug that made the panel’s tooltip in edit mode become malformed after right-clicking on the panel. (Christoph Wolk, KDE Bugzilla #488578)

If your system is in a super-duper messed-up state, it can at least no longer cause the DrKonqi crash handler to crash in a loop, feeding itself with crashes that exhaust the system’s memory. (Harald Sitter and Alexander Berg, KDE Bugzilla #524048)

Plasma 6.8

Fixed the second-most-common crash in Plasma, which could happen while logging out. (Tobias Fella, plasma-workspace MR #6973)

On System Settings’ Plasma Search page, the “Defaults” button and non-default settings highlighting now work as expected. (Tobias Ozór, plasma-desktop MR #3973)

With multiple Application Launcher (Kickoff) Widgets, all of them are now capable of returning search results for not-yet-installed apps, not just the first one. (Christoph Wolk, KDE Bugzilla #511220)

A logout sound no longer delays the logout process more than it needs to. (Ramil Nurmanov, KDE Bugzilla #491745)

Notable in performance & technical

Plasma 6.7.5

Improved the way HDR content looks when using an ICC profile. (Xaver Hugl, KDE Bugzilla #524038)

Plasma 6.8

Improved the performance and power efficiency of many kinds of full-screen content when using an Intel or NVIDIA GPU with HDR, ICC profiles, and/or the Night Light effect. (Naveen Kumar, kwin MR #9640)

KWin now supports HDR content using the HLG transfer function. (Xaver Hugl, KDE Bugzilla #508817)

Reduced screen-casting latency throughout Plasma and KWin (including for the built-in RDP server!) by one frame. (David Edmundson, kpipewire MR #274)

Reduced the resource usage required to show thumbnails in notifications and the Activities sidebar. (Kai Uwe Broulik, plasma-workspace MR #6966 and plasma-desktop MR #3967)

Reduced the resource usage required for the Trash widget. (Kai Uwe Broulik, plasma-desktop MR #3965)

Screenshots made with Spectacle that don’t have any transparency no longer include an alpha channel, slightly reducing file sizes. (Kai Uwe Broulik, kwin MR #9798)

Disabling a System Tray widget now frees up its memory immediately, rather than only after Plasma or the system is restarted. (Tomáš Hnyk, plasma-workspace MR #6983)

The showConfigurationInterface() function now works in Plasma scripting. (Remilia S., plasma-workspace MR #6977)

If you’ve broken, misconfigured, or removed all of Plasma’s wallpaper plugins, Plasma will now launch without them and just show a plain background, instead of failing to launch at all. (Ramil Nurmanov, KDE Bugzilla #524875)

Frameworks 6.30

KWallet no longer spams your log with errors in certain non-default configurations. (Nicolas Fella, KDE Bugzilla #524500)

KDE Gear 26.12.0

System Settings’ Proxy page has been rewritten in QML, which lets it work on Plasma Mobile. The design is nearly identical, so you shouldn’t notice any obvious changes to it. (Tobias Fella, kio-extras MR #536)

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.

It has begun.

After couple months of work, I have now finally managed to cobble together the QtWidgets side of Union.

This means that your QtWidgets apps, such as Dolphin, KMail, Kate etc. can now use the Union CSS files as the source of their styling.

However, temper your expectations, as this is the first initial release!

My lizard fursona making an smile face.

Do note that there are visual bugs and oddities! I'm still working on things!

So yes, as you can see, some things look off. Not Breeze at all! Some things are just different, some other things have wrong colors.

These are all fixable and I will do my best to get as many things as possible fixed for the Plasma 6.8 release.

But some other oddities are kind of expected: This is the first time ever Breeze QtWidgets and QtQuick style have same shared source-of-truth as an easily editable file! (Excluding colorschemes.) So some of these designs are made with QtQuick in mind, so they can look a bit off in QtWidgets.

I'll go through here what I did and what still needs to be done, but this was a huge undertaking, so I'm having a small celebration for the very first release of this. :)

Hold on, can I try it!?

Yes! It should be released in Plasma 6.8, unless someone tells me no. As of writing this, nobody has said no.

You can make your own CSS files and see them affect QtWidgets apps too. Just expect some breakage and report all the bugs!

Go crazy with the themes. Try everything. Bring back whimsy to computers. Tell us about the theming experience in general.

Have fun. Your computer should be just as cool as you are.

The rest of this blogpost is more a technical rant and ramble as I am venting all the exhaustion over this thing, lol.

QStyle is difficult

QStyle themes, which are the styles that modify the look of QtWidgets applications, are not easy to work on. Most themes I've seen take an existing one, such as Fusion or Breeze and make their changes on top of those.

But for Union, we had to start from scratch. I took the very basic base of QStyle, which is called QCommonStyle (kind of a fallback theme), and began building on top of that.

Then, there was multiple parts:

  • Figure out a way for the QStyle to paint things using CSS
  • Build a hierarchy of the style by reading the CSS data and applying it to QStyle world
  • Create a completely new set of element files we use
    • The QStyle themes are very unwieldy and hard to work on otherwise
  • Go through every single element and ensure they read all data from the CSS correctly
    • And ensure the style stays backwards compatible!
    • This is still ongoing process, most bugs lurk here. :P
  • Figure out how to use Union layouting system within QStyle elements
    • This is also buggy, as QStyle is more "rigid" with layouting
    • Applications expect very specific layouting from QStyles over the years it has existed
    • So any application that deviates from those expectations will look broken
  • Caching so that the style is performant
    • Here Arjen helped me a lot, thank you!
  • And a lot of other stuff I have already forgotten..

Thankfully redstrate had already made the painting part for the very simplified proxystyle (which took Breeze and modified it a bit), so I did not have to modify that too much. I mostly had to poke at it to make it work with my hierarchy system. So thanks! <3

It's hard to put it into words how much work there was involving the actual QStyle itself and creating a sort of "framework within a framework" so that the Union rules would translate better for the QStyle rules.

For example, when a widget, such as a PushButton, wants to be styled, it informs the QStyle about it with something called QStyleOptionButton. This class holds bunch of information about the button, and the style can use that information to decorate it better. But of course, the styleoption does not necessarily need to exist. If there is no styleoption, the style can use the QWidget itself for style information. But even that can be empty! And at that point, you do not know how to style something, since you do not even know what it is.

What made matters even worse was that the documentation just Does Not Exist.

Sure, there is the QStyle documentation, but it is more about "what" and not "why" or "how." I could have used somekind of tutorial for how to make a QStyle from scratch, but I could not really find anything, except super old information from Qt4 times. So very very often I resorted to just reading the raw source code itself, which is also not very easy to read. There is a lot of variables that are just named pw or w. So even the codebase is very undocumented..!

Most of the work had to be done with trial and error! "What happens if I change this value?" "What if I use debugger to follow this variable, where will it lead?" I also used Breeze as my information bank a lot, as it had gone through it all before. That was very helpful.

But the lack of documentation and old codebase nobody seems to really touch anymore, much less document, was the thing that made this all take so long time.

My lizard fursona making an grumpy face.

Not to forget the completely misleading names in the API. "PM_MenuPanelWidth" is not the width of the panel, but actually "Border width (applied on all sides) for a QMenu."

The total work was 9000 lines of code. Yes. And all of it is required. Lot's of boilerplate, as QStyle seems to love boilerplate. Pretty much all of it is artisanal, handwritten slop by yours truly.

I had to painstakingly go through all the elements we're drawing and sizes we're calculating, then turning it into an Element that we can easily modify without modifying the whole style.

If you have managed to make a working QStyle theme completely from scratch, going through every little detail, I salute you. This is some of the toughest stuff I've ever worked on.

So in summary: I had to backwards engineer a lot of stuff to figure out what order we even draw some things, or what size affects what in the actual application. Then make it work with Union core and CSS.

My lizard fursona making an scream face.

DOCUMENT YOUR API PLEASE I BEG YOU

Next steps

Next up is testing and bugfixing.

There's already a lot of bugs being found here: https://invent.kde.org/plasma/union/-/work_items/205 And more will be found. There will be weird edgecases where application expects everything to work like in Fusion style, as it's the default Qt style, but Union does not handle that situation yet well.

So here's what I need from you, dear reader: See what breaks. Document it. Make a bugreport. Let's find these weird things and figure them out, so that the QtWidgets side can finally be themed without so much pain.

Of course, there's also the design side: Like I mentioned earlier, the Breeze CSS we have now is very QtQuick oriented, so QtWidgets applications can look and feel odd.

Something to keep in mind though is that QtQuick and QtWidgets applications will likely never look the exact same, due to the way how they work and are drawn. But we can try to make the QtWidgets style work reliably first and then try to make it look as close to QtQuick side as possible.

My todo list is pretty much following:

  • Fix as many bugs as I can before 6.8 release
  • Figure out a layouting system for the QStyle that is robust
    • Even if it can't do all the tricks QtQuick can
  • Make sure the QStyle is backwards compatible with as many applications as possible

So, more work. A lot of work.

But at least we can now properly start that work, which is what this first release is about. Getting the tedium out of the way, so the interesting parts can begin.

And boy how much tedium that was. I would never do it again, but honestly.. It was fun at times. Super interesting to figure out. Like a very tough puzzle game. I'm happy with what I've achieved here, even if it's not perfect yet. And I hope all this work is useful for you too, dear users. I really want to see the crazy things you all will come up with.

Thanks for reading!

ps. Again sorry if this reads all over the place, I just needed to get it out of my system. I don't like writing drafts much, so I just write a braindump and go.

Thursday, 27 August 2026

As you might already know, Transitous is a project that runs a public transport routing service that aims to work wold-wide. To make Transitous results more useful, there needs to be a simple way to book the individual sections of a multi-modal route. It is important to mention that Transitous can not legally sell tickets itself, and there are no plans to change that, so booking in this case means directing users to a ticket shop that can sell tickets for the route.

LTG Link route from Vilnius to Kaunas displaying a Tickets button

Ticketing Extension

Transitous is primarily based around the GTFS format for its transport schedules, although NeTEx is increasingly being used as well. The first step naturally was to implement reading ticketing information from the schedule files. Although ticketing is not a core part of GTFS, there is the Google Transit ticketing extension.

Its most important feature is specifying booking urls and a way to pass the stop ids, trip ids and times to the ticket shops. The extension also allows to define ids for stops and trips that the ticket shop can understand. This is important because often the ticket shop software is different from the piece of software that writes the GTFS files. These don’t necessarily have to agree on the identifier they use.

If each trip had it’s own booking deeplink, the size of the schedule would increase massively, as well as the size of the data we’d need to store on the Transitous servers. To solve this, the ticketing extension only stores the base url, and assembles the parameters for each deep link only if needed.

However, this requires a separate shop-specific server side step to convert the standardized parameters to something that the ticket shop understands.

My work

Itinerary screenshot showing bookable connections from Vilnius to Riga

Transitous is mostly just an instance of the MOTIS routing engine, so much of the work happened there.

This work has partially been funded by NLnet through the NGI0 Commons Fund with financial support from the European Commission’s Next Generation Internet programme.

Unfortunately that did not magically give us booking links everywhere. The ticketing extension does not (yet) play such a big role in the open-data / open-source GTFS ecosystem. However since Google Maps supports it, many feeds made for it already contain ticketing_deeplinks.txt. Maybe you can get your local transit operators to add support for it as well :)

To do my part in improving the situation, I added support for it in some of my own GTFS feeds and the library I use for creating them.

Since the problem of needing to translate the url parameters for the ticket shops comes up in every inofficial feed, I also wrote a generic server for doing the redirecting. Adding support for a new ticket shop there is very easy. Since I already host it, it also removes the burden of needing to run a server side component for each feed one publishes.

You can see the results on Transitous: Route from Nikšić to Podgorica.

It also already works in KDE Itinerary.

Adding Ticketing

Adding ticketing to your own feeds is fortunately quite straightforward in many cases. These examples are based on my gtfs-generator rust crate, but it would be very similar in other language ecosystems.

Assuming there is one shop for all trips in the feed, you only need to add one ticketing link:

generator
    .add_ticketing_deep_link(TicketingDeepLink {
        ticketing_deep_link_id: "tickets-zpcg".to_string(),
        web_url: Some("https://jbb.ghsq.de/ticket-redirect/zpcg/".to_string()),
        android_intent_url: Some("https://jbb.ghsq.de/ticket-redirect/zpcg/".to_string()),
        ios_universal_link_url: Some("https://jbb.ghsq.de/ticket-redirect/zpcg/".to_string()),
    }).unwrap();

If the IDs the ticket shop and the feed use are already the same, you already know the IDs and just need to copy them over:

generator.add_ticketing_identifier(TicketingIdentifier {
    ticketing_stop_id: stop.stop_id.to_string(),
    stop_id: stop.stop_id.to_string(),
    agency_id: "zpcg".to_string(),
})?;

Then all that’s left is editing the agency entry to reference the new ticketing link. For more complicated cases, you can also reference a different ticcketing link per route.

If the IDs don’t match, chances are this is still relatively easy. Often the ticket shops’ autocompletion allows to retrieve a full list of stops, ideally including coordinates as well. Then matching these to your stops is relatively straightforward.

If you import your feed into MOTIS with these changes, you should already get a clickable “Tickets”-button. To make it redirect somewhere useful, the redirect server needs to be tought how the url scheme of the ticket shop works by adding a little function like this:

func redirectZpcg(w http.ResponseWriter, r *http.Request, from []string, to []string, date []time.Time, trip []string, departure []time.Time, arrival []time.Time) {
	baseUrl, _ := url.Parse("https://www.tickets-zpcg.me/en/rezultati.php")
	q := baseUrl.Query()
	q.Set("from", from[0])
	q.Set("to", to[len(to)-1])
	q.Set("date", date[0].Format("2006-01-02"))
	baseUrl.RawQuery = q.Encode()

	http.Redirect(w, r, baseUrl.String(), http.StatusSeeOther)
}

The parameters are arrays, since in the ticket links allow to buy multiple tickets via one link. This feature might not be possible to support with every ticket shop.

Maybe this motivated you to add support for this in some new corner of the world :)

Svenska språket uppfinns.

“Hej! Här kommer en uppdatering av våra villkor! Du kan nu använda upp till två tusen ord i månaden med vår gratistjänst, sedan måste du uppgradera till Basic Plan för 129 kr/månaden. Ska du använda svenskan i jobbet kostar det som innan 1299 kr/månaden. Behöver du läsglasögon? Våra enbart godkända leverantörer finner du här. Vi påminner om att pensionärsutgåvan finns inte mer. Vi hörs!”

Wow. Vilken teknologi. Vilken innovation. Vi alla köper.

År 2026, och så har det varit ett tag, så är det så här uttrycksfrihet fungerar på nätet. Vill du skriva till någon som är på Facebook men du är inte? Går inte. Vill du ta del av samhällsaktörers meddelanden och debatt utan annonser och material från den vinstdrivande aktören X? Sorry. Vill du chatta med dina kompisar på SnapChat med en app som är designad på ett helt annat sätt? Det får du inte. Välja leverantör av din feed på TikTok? Nope. Och så vidare.

Grunden i Internet, så som e-post och webbsidor, som byggs upp av specifikationer och organisationer, var designad runt att vara öppen. Du kan välja e-postprogram, webbläsare och vem som helst kan skapa en webbsida. Syftet med dess design var att hålla Internet neutralt, utan så kallade proprietära teknologier och nedlåsning med vinstdrivande intressen. Detta bidrog till stor del till dess succé, och varför det är bra. (Och gammal teknologi, uttrycksfrihet och demokrati har också sina utmaningar.)

De lager och applikationer som vi alla använder i nuläget är långt i från det. Det hela kännetecknas av vad ekonomer kallar marknadssvikt: de sociala medier-apparna tjänar oss konsumenter dåligt.

De samhällsproblem så som psykisk ohälsa och en systemisk sänkning av vår förmåga är ett resultat av hur teknologin och juridiken ser ut. Vi vill digitalt kommunicera och ta del av media, men kan i nuläget inte välja hur eller faktiskt vilket innehåll. Att hålla vinstdrivande aktörer samhällsmässigt ansvariga fungerar inte, men de respekterar marknadens spelregler. Ändra dem.

Så här finns det utrymme för innovation. Dra ihop jurister, samhällsvetare, teknologer och uppfinn de moment i form av teknologi (tänk API:er, referensimplementationer, specifikationer), lämplig juridik och de (supranationella) samarbeten som behövs för att göra den korrektion som är nödvändig. Teknisk separation mellan den app som visar och konton med material? Obligatoriska standarder? En EU-motsvarighet till Finansinspektionen? Här är några utmaningar med det: dåligt betalt, folk fattar inte riktigt poängen, och klurigt.

Kanske det är viktigt nog. Vad är första steg?

Last week, I went to FOSSY 2026 to participate in Camp KDE!