Skip to content

Friday, 10 April 2026

Introduction

Another year, another successful Season Of KDE for 20 contributors! This article has been co-written with the input from all contributors.

Lokalize

During Season of KDE 2026, Tanish Kumar worked on cleaning up the UI in Lokalize, KDE’s translation tool. The main task was fixing an annoying bug where the menu bar kept jumping around whenever you switched tabs, which was solved by giving the menus a stable “skeleton” in the KXMLGUI .rc files. Along the way, a bunch of “ghost actions” were discovered - menu entries that existed only in XML - and actually implemented the missing ones like Cut, Copy, Paste, Alternate Translation, Save All, Revert All, and Close All. He also built a Bookmark Manager dialog so translators can see all their bookmarks in one place.

Lokalize menu bar is stable now, no more menus jumping when changing tabs

Navya Sai Sadu and Kumud Sagar fixed navigation inconsistencies in the Editor Tab where shortcuts like “Approve and Go Next” failed to respect active filters and custom ordering in the Translation Units view. They ensured consistent behavior across all related shortcuts, including Next Ready, Next Non-Empty, and Next Bookmark. They unified the traversal logic so navigation always follows the filtered and ordered entries and users of Lokalize can now navigate through Translation Units using the keyboard shortcuts or the options in Go menu properly..

Lokalize translation units view improvements

Additionally, Kumud identified Lokalize’s on-disk file tracking mechanism and began improving its handling of external file updates.

Pop up when opened file in Lokalize is modified by another program

Jaimukund Bhan fixed foundational issues with the Glossary file, ensuring it could be properly loaded, saved, and autosaved, and cleaned up the codebase by removing an obsolete Restore function that no longer made sense once autosaving was in place. Several UI bugs were resolved, including the editor failing to clear when all terms were deleted and incorrect pre-selection behavior when the app started on the Glossary tab. In the second half, Jaimukund improved the manual term addition workflow by replacing silent blank entry creation with a proper dialog prompt, preventing accidental accumulation of empty entries. He also fixed a broken keyboard shortcut for switching to the previously active tab by replacing an index-based tracking variable with a widget pointer, which remains valid even as tab positions change.

Window to add a new word in glossary

Aditya Sarna made a full Figma redesign for the Glossary tab, which was referenced in several places to implement comprehensive UI and UX improvements. The work involved close collaboration with translators to understand user pain points and iterating on designs based on feedback from the design group. It included replacing button text with icons and adding tooltips to the Add and Delete buttons to clarify their purpose. This was followed by designing a new delete functionality, which introduced a cross button for each entry to make deletion more intuitive. Several additional UI changes were implemented, including shifting elements and improving the overall structure and layout of the Glossary tab. Furthermore, the workflow for adding new terms was refined by moving note text into the dialogue box and enhancing its layout, resulting in a cleaner, more intuitive and user-friendly interface.

Figma redesign for Glossary tab

Varun Sajith Dass worked on improving the proofing capabilities of Lokalize and implemented a reactive character consistency check that alerts translators in real-time when special characters are mismatched between the source and target strings. This involved debugging Qt UI signals, resolving macOS build issues with KIO workers, and creating a persistent status bar warning system to enhance the overall translation workflow.

Testing the reactive consistency checker in Lokalize. In the highlighted translation unit (Row 11), a special character present in the source string (the colon in 'Origin: %1') is intentionally omitted from the active target translation ('Herkunft %1') to evaluate the mismatch detection logic

Vishesh Srivastava worked on adding Appium-based UI testing to KDE’s Lokalize. Vishesh started with a small bug fix and unit test to familiarize with the codebase and then built a complete Appium test from scratch, including basic tests and a full end-to-end workflow. Another thing done was adding accessibility ids in the UI so Appium could interact with the editor. The tests were integrated into the CMake system, ensured they ran independently of the user, and can run with kde-builder tests with a flag. By the end, Vishesh had developed a functional UI testing framework for Lokalize, along with documentation to help future contributors.

Workflow test running using appium in Lokalize

KDE mentorship website

Advaith Sathish Kumar project was transforming mentorship.kde.org into a proper onboarding system for new KDE contributors. On the homepage, the hero section was redesigned, placeholder routing with experience based navigation was replaced, social media links were added, and the news cards to include author, date, and tags were also redesigned. For the /mentees page, I added past mentee details, implemented pagination, and added client-side filtering by year, program, and technology.

