Sunday, 22 June 2025
A very long awaited milestone has been reached: Today the KMyMoney team announces the availability of the latest stable version of its Personal Finance Manager together with its companion library Alkimia..
Since the last stable release almost 3 years ago, the developers made 3440 changes to the main code base and 800+ changes to the Alkimia library.
Here’s an overview of some major functionality changes and improvements made among all the little bug fixes along the way (with more details on a separate page):
Multi account ledger view
KMyMoney now allows to open the ledger of multiple accounts in tabs side by side in the ledger view.
New and improved transaction editors
The transaction editors have completely rewritten. They now open a widget directly in the ledger area and there is no distinction between form based and register based method anymore. The sometimes confusing tabs showing Deposit/Transfer/Withdrawal have been removed and the amount entry now provides two mutually exclusive widgets for debit and credit. These changes also found their way into the split editor.
And for transfers you now simply type/select the account name in the category widget.
Customize tab order for transaction editors
Another feature of the transaction entry is to customize the tab order for data entry. Pressing Ctrl+Alt+T opens the tab order editor and the user can select the order of the widgets that are visited when pressing the TAB key.
Open categories in ledger view
With the new version, it is now possible to open categories in the ledger and enter transactions. This has been a long standing user request.
Customize order of columns in tabular views via drag and drop
The order of the columns of e.g. the ledger, accounts or categories view can now be modified by the user by simply dragging the header column to its new location.
Move accounts in hierarchy via drag and drop
Moving accounts in the hierarchy is now possible using drag and drop.
Load passwords from gpg encrypted password store
Passwords for e.g. the KBanking backend can now be loaded from the standard Unix password store pass with a simple mouse click. Pass uses strong GPG based encryption to store its information. A Qt based GUI frontend for pass is also available.
Improved handling of tags
The support for tags has been overhauled. Especially the reporting section for tags received many improvements.
Link documents to transactions
KMyMoney now provides a feature to link documents stored in the filesystem to transactions. This can be automated to support recurring transactions (e.g. your phone bill) by simple configuration using regular expressions per payee.
Online exchange rate download available for other finance apps
Online currency exchange rate and stock price download has been moved over to the Alkimia library and then re-integrated into KMyMoney. This makes it available for other applications by simply linking to Alkimia.
Updated handbook
The KMyMoney handbook has received many changes to reflect the new functionality.
A big thank you goes out to those who supported us by reporting problems and helping to identify their root cause. In case you have a question about the usage of some new features or even old ones, please post your question on the KDE user forum. If you are sure you found real problem or want to ask for a new feature, please do so on our bugtracker.
Tackling the Migration Agent
For week three, I finished resolving the configuration window issue for the EteSync resource by hiding the default configuration window and programmatically linking the wizard’s “Accepted” and “Rejected” states to the configuration window’s accept() and reject() methods. This ensured that the wizard cleanly replaced the built-in dialog without leaving a “zombie” window behind. I’ve submitted a merge request for these changes so it can be reviewed and integrated upstream.
With that resolved, I moved on to a new and intriguing component: the PIM Migration Agent. This agent is responsible for managing data migrations between different Akonadi versions or formats — a critical part of ensuring smooth transitions when updating KDE PIM components.
And like the other agents and resources, it was time for it to shed its QtWidgets dependency.
Decoupling the UI
Following the established pattern, I began by:
Creating a dedicated UI plugin for the migration agent’s configuration dialog
Removing the old
configure()method from the agent’s core logicUpdating the relevant
CMakeLists.txtfiles to support the plugin and cleanly separate UI code from the core agent
However, while this transition was relatively smooth, the plugin-agent communication needed more work to function correctly in this new structure.
Creating a D-Bus Interface for Plugin-Agent Communication
To enable proper communication between the configuration plugin and the migration agent, I created a new D-Bus interface:org.kde.Akonadi.MigrationAgent
This interface allows the plugin to:
Receive status or configuration information from the agent
Send information back if needed (e.g., configuration changes)
To support this, I also:
Modified the
CMakeLists.txtto include the interface and generate the corresponding D-Bus adaptorUpdated both the
migrationagentandmigrationstatuswidgetfiles to use the new D-Bus interface for interaction
This ensures the plugin can communicate cleanly with the agent without relying on any hard-coded QtWidgets calls or tightly coupled logic.
The KUiServerJobTracker Problem (Still Pending)
While working on the migration agent, I encountered a significant QtWidget dependency:KUiServerJobTracker, which handles job progress display by showing dialogs and notifications automatically.
Removing it is straightforward — but it leaves a gap:
How should the migration agent report progress to the user once
KUiServerJobTrackeris gone?
I’m currently exploring options for replacing it, possibly using a D-Bus-based mechanism where the agent broadcasts progress updates and a separate component (e.g., the plugin or a tray app) displays them. This would decouple the presentation layer from the agent’s logic, but I haven’t yet finalized the design.
What’s Next?
My immediate priority is to test the new plugin and the communication logic to ensure everything works correctly. In parallel, I’ll continue thinking through a robust replacement for KUiServerJobTracker, aiming for a modular, widget-free solution.
This week introduced new architectural challenges, but also laid the groundwork for cleaner, more maintainable agents. I’m excited to keep building on this momentum next week!
Saturday, 21 June 2025
It took a year for me to actually make a release, but KTimeTracker 6.0.0 is now out!
Major changes
The major thing about it is that KTimeTracker has been ported to Qt6. For end users this means up-to-date Linux distributions that had orphaned KTimeTracker will get the package back once a package maintainer steps up.
KTimeTracker has long had a (currently) X11-exclusive feature where it detects the virtual desktop you’re in and uses that to start/stop tracking a task. This does not work on Wayland and Windows, and now it won’t show up on either platform so you don’t attempt to use something that doesn’t work!
Wednesday, 18 June 2025
Tuesday, 17 June 2025