Addition of the previous mentees details

Aryan's project was to make mentorship.kde.org better so that new contributors who want to work with the KDE ecosystem have a better onboarding experience. As part of this effort, a new "/programs" page was added. It gives a structured overview of the main KDE mentorship programs and links to help newcomers find their way around the opportunities more easily. He also changed the card template to better organize the repository, making it more structured, easier to maintain. Aryan also filled the /resources page with more useful resources for new contributors.

Addition of the programs page to mentorship website

Documentation website

Mohit Mishra worked on decoupling the bundled dblatex fork from the docs-kde-org repository and fixing PDF generation for Chinese, Japanese and Korean (CJK) languages for KDE documentation. This involved switching the TeX engine to XeTeX from pdfTeX and then re-integrating the KDE styles. The outputs are now nearly identical, with CJK languages rendering correctly as well. There is still work in process to ensure there are no regressions and we can officially switch to this generation.

CJK pdf rendered with XeTex

Scripty

Aviral Singh and Keshav Nanda worked on fixing KDE's translation tools so translators can easily locate where text belongs in the code. Keshav corrected the underlying logic to make sure these paths are always accurate, and Aviral built an automated testing system to validate the fix across KDE projects.

Marknote

Siddharth Chopra worked on Marknote to add source mode for notes. The Source Mode essentially allows users to bypass the rich-text WYSIWYG interface and directly edit the raw markdown. While working on this feature, Siddharth also made a major refactoring of the codebase (on both the QML and C++ sides). Spell checking using Sonnet was also added, among other small fixes and improvements.

KDE Eco

Hrishikesh Gohain worked on setting up KEcoLab's measurement environment with Wayland on Fedora 43 KDE Plasma Desktop. He ported the Okular measurement scripts from the X11-based xdotool to ydotool and kdotool, which work on both X11 and Wayland. His contributions can be found in this merge request. The original project plan had included measuring the KDE Plasma desktop environment itself. However, porting the Okular scripts to Wayland in the new lab setup turned out to be more complex than expected. Moreover, measuring a desktop environment may need some infrastructure changes to the KEcoLab setup. Hrishikesh is currently working towards it and will continue after SoK26 is over.

Measurement script for Okular

Automate Promo Data Collection

Chuyen Nguyen wrote automation scripts and created environments for them to perform some of the KDE promotional team's insight data collection tasks. The first script collects KDE's X, Bluesky, Mastodon, and Threads accounts' follower and post counts using a mix of API requests and web scraping methods alongside a local Nitter instance. The second script scrapes the KDE subreddit's Reddit Insights page for weekly metrics on page visits, unique visitors and its total member count and includes a Docker image that allows for headless execution. The final script collects articles related to KDE using Google Alerts emails and performs sentiment analysis on them using a locally run large-language model. The figure below shows output from the follower and post count scraper, Reddit Insights page scraper, and Google Alerts evaluator respectively.

Terminal output of the different results of the scripts

Plasma Setup

Onat Ribar worked on bringing Plasma Setup, KDE's first-run setup wizard, to Plasma Mobile. Plasma Setup was built with desktop screens in mind, and running it on a phone showed overall accessibility issues including but not limited to overlapping components, content clipping on short window sizes, session buttons that remained tappable beneath wizard pages, and a timezone selector built around an interactive map that was nearly unusable on a small touchscreen. Onat worked through these systematically across the wizard's QML UI, resulting in an adaptive experience across screen sizes and input methods without affecting the desktop UX. Two MRs have been reviewed, merged, and are now part of the upstream codebase in repositories plasma-setup and plasma-workspace.

Setup Wizard for Plasma Setup

Falkon

Sairam developed a XMPP extension that adds a chat client directly into the KDE Falkon browser's sidebar. Written in Python using Slixmpp, the project lets users message each other and run interactive WebXDC apps right inside their chat window. It supports modern XMPP features like Message Carbons (XEP-0280) for device syncing, Message Corrections (XEP-0308) for edits, Emoji Reactions (XEP-0444), and HTTP File Uploads (XEP-0363). This setup turns Falkon into a communication tool without even leaving the browser.

XMPP Support in Falkon through WebXDC

J Shiva Shankar added XMPP bookmark syncing to the Falkon browser. The basic setup is working, so whenever you add or update a bookmark, it successfully syncs across your devices. Deleting bookmarks still has a few bugs right now, but they have been documented. He plans to keep contributing after SoK to squash these bugs and get the feature completely polished.

Bookmarks synchronization in Falkon

Mankala Engine

Sayandeep Dutta helped in redesigning the MankalaNextGen GUI with Kirigami and added designs fixing the Main UI and the Game with game boards and shells. He also added music with Qt to Mankala and made translations in Tamil and Hindi. Made assets for the game variants using Krita in their traditional designs and motifs. Started with the review process of MankalaNextGen with the CI build.

Bohnenspiel Board

Pavan Kumar enhanced MankalaEngine by adding an opening book and investigated performance of multithreaded alpha-beta search using OpenMP, Pthreads and Taskflow. In addition, he enhanced MankalaNextGen by creating visual assets for game boards and seeds and also created logos for MankalaEngine and MankalaNextGen.

New MankalaEngine logo

Thursday, 9 April 2026

Very technical post, feel free to ignore if you're not working on KDE stuff.

Since I'm on KDE Linux, I use flatpak apps for pretty much everything, such as Kontact suite. I wanted to test out how my Breeze changes would look like in KMail and other apps, but I didn't want to build the whole PIM stack.

Here's how I tested it by building the flatpak-kde-runtime in CI, downloading the built files and using it as a repository for testing any changes to org.kde.Platform locally.

  1. First make changes to the flatpak-kde-runtime, such as this here: https://invent.kde.org/packaging/flatpak-kde-runtime/-/commits/work%2Fakselmo%2Ftest-breeze
  2. Run the CI
  3. Check the pipeline ID for build-runtime-amd64
    • Click the green checkmark, its something like #1210828
  4. Download the artifact from here: https://storage.kde.org/ci-artifacts/packaging/flatpak-kde-runtime/p/PIPELINE_ID_HERE/repository-x86_64.tar.gz
  5. Extract the tar into some folder after downloading
  6. Add it as a repository: flatpak remote-add --no-gpg-verify kde-platform-testing ./repo-x86_64
  7. Uninstall the current platform: flatpak uninstall org.kde.Platform --force-remove
    • The force-remove makes sure we do not install any apps, just the platform
  8. Run flatpak install org.kde.Platform
  9. Select the kde-platform-testing as the repo to install from
  10. Done!

Now any app that uses the version of platform (6.10 in my example) will utilize your custom built one.

Akademy 2026: Registration

Akademy 2026 will be a hybrid event held simultaneously in Graz, Austria, and Online.

Hundreds of participants from the global KDE community, the wider free and open source software community, local organisations and software companies will gather at this year's Akademy 2026 conference. The event will take place in Graz and Online from Saturday, 19 September to Thursday, 24 September.

KDE developers, artists, designers, translators, users, writers, sponsors and supporters worldwide will meet face-to-face to discuss key technology issues, explore new ideas and strengthen KDE's innovative and dynamic culture.

Register now and join us for engaging talks, workshops, BoFs and coding sessions. Collaborate with your fellow KDE contributors to fix bugs, pioneer new features and immerse yourself in the world of open source.

For more information about the conference, visit the Akademy 2026 website.

The Skrooge Team announces the release 26.4.0 version of its popular Personal Finances Manager based on KDE Frameworks.

Changelog

  • Correction bug 515099: Missing secondary currency value in Accounts totals
  • Correction bug 514649: Fix initial layout when splash screen is not displayed
  • Correction bug 514649: Double click issue on table when there is no selection
  • Correction bug 438967: Labels in Skrooge Report axis and Legend tend to illegible
  • Correction bug 517475: Alarms triggering even when conditions not met
  • Correction bug 515186: Import should remember the directory used last when restarted
  • Correction bug 430245: summaries display truncated after searching in Operations grouped by Category
  • Correction bug 518461: charts missing in responsive monthly report
  • Correction: Better filtering in categories page
  • Correction: Fix various error in flatpak mode (import, download sources, ...)

Wednesday, 8 April 2026

Krita 5.3.1.1 is an Android-only fix for 5.3.1. It is exactly the same as Krita 5.3.1, but with two fixes:

  • fixed a crash on Android 12 and older when trying to access any text controls
  • fix stylus workarounds for Xiaomi and OnePlus to work properly

Check out the release notes for a full overview of all the new features in Krita 5.3 and 6.0.