This project began as a casual college game I developed in my second year, using Pygame. The idea was simple. You’re driving a car, and your job is to survive enemy attacks, collect energy to stay alive, and shoot down as many opponents as you can. The more you destroy, the higher your score.
The core gameplay loop was designed in Pygame and includes:
- A player car that moves left and right.
- Opponent cars that spawn and rush toward the player.
- Energy pickups that keep your car alive.
- Bullets using which you take down enemy cars.
Each component is managed by its respective class: MyCar, Opponent, Fire, and Explosion.
The original version used keyboard input for movement and shooting. The objective was to survive as long as possible while scoring points by destroying opponents.
While building the game, I found myself knee-deep in things I hadn’t anticipated—like why a car would randomly vanish mid-frame, or why every collision either did nothing or ended in total chaos. I spent hours tweaking bounding rectangles, trying to get explosions to appear in the right place, and making sure enemy cars didn’t spawn on top of each other. Most of my time went into figuring out how to reset things properly after a crash or making sure the game didn’t freeze when too many things happened at once. It was messy, confusing, and at times exhausting, but weirdly satisfying when everything finally came together.
Recently, I revisited this project with the idea of automating it. I wanted to see if the car could make its own decisions—to dodge, shoot, or stay put—all without human input. That’s where Monte Carlo Tree Search (MCTS) came in. Being a decision-making algorithm, it’s particularly useful in many strategic games when the search space is large and rewards are sparse or delayed—perfect for a chaotic survival game like mine.
Implementation Details
The first step was to abstract the game state into a simplified object. I created a GameState class in mcts_car_shooter.py that captures:
- My car’s
xposition. - Remaining energy and current score.
- Positions and energy levels of alive opponents.
- Fire coordinates (optional) and energy pickup position.
This allowed the MCTS algorithm to run without needing to interact with the actual rendering or physics code.
In the main game loop, every 5 frames, I pass the current game state to the MCTS engine:
if frame_counter % 5 == 0:
state = get_game_state_from_main(mycar, energy, score, list(opponent))
action = mcts_search(state, computation_time=0.05)
The result is one of four possible actions: "left", "right", "shoot", or "none".
Once the decision is made, the game responds accordingly:
if action == "left":
mycar.move("left")
elif action == "right":
mycar.move("right")
elif action == "shoot":
fire_sound.play()
So here’s what’s actually going on behind the scenes every time the AI makes a move. The MCTS algorithm starts by traversing the existing tree of game states to find the most promising node to explore—this is the selection step. Once it lands on that node, it simulates one new possible action from there, which is the expansion phase. From that new state, it plays out a few random steps of the game using a basic policy (like “shoot if you see enemies” or “don’t move if energy is low”)—this is the simulation part. And then finally, based on how well or badly that rollout went, it backpropagates the reward back up the tree so that decisions that led to good outcomes get reinforced and are more likely to be chosen in the future. Each loop tries to balance exploration (trying out new stuff) and exploitation (doing what’s already known to work), and this constant balance somehow ends up producing surprisingly smart behavior out of nothing but random simulations and reward math.
After integrating MCTS, the game now plays itself. The car intelligently avoids enemy fire, conserves energy, and shoots at the right moments. It’s not perfect—but it’s good enough to survive for a few minutes and rack up a decent score.
However, one limitation of the current setup is that the AI doesn’t retain any memory of past games—it starts from scratch every time the game restarts. The MCTS algorithm only simulates forward from the current state and doesn’t learn or adapt across episodes. So while it can make fairly smart decisions in the moment, it has no long-term strategy or evolving understanding of what works best over time. There’s no persistence of experience, which means it can’t build on previous runs to improve future performance. This makes it efficient for one-off decisions but not ideal for learning patterns or refining behavior over multiple plays.
Next, I’m planning to take things a bit further. I want to train a policy network on the trajectories generated by MCTS so the model can learn from past simulations and make better long-term decisions without needing to simulate every time. I’m also thinking of adding a simple GUI to visualize how the MCTS tree grows and changes in real time—because watching the AI think would honestly be super fun. And eventually, I’d like to give players the option to toggle between AI-controlled and manual play, so they can either sit back and watch the car do its thing or take control themselves. You can find the full implementation on my GitHub. Thanks for reading!