Note: this release is only relevant for Android, so only Android APK's and source archives are available. You only need the source archive when building for Android yourself.

⚠️ Warning

One again, we consider Krita 5.3.1 suitable for productive work; 6.0.1 is, because of the many changes from Qt5 to Qt6 more experimental.

5.3.1.1 Download

Android

Krita on Android is still beta; and is meant to run on chromebooks and tablets only.

Source code

ⓘ Note

Note for distributions: if you package both PyQt5 and PyQt6, you will want to patch our source code with this patch: Disallow importing conflicting version of PyQt

md5sum

For all downloads, visit https://download.kde.org/stable/krita/5.3.1/ and click on "Details" to get the hashes.

Key

The the source tarballs are signed. You can retrieve the public key here. The signatures are here (filenames ending in .sig).

Tuesday, 7 April 2026

Explore how SWHID is applied in real-world scenarios to improve SBOMs, support Cyber Resilience Act compliance, and enable software traceability. Discover practical use cases across telecom and automotive industries, based on insights from recent industry talks.

The problem

At the first start of an application, user can be a bit confused in front of all of these features, buttons and data. In response to that, we often have a short presentation of each element on the screen. This also presents a typical workflow with the application.

First, You need to create a project or document. Then, define the name, the type… Then add content using this or that.

This feature is often called UI walk through, or UI tour.

UI Walker

I made this library to provide an easy way to do a walkthrough in any QML application.

Include Ui Walker to your project

target_link_libraries(MyProject
PRIVATE
    Qt6::Core
    Qt6::Quick
    WalkerComponent # add UIWalker
)

Using cmake it is really easy. You can define the library to be a git submodule and then

Prepare you qml code

The whole concept is based on attached property. To highlight a item, you must define two properties:

  • WalkerItem.description: the text that will be displayed when this element is highlighted
  • WalkerItem.weight: Numeric value to define the order (ascending order).
ToolButton {
    WalkerItem.description: qsTr("Description of the element")
    WalkerItem.weight: 104
}

Add the UI walker

Currently, you have to add one item. It should have the size of the whole window. This item provides several properties in order to help you manage the output.

Properties:

namedescriptiontype
countTotal number of highlighted Itemint
currentIndex of the current highlighted itemint
currentDescDescription of the current itemQString
dimColorColor which hides the rest of the applicationQColor
dimOpacityOpacity of the dimqreal
availableRectBiggest Rectangle (where text can be displayed).QRectF
borderRectRect of the current highlighted itemQRectF
intervalDefine the time interval on each highlighted itemint
activeTrue when the Walker is displayedbool

Here is an example:

 WalkerItem {
    id: walker
    anchors.fill: parent
    visible: false
    dimOpacity: 0.8

    onActiveChanged: {
        //walker.active
    }
        
    Label {
        id: label

        
        text: walker.currentDesc // text from walker
        x: walker.availableRect.x // calculated position
        y: walker.availableRect.y // calculated position
        width: walker.availableRect.width // calculated position
        height: walker.availableRect.height // calculated position
    }
    
    Rectangle {
        x: walker.borderRect.x-2
        y: walker.borderRect.y-2
        width: walker.borderRect.width+4
        height: walker.borderRect.height+4
        border.color: "red"
        color: "transparent"
        radius: 10
        border.width: 4
    }

    ToolButton {
        icon.source: walker.current + 1 === walker.count ? "qrc:/finish.svg" : "qrc:/next.svg"
        
        onClicked:{
            if(walker.current +1 === walker.count)
                walker.skip()
            else
                walker.next()
        }   
    }
}

React on Highlight event

Highlighted items get notified through two signals: enter and exit. Defining signal handlers allow you to react. So you can show the full workflow to add new data.

TextField {
    id: nameField
    // …
    WalkerItem.description: qsTr("Set macro name.")
    WalkerItem.weight: 30
    WalkerItem.onEnter: {
        nameField.text = qsTr("Skill Roll")
    }
}

Start it !

In order, to start the UI tour, you simply have to call the function: start() of the Item. Of course, it is up to you to trigger it automatically when it’s the first start of the application or if the user asked for the tour.

Here you have an example:

Component.onCompleted: {
    if(DiceMainController.uiTour === DiceMainController.UnDone) {
        walker.start()
    }
}

I have a CPP controller with property UiTour which gives the current status of the tour. Here, I call directly the walker function. But it may be safer to call a function to reset the state of the window.

The walker provides two important function next() and previous() to navigate. Basically on the walker, you can add buttons in the available Rect to manage the navigation.

Other option, you can define an interval in milliseconds which will call the next() function.

You have to make sure the item is visible while the walker highlight it. It could be tricky to make the path from the end to be beginning. In some case, it is easier to never use the previous function.

Finish it!

Calling the function skip(), close the walker. Then the application is displayed normally. It can be called at any time.

Cheat code

Functiondescription
start()The walker becomes visible, and the first item is highligthed
next()Highlight the next item, trigger appropriated signals
previous()Highlight the previous item, trigger appropriated signals
skip()Hide the walker

How it works ?

The attached properties

In order to harvest all data from the QML, I had to define attached property.

This is the definition of QObject which will be attached, each time a QML item has defined any Walker property.

class WalkerAttachedType : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged FINAL)
    Q_PROPERTY(int weight READ weight WRITE setWeight NOTIFY weightChanged FINAL)
    QML_ANONYMOUS
public:
    explicit WalkerAttachedType(QObject* parent= nullptr);
    //…
signals:
    void enter();
    void exit();
    //…
};

In the WalkerItem.h, I have to create this static function.

    // …
    Q_OBJECT
    QML_ATTACHED(WalkerAttachedType)
    // …
    static WalkerAttachedType* qmlAttachedProperties(QObject* object)
    {
        QQuickItem* item= qobject_cast<QQuickItem*>(object);
        if(!item)
            qDebug() << "Walker must be attached to an Item";
        s_items.append(item);
        return new WalkerAttachedType(object);
    }

QSceneGraph and Nodes

WalkreItem defines a QML item, written in cpp to be light-weighted. I used QSGNode to draw it on screen. The item code manages the logic of the walkthrough and the update of the geometry.

To make it short, the SceneGraph is the rendering engine of QML. QSGNode defines an API to communicate with it directly.

First, I create the QML item in cpp, using QSGNode to be rendered.

//walkeritem.h
class WalkerItem : public QQuickItem
{
    Q_OBJECT
    QML_ATTACHED(WalkerAttachedType)
    QML_ELEMENT
    Q_PROPERTY(QString currentDesc READ currentDesc NOTIFY currentChanged FINAL)
    Q_PROPERTY(QColor dimColor READ dimColor WRITE setDimColor NOTIFY dimColorChanged FINAL)
    Q_PROPERTY(qreal dimOpacity READ dimOpacity WRITE setDimOpacity NOTIFY dimOpacityChanged FINAL)
    Q_PROPERTY(QRectF availableRect READ availableRect NOTIFY availableRectChanged FINAL)
    Q_PROPERTY(QRectF borderRect READ borderRect NOTIFY borderRectChanged FINAL)
    Q_PROPERTY(int interval READ interval WRITE setInterval NOTIFY intervalChanged FINAL)
    Q_PROPERTY(bool active READ active NOTIFY activeChanged FINAL)
public:
    WalkerItem();
    
    // accessors, signals, slots…

protected:
    QSGNode* updatePaintNode(QSGNode*, UpdatePaintNodeData*) override;// update scenegraph
};



//walkeritem.cpp
WalkerItem::WalkerItem()// in the constructor
{
    setFlag(QQuickItem::ItemHasContents);// must be called
    connect(child, &QQuickItem::widthChanged, this, &WalkerItem::updateComputation);
    connect(child, &QQuickItem::heightChanged, this, &WalkerItem::updateComputation);
}

void WalkerItem::updateComputation()
{
    // compute geometry and list any changes that must be sync with the SceneGraph.
    m_change|= WalkerItem::ChangeType::GeometryChanged;
    update();// call to paint the item
}

QSGNode* WalkerItem::updatePaintNode(QSGNode* node, UpdatePaintNodeData*)
{
    auto wNode= static_cast<WalkerNode*>(node);
    if(!wNode)
    {
        wNode= new WalkerNode();//first time
    }

    if(m_change & WalkerItem::ChangeType::ColorChanged)
        wNode->updateColor(m_dimColor);
    if(m_change & WalkerItem::ChangeType::GeometryChanged)
        wNode->update(boundingRect(), m_targetRect);
    if(m_change & WalkerItem::ChangeType::OpacityChanged)
        wNode->updateOpacity(m_dimOpacity);

    m_change= WalkerItem::ChangeType::NoChanges;
    return wNode;
}