Back in my second year of college, I had just started exploring functional programming. I was picking up Haskell out of curiosity - it felt different, abstract, and honestly a bit intimidating at first. Around the same time, I was also diving into topics like context-free grammars, automata theory, parse trees, and the Chomsky hierarchy - all the foundational concepts that explain how programming languages are parsed, interpreted, and understood by machines.
Somewhere along the way, it hit me: what if I could build something with both? What could be more fun than writing an interpreter for an imperative programming language using a functional one? That idea stuck - and over the next few weeks, I set out to build a purely functional monadic interpreter in Haskell.
I designed the grammar for the language myself, mostly inspired by Python. I wanted it to support loops, conditionals, variable assignments, print statements, and basic arithmetic, boolean, and string operations. It even has a “++” operator for string concatenation. Writing the grammar rules involved figuring out how to model nested blocks, expressions with precedence, and side-effect-free evaluation. I built the entire thing using monadic parser combinators—no parser generators or external libraries, just Haskell’s type system and some stubbornness.
Here’s a rough look at the grammar that powers the interpreter:
Block
: { Part }
Part
: Statement Part
| IfStatement Part
| WhileLoop Part
| Comment String Part
| epsilon
Statement
: var = AllExpr;
| print( AllExpr );
AllExpr
: Sentences ++ AllExpr
| Sentences
Sentences
: string
| LogicExpr
IfStatement
: if ( LogicExpr ) Block else Block
WhileLoop
: while ( LogicExpr ) Block
LogicExpr
: BoolExpr && LogicExpr
| BoolExpr || LogicExpr
| BoolExpr
BoolExpr
: True
| False
| ArithBoolExpr
ArithBoolExpr
: Expr > Expr
| Expr < Expr
| Expr == Expr
| Expr != Expr
| Expr
Expr
: HiExpr + Expr
| HiExpr - Expr
| HiExpr
HiExpr
: SignExpr * HiExpr
| SignExpr / HiExpr
| SignExpr % HiExpr
| SignExpr
SignExpr
: int
| ( AllExpr )
| var
The interpreter parses the source code using this grammar, builds an abstract syntax tree, and evaluates it by simulating an environment. There’s no mutation—it just returns a new environment every time a variable is assigned or a block is executed.
Running it is simple enough. After compiling with GHC, it reads the program from stdin and prints the resulting variable bindings and any output generated by print() statements.
ghc -o interpreter interpreter.hs
./interpreter
Here’s a sample program to show how it works:
{
i = 5;
a = (4 < 3) || 6 != 7;
print(a);
# First While! #
while(i != 0 && a)
{
print(i);
i = i - 1;
}
}
Output : a True
i 0
print True 5 4 3 2 1
Once I had the interpreter working, I wanted to make it a bit more fun to interact with. So I built a small GUI in Python using tkinter. It’s nothing fancy—just a textbox to enter code, a button to run it, and an output area to display the result. When you click “Run,” the Python script sends the code to the Haskell interpreter and prints whatever comes back.
The entire thing—from parsing to evaluation—is written in a purely functional style. No mutable state, no IO hacks, no shortcuts. Just expressions flowing through types and functions. It’s probably not the fastest interpreter out there, but writing it did teach me a lot about how languages work under the hood.
Sunday, 15 June 2025
This is the release schedule the release team agreed on
https://community.kde.org/Schedules/KDE_Gear_25.08_Schedule
Dependency freeze is in around 2 weeks (July 3) and feature freeze one
after that. Get your stuff ready!
🎉 New Clazy Release: Stability Boost & New Checks!
We’re excited to roll out a new Clazy release packed with bug fixes, a new check, and improvements to existing checks. This release included 34 commits from 5 contributors.
🔍 New Features & Improvements
New Check:
readlock-detaching
Detects unsafe and likely unwanted detachment of member-containers while holding a read lock. For example, when calling.first()on the mutable member instead of.constFirst()Expanded Support for Detaching Checks
Additional methods now covered when checking for detaching temporary or member lists/maps. This includes reverse iterators on many Qt containers andkeyValueBegin/keyValueEndon QMap. All those methods haveconstcounterparts that allow you to avoid detaching.Internal Changes With this release, Clang 19 or later is a required dependency. All older versions needed compatibility logic and were not thouroughly tested on CI. In case you are on an older Version of a Debian based distro, consider using https://apt.llvm.org/ and compile Clazy from source ;)
🐞 Bug Fixes
install-event-filter: Fixed crash when no child exists at the given depth.
BUG: 464372fully-qualified-moc-types: Now properly evaluatesenumandenum classtypes.
BUG: 423780qstring-comparison-to-implicit-char: Fixed and edgecase where assumptions about function definition were fragile.
BUG: 502458fully-qualified-moc-types: Now evaluates complex signal expressions likestd::bitset<int(8)>without crashing. #28qvariant-template-instantiation: Crash fixed for certain template patterns when using pointer types.
Also, thanks to Christoph Grüninger, Johnny Jazeix, Marcel Schneider and Andrey Rodionov for contributing to this release!
From Refactor to Functioning Plugin
Hi again! Week two was all about turning last week’s refactored EteSync resource and newly separated configuration plugin into a fully working, stable component. While the initial plugin structure was in place, this week focused on making the pieces actually work together — and debugging some tricky issues that emerged during testing.
Removing QtWidgets Dependencies with KNotification
While testing, I discovered that the original EteSync resource code used QDialog and KMessageBox directly for showing error messages or status updates. These widget-based UI elements are too heavy for a background resource and conflict with the goal of keeping the resource lightweight and GUI-free.
To address this, I replaced them with a much cleaner approach: creating KNotification instances directly. This allows the resource to send system notifications (like “EteSync sync successful” or error messages) through the desktop’s notification system, without relying on any QtWidgets. As a result, the resource is now fully compatible with non-GUI environments and no longer needs to link against the QtWidgets library.
Refactoring Settings Management for Plugin Compatibility
Another major change this week involved how the resource handles its settings.
Previously, the configuration was implemented as a singleton, meaning both the resource and its configuration plugin were sharing a single instance of the settings object. This worked in the old, tightly-coupled model, but caused conflicts in the new plugin-based architecture.
To fix this, I updated the settings.kcfgc file to set singleton=false. This change allows the resource and the configuration plugin to maintain separate instances of the settings object, avoiding interference. I also updated both etesyncclientstate.cpp and etesyncresource.cpp to properly manage their respective configurations.
Solving the “Zombie Window” Issue
One final issue emerged after separating the UI: the configuration wizard now appears in a separate window from the main Akonadi configuration dialog. When the wizard is completed and closes, the original configuration window — now empty and disconnected — remains open.
Clicking buttons on this leftover window causes terminal errors, since it no longer communicates with a valid process. This results in a confusing and potentially buggy experience for users.
What’s Next?
My next task is to figure out a clean way to close the original parent window when the wizard completes, ensuring a smooth and error-free configuration flow. In addition to that, I’ll begin testing the full integration between the EteSync resource and its configuration plugin to ensure everything works correctly — from saving and applying settings to triggering synchronization. This will help verify that the decoupling is both functionally solid and user-friendly.