We have here an item with a geometry like any other item (x,y,width, height), we also have a dimColor and dimOpacity. Any time one of these properties change. I have to sync with the QSceneGraph to update either the geometry, the dimColor or the dimOpacity. Each time, one property changes, I stored the type of change in the m_change member and I call update().

The render engine will call my item with the QSGNode reprenting it on the SceneGraph side. Then I can call function on my SGNode. When sync is finished I reset the change to NoChange and return the node.

The updatePaintNode can be called with a null node. In this case, you have to create it. It will be the case, the first time. And it could happen later in some cases for optimalization reason.

Now, let see the code of the QSGNode. You have to see the QSGNode as the root item of a tree. Where each node is in charge of representing one aspect of the item: its geometry, its color and its opacity.

// header
class WalkerNode : public QSGNode
{
public:
    WalkerNode();
    virtual ~WalkerNode();
    void update(const QRectF& outRect, const QRectF& inRect);
    void updateColor(const QColor& dim);
    void updateOpacity(qreal opacity);

private:
    QSGOpacityNode m_opacity;
    QSGFlatColorMaterial m_dimMat;
    QSGGeometryNode m_dim;
};

In the constructor, I create each node, and then I define the hierarchy.

WalkerNode::WalkerNode()
{
    auto dimGeo= new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 0);
    dimGeo->setDrawingMode(QSGGeometry::DrawTriangles);
    dimGeo->allocate(triangleCount * 3);

    m_dim.setGeometry(dimGeo);
    m_dim.setMaterial(&m_dimMat);
    m_dimMat.setColor(Qt::black);

    m_opacity.setOpacity(0.6);

    m_opacity.appendChildNode(&m_dim);
    appendChildNode(&m_opacity);

    markDirty(QSGNode::DirtyMaterial | QSGNode::DirtyGeometry | QSGNode::DirtyOpacity);
}

Here the final tree:

Define or Update the geometry

void WalkerNode::update(const QRectF& out, const QRectF& in)
{
    // out is the geometry of the window
    // in is the geometry of the highlighted item
    const auto a= out.topLeft();
    const auto b= in.topLeft();
    const auto c= in.topRight();
    const auto d= out.topRight();
    const auto e= in.bottomRight();
    const auto f= out.bottomRight();
    const auto g= in.bottomLeft();
    const auto h= out.bottomLeft();

    {
        auto gem= m_dim.geometry();
        auto vertices= gem->vertexDataAsPoint2D();
        QList<std::array<QPointF, 3>> triangles{{a, b, d}, {b, d, c}, {d, c, f}, {c, f, e},
                                                {f, e, h}, {e, g, h}, {h, g, a}, {g, a, b}};
        int i= 0;
        for(auto t : triangles)
        {
            vertices[i + 0].set(t[0].x(), t[0].y());
            vertices[i + 1].set(t[1].x(), t[1].y());
            vertices[i + 2].set(t[2].x(), t[2].y());
            i+= 3;
        }

        m_dim.markDirty(QSGNode::DirtyGeometry | QSGNode::DirtyMaterial);
    }

    markDirty(QSGNode::DirtyGeometry | QSGNode::DirtyMaterial);
}

We split the surface we have to cover in triangles.

Todo

  1. Animations: Smooth animation while transiting from one item to another.
  2. Test on bigger apps
  3. Find a logic to allow previous
  4. Use shader effect to make it better.
  5. Other…

Conclusion:

UiWalker is already in production. It works like a charm. I hope to use it elsewhere. Then, I will add some new features. Contributions and comments are welcomed.

Hope you find this article interesting.

Sunday, 5 April 2026

The last post regarding work on fixing Oxygen was a month and a half ago. With all that's happened in between, it feels like so much more time has actually passed. With this post, I'd like to do a sort of mid-term update summing up all of the improvements done so far. These improvements are...... Continue Reading →

For the next digiKam releases, the digiKam team needs photographs for digiKam and Showfoto splash-screens. Proposing photo samples as splash-screens is a simple way for users to contribute to digiKam project. The pictures must be correctly exposed/composed, and the subject must be chosen from a real photographer’s inspiration. Note that we will add a horizontal frame to the bottom of the image as in the current splashes.