Skip to content

Saturday, 17 August 2024

It's been more than three weeks since the midterm summary, and the project is now nearing completion.

Currently, all the original features of Blinken have been fully implemented in the QML version. The remaining tasks involve UI adjustments, testing, and fixing potential bugs.

Over the past few weeks, I’ve been working on the following:

Integrating Blinken's Logic

The game logic of Blinken is handled by the BlinkenGame class from the original Blinken. The original code design is quite good, with most of the game logic encapsulated in this one class. The separation between the logic and the UI rendering is well done, so all I needed to do was connect the signals from this class in QML.

As for the audio playback in Blinken, the original code used the Phonon library, which is also open-source but does not support Android. Therefore, I replaced it with the QtMultimedia library, which provides cross-platform audio playback functionality.

Android Build for KF6 Applications

Some features of Blinken rely on libraries provided by the KF6 framework, such as KF6I18n and KF6Config. When cross-compiling to the Android platform, it's necessary to use the aarch64-linux versions of these libraries. If these libraries are not available on your system, you will encounter the following errors during compilation:

ld.lld: error: /usr/lib64/libKF6XmlGui.so.6.4.0 is incompatible with aarch64linux ld.lld: error: /usr/lib64/libKF6ConfigWidgets.so.6.4.0 is incompatible with aarch64linux 
……

However, the package manager on my Fedora distribution does not provide these versions. Compiling and installing them one by one from source is too cumbersome. On the advice of the community, I used Craft to handle cross-compilation.

For reference, here is the Craft tutorial: Craft - KDE Community Wiki

Important note: If you encounter installation failures, make sure to clear all contents under craft-kde-android before trying again, as leftover files may cause the installation to fail.

When installing, choose the Arm64 target architecture. If there are remnants from a previous failed installation, it may prevent the option to select the ARM64 architecture.

If you encounter issues like "Permission denied," you’ll need to disable SELinux:

sudo apt-get install selinux-utils 
sudo setenforce 0

Additionally, note that in the virtual machine invent-registry.kde.org/sysadmin/ci-images/android-qt67 provided by the community, the Java version is outdated, preventing the use of Gradle 8.6. You can either manually update the Java version in the docker or use an older version of Gradle.

To use Craft for building applications, you need to write a script called a Blueprint, which describes the libraries your application depends on. These scripts are relatively easy to write, and you can quickly get started by following the community documentation: Craft/Blueprints - KDE Community Wiki.

Using KF6 Framework Libraries

Some of the libraries originally used by Blinken are compatible with the Android platform, while others are not. By referring to the API Documentation, you can check which libraries are supported on Android. In Blinken, the following libraries are Android-compatible:

  • CoreAddons
  • GuiAddons
  • I18n
  • XmlGui

I needed to use these libraries in the QML version of Blinken.

The KF6 framework provides a convenient internationalization API, and the usage in QML is almost the same as in QWidget, which allowed me to directly reuse Blinken’s original multi-language support, saving a lot of time.

KConfig is used in Blinken to store high score information and settings. For the high scores, I needed to extract the HighScoreManager class from the original HighScoreDialog file, make some modifications, and then create a new high score interface in QML that connects the signals and slots of HighScoreManager. For the settings functionality, it’s as simple as registering a KConfig singleton in QML :

`qmlRegisterSingletonInstance<blinkenSettings>("org.kde.blinken", 1, 0, "BlinkenSettings", blinkenSettings::self());

KF6XmlGui was used in the original Blinken to create the About Blinken Page, About KDE Page, and Handbook Page. Although this library is Android-compatible, it is based on QWidget, while the main interface of Blinken is built with QML. Bringing in QWidget just for these pages didn't seem like a good idea. Luckily, for the Android platform, kirigami-addons provides this functionality. By incorporating it, I also brought in Kirigami, which helps optimize the UI.

After adding new dependencies, it’s important to modify the .kde-ci.yml file to support CI/CD. For more information: Infrastructure/Continuous Integration System - KDE Community Wiki.

Thursday, 15 August 2024

This will be a guide on how to generate Python bindings for your C++ library using Shiboken. Shiboken is a tool specifically created to build PySide, so it supports Qt code perfectly fine.

The steps described here require at least KDE Frameworks 6.8. I’ll use KUnitConversion as example, because it’s a small library.

We’ll start adding the building instructions. This part is mostly boilerplate code as it’s the same for any library (except for the obvious thing of changing the library name):

 1set(bindings_library "KUnitConversion")
 2
 3set(wrapped_header ${CMAKE_SOURCE_DIR}/python/bindings.h)
 4set(typesystem_file ${CMAKE_SOURCE_DIR}/python/bindings.xml)
 5
 6set(generated_sources
 7    ${CMAKE_CURRENT_BINARY_DIR}/KUnitConversion/kunitconversion_module_wrapper.cpp
 8    ${CMAKE_CURRENT_BINARY_DIR}/KUnitConversion/kunitconversion_wrapper.cpp
 9    ${CMAKE_CURRENT_BINARY_DIR}/KUnitConversion/kunitconversion_converter_wrapper.cpp
10    ${CMAKE_CURRENT_BINARY_DIR}/KUnitConversion/kunitconversion_unit_wrapper.cpp
11    ${CMAKE_CURRENT_BINARY_DIR}/KUnitConversion/kunitconversion_unitcategory_wrapper.cpp
12    ${CMAKE_CURRENT_BINARY_DIR}/KUnitConversion/kunitconversion_updatejob_wrapper.cpp
13    ${CMAKE_CURRENT_BINARY_DIR}/KUnitConversion/kunitconversion_value_wrapper.cpp)
14
15ecm_generate_python_bindings(
16    PACKAGE_NAME ${bindings_library}
17    VERSION ${KF_VERSION}
18    WRAPPED_HEADER ${wrapped_header}
19    TYPESYSTEM ${typesystem_file}
20    GENERATED_SOURCES ${generated_sources}
21    DEPENDENCIES KF6::UnitConversion
22    QT_VERSION ${REQUIRED_QT_VERSION}
23    HOMEPAGE_URL "https://invent.kde.org/frameworks/kunitconversion"
24    ISSUES_URL "https://bugs.kde.org/describecomponents.cgi?product=frameworks-kunitconversion"
25    AUTHOR "The KDE Community"
26    README ../README.md
27)
28
29target_link_libraries(${bindings_library} PRIVATE KF6UnitConversion)
30install(TARGETS ${bindings_library} LIBRARY DESTINATION "${KDE_INSTALL_LIBDIR}/python-kf6")

Let’s see what each part does.

 1set(bindings_library "KUnitConversion")
 2
 3set(wrapped_header ${CMAKE_SOURCE_DIR}/python/bindings.h)
 4set(typesystem_file ${CMAKE_SOURCE_DIR}/python/bindings.xml)
 5
 6set(generated_sources
 7    ${CMAKE_CURRENT_BINARY_DIR}/KUnitConversion/kunitconversion_module_wrapper.cpp
 8    ${CMAKE_CURRENT_BINARY_DIR}/KUnitConversion/kunitconversion_wrapper.cpp
 9    ${CMAKE_CURRENT_BINARY_DIR}/KUnitConversion/kunitconversion_converter_wrapper.cpp
10    ${CMAKE_CURRENT_BINARY_DIR}/KUnitConversion/kunitconversion_unit_wrapper.cpp
11    ${CMAKE_CURRENT_BINARY_DIR}/KUnitConversion/kunitconversion_unitcategory_wrapper.cpp
12    ${CMAKE_CURRENT_BINARY_DIR}/KUnitConversion/kunitconversion_updatejob_wrapper.cpp
13    ${CMAKE_CURRENT_BINARY_DIR}/KUnitConversion/kunitconversion_value_wrapper.cpp)

The first line just defines the name of the Python library we’ll build later. Then we set the header file that includes all the necessary headers of the library. We’ll see that file later. The generated sources list is a bit more complicated, as you need to guess the names of the files generated by Shiboken. Fortunately, you can probably guess the pattern from the example above: the first two files are always the same (the name of the library + _module_wrapper or _wrapper) and the rest is the list of classes defined in your XML file (more about it later). The qt_libs variable just contains a list of the Qt modules that our library requires. You should list all of them, even if one depends on another, because otherwise Shiboken won’t be able to find the include directories.

15ecm_generate_python_bindings(
16    PACKAGE_NAME ${bindings_library}
17    VERSION ${KF_VERSION}
18    WRAPPED_HEADER ${wrapped_header}
19    TYPESYSTEM ${typesystem_file}
20    GENERATED_SOURCES ${generated_sources}
21    DEPENDENCIES KF6::UnitConversion
22    QT_VERSION ${REQUIRED_QT_VERSION}
23    HOMEPAGE_URL "https://invent.kde.org/frameworks/kunitconversion"
24    ISSUES_URL "https://bugs.kde.org/describecomponents.cgi?product=frameworks-kunitconversion"
25    AUTHOR "The KDE Community"
26    README ../README.md
27)

This is the magic part. The ecm_generate_python_bindings function takes care of running Shiboken with all the required arguments, building the Python library and a wheel file to publish it on the Python Package Index (pypi.org). It has the following arguments:

  • PACKAGE_NAME: Name of the Python library.
  • VERSION: Version of the resulting library.
  • WRAPPED_HEADER: The header file we talked about above.
  • TYPESYSTEM: XML file with the type system information.
  • GENERATED_SOURCES: The list of files that Shiboken will generate.
  • DEPENDENCIES: A list of libraries that the bindings require, typically the library we’re building the bindings of.
  • QT_VERSION: The minimum required Qt version.
  • HOMEPAGE_URL: A URL to the homepage of the project.
  • ISSUES_URL: A URL where users can report bugs.
  • AUTHOR: The author of the library.
  • README: The README file for the Python library.
29target_link_libraries(${bindings_library} PRIVATE KF6UnitConversion)
30install(TARGETS ${bindings_library} LIBRARY DESTINATION "${KDE_INSTALL_LIBDIR}/python-kf6")

The last part links the C++ library with the Python bindings and installs it. Now let’s take a look at the header file:

1#pragma once
2
3// Make "signals:", "slots:" visible as access specifiers
4#define QT_ANNOTATE_ACCESS_SPECIFIER(a) __attribute__((annotate(#a)))
5
6#include <KUnitConversion/Converter>
7#include <KUnitConversion/Unit>
8#include <KUnitConversion/UnitCategory>
9#include <KUnitConversion/Value>

Nothing exciting there, just the list of includes (and some Qt thing that I don’t understand).

The last file you need is the typesystem definition, where you tell Shiboken which things (classes, structs, enums, namespaces…) you want to include in your bindings and how it should interpret them. You can delete or rename functions, change the return type, modify the input parameters and many other things. You may want to take a look at the documentation because the list of posible options is very large.

 1<?xml version="1.0"?>
 2<typesystem package="KUnitConversion">
 3    <load-typesystem name="typesystem_core.xml" generate="no" />
 4
 5    <namespace-type name="KUnitConversion">
 6        <enum-type name="CategoryId" />
 7        <object-type name="Converter" />
 8        <object-type name="Unit" />
 9        <object-type name="UnitCategory" />
10        <enum-type name="UnitId" />
11        <object-type name="UpdateJob" />
12        <object-type name="Value" />
13    </namespace-type>
14</typesystem>

You need to load the typesystems of the Qt libraries that you are using so Shiboken can understand what your code is referring to. They come included with PySide.

That’s all you need to generate the Python bindings for your library. The last step is building the project as you usually do.

Update 2024-11-16: Updated the post with the released version of the module.

Sunday, 11 August 2024

I’ve realized that it’s been nearly a month since the last update about my GSoC project, so it’s time to publish a new one.

I’ve been upstreaming the Python bindings to their corresponding repositories and addressing the comments. Many thanks to Nico, Christophe, Volker, Ben and Carl (my mentor) for their comments! The CMake part has improved a lot and it’s almost ready to be merged. CI support should be ready for FreeBSD and Linux. We can add support for Windows if people are interested.

I’ll probably write a tutorial on how to add Python bindings to a library next week.

Saturday, 10 August 2024

Most of the time programmers do not write new code. Instead, they read, try to understand,  extend, and fix bugs in existing code. While some parts of KDE are pretty new and follow modern standards, many parts are more then two decades old -- following obsolete coding principles, using outdated ways of solving problems, and having additions from several persons with different styles. Often when we read code, we immediately spot things we could improve.

Kent Beck's approach is applying a series of small tidyings that leads to structural change and an overall better software design. In his new book Tidy First? he describes his idea in three parts: Tidyings, how to manage tidyings, and software design theory.

In the first part the author introduces generic tidyings like dead code removal, moving declaration and initialization together, introducing new interfaces, or explicit parameters. Most proposals are not new, but it is a good reminder to follow them and fix these things wherever you come across them in code you are working with. After reading the first part, I felt motivated to create some tidying commits right away. For KDE more specific tidying could be added: Fix deprecation warnings from Qt and KF, replace C-style code by C++, use modern C++ (range-base for loop, initialization lists), fix compiler warnings.

The second part gives hints on how to organize and commit tidyings. Separate tidyings from new features or behavioral changes. Find a balance between asking for review of your tidyings too often or with too extensive reviews.

In the third part Kent Beck offers some basic ideas from software design, especially future options and code coupling.

The book is worth reading for both commercial and open-source developers. Both are facing similar issues. Open-source developers are not worrying about costs, but precious spare time dedicated to coding for their pet project. Every projects has bit rot and profits from regular tidyings by their developers.

People interested in software design will recognize the ideas from classic books like Structured Design or Refactoring: Improving the Design of Existing Code. Nevertheless, Tidy First? makes the knowledge easily accessible. Most chapters are only one to three pages long and the book stays below a hundred pages.

This is the first book of a planned series of small books. Kent Beck develops his ideas in his blog (partially pay-walled) and discusses his views with his readers. Some blog post make it into Kevin's weekly web reviews.

Thursday, 8 August 2024

The KIO Framework has gained support for de-facto standard, cross-desktop thumbnail generators. This means that we have a support for thumbnails from 3rd party applications! On Linux systems, many applications that produce some kind of output, such as a 3D file or text document, ship a thumbnailer file that tells file managers how to create thumbnails of their files. One specific example I've used here in the images are STL files, for which we don't have our own KDE-specific thumbnailer plugin.

Screenshot of various STL file thumbnails

Screenshot of a Xenomorph STL files

These thumbnailer files are currently used by Nautilus and Thunar, so we felt like we were missing out and wanted to join the party! :)

Thumbnailer files

Thumbnailer files are simple text files that tell the system what program we should run to generate a thumbnail. You can check what thumbnailers you have installed by running ls /usr/share/thumbnailers

For example, the STL thumbnailer file looks like this:

[Thumbnailer Entry]
TryExec=stl-thumb
Exec=xvfb-run --auto-servernum -w 0 stl-thumb -f png -s %s %i %o
MimeType=model/stl;model/x.stl-ascii;model/x.stl-binary;application/sla;

It tells the software running the thumbnailer what commands to use to generate the thumbnail, and what mimetypes it supports.

KDE Thumbnailer Plugins

On KDE side, we have used plugins for KIO, that reside in the kio-extras repository. They work just fine for our usecase in KDE apps, but nobody should need to write a KIO specific plugin for their application.

The changes to KIO

You can check the merge request for more in-depth details, but here's a summary of how I made it work side-by-side with our plugin system:

We utilize the KIO plugins always first if possible, since we know for sure they work. This is to avoid any possible regressions and oddities, and to keep the change as unintrusive as possible. When we encounter a mimetype that is not supported by our plugins, like STL files, we utilize a thumbnailer file instead.

This also means that it's transparent to users. Users do not have to worry which one they have installed.

Why make support for thumbnailer files then?

As mentioned earlier, no application should need to create a plugin for KIO just to make their thumbnails show up in our applications.

Thumbnailer files offer other benefits too, such as easing future transitions, (like from KF6 to KF7); working nicely with sandboxing, and being distributable in Flatpak bundles.

I am also working on moving our own plugins into thumbnailers, so we get the benefits from that too.

How can I test it out?

Currently it's only in the master branch of KIO, so if you really want to try it out, you will have to set up KDE Plasma development environment: https://develop.kde.org/docs/getting-started/building/kdesrc-build-setup/

When inside in the development environment, open Dolphin and enable the thumbnailers from preview settings.

Any help testing it would be very welcome! :) Let me know of any possible improvements and bugs!

Sunday, 4 August 2024

The Freedesktop.org Specifications directory contains a list of common specifications that have accumulated over the decades and define how common desktop environment functionality works. The specifications are designed to increase interoperability between desktops. Common specifications make the life of both desktop-environment developers and especially application developers (who will almost always want to maximize the amount of Linux DEs their app can run on and behave as expected, to increase their apps target audience) a lot easier.

Unfortunately, building the HTML specifications and maintaining the directory of available specs has become a bit of a difficult chore, as the pipeline for building the site has become fairly old and unmaintained (parts of it still depended on Python 2). In order to make my life of maintaining this part of Freedesktop easier, I aimed to carefully modernize the website. I do have bigger plans to maybe eventually restructure the site to make it easier to navigate and not just a plain alphabetical list of specifications, and to integrate it with the Wiki, but in the interest of backwards compatibility and to get anything done in time (rather than taking on a mega-project that can’t be finished), I decided to just do the minimum modernization first to get a viable website, and do the rest later.

So, long story short: Most Freedesktop specs are written in DocBook XML. Some were plain HTML documents, some were DocBook SGML, a few were plaintext files. To make things easier to maintain, almost every specification is written in DocBook now. This also simplifies the review process and we may be able to switch to something else like AsciiDoc later if we want to. Of course, one could have switched to something else than DocBook, but that would have been a much bigger chore with a lot more broken links, and I did not want this to become an even bigger project than it already was and keep its scope somewhat narrow.

DocBook is a markup language for documentation which has been around for a very long time, and therefore has older tooling around it. But fortunately our friends at openSUSE created DAPS (DocBook Authoring and Publishing Suite) as a modern way to render DocBook documents to HTML and other file formats. DAPS is now used to generate all Freedesktop specifications on our website. The website index and the specification revisions are also now defined in structured TOML files, to make them easier to read and to extend. A bunch of specifications that had been missing from the original website are also added to the index and rendered on the website now.

Originally, I wanted to put the website live in a temporary location and solicit feedback, especially since some links have changed and not everything may have redirects. However, due to how GitLab Pages worked (and due to me not knowing GitLab CI well enough…) the changes went live before their MR was actually merged. Rather than reverting the change, I decided to keep it (as the old website did not build properly anymore) and to see if anything breaks. So far, no dead links or bad side effects have been observed, but:

If you notice any broken link to specifications.fd.o or anything else weird, please file a bug so that we can fix it!

Thank you, and I hope you enjoy reading the specifications in better rendering and more coherent look! 😃

I like to call myself git “expert”, but I failed pretty badly few weeks ago I needed to bisect the kernel source code to figure out one bug.

General git bisect process is, You have two known commits, one is good and one is bad, and you keep searching for bad commit by splitting history in two. Lets say you have following changelog (not the actual changelog I was debugging, but example):

Saturday, 3 August 2024

KStars v3.7.2 is released on 2024.08.03 for Windows, MacOS & Linux. It's a bi-monthly bug-fix release with a couple of exciting features.

A few members of the KStars development team were enjoying their summer holidays over the past few weeks, but we still have a couple of exciting features in this release!

Multi-Camera Support

Wolfgang Reissenberger devoted countless hours to bring this complex feature that required lots of architectural changes in Ekos. If you have double rigs (or even more), we have a new great feature: multi camera support! If you have more than one optical train on your mount, you now will be able to run capture sequences for each of your optical trains in parallel from the same KStars instance. You simply need to create an optical train for each of your telescopes on your mount, create camera tabs for each optical train, create their own sequence and let them run in parallel.



This new feature may also be used in combination with the scheduler: in this release, the scheduler itself will control the first camera. On top of that, you could configure additional cameras in the capture tab which could execute their own capture sequences. Enhancing the scheduler such that it could control multiple optical trains in parallel is already under development and will be part of one of the next releases. So stay tuned!

Focus Advisor v4


John Evans refactored the Focus Advisor to make it simpler while still offering a lot of insight on parameters tuning. It is now more accessible to new users and has added functionality to optimize values for 2 of the more difficult Focus parameters: Step Size and Backlash (or AF Overscan).




In addition, Focus Advisor contains a convenience tool to locate stars by searching the range of motion of the focuser and another convenience tool to highlight differences between current Focus parameter settings and those recommended by Focus Advisor.

Akademy 2023 was almost year ago and soon Akademy 2024 is coming. This is probably good time to talk about Akademy 2023. I know it was in way too past but some of those who know me personally/professionally know that last year has been rollar-coaster for me emotionally and did not manage to write about event while recovering from it.

But since this post was sitting in draft from long time, it is finally time to finish and publish it.

Friday, 2 August 2024

The Amarok Development Squad is happy to announce the immediate availability of Amarok 3.1 "Tricks of the Light"!

Amarok 3.1 player window with a customized layout, featuring the new Similar Artists applet

Coming three months after 3.0.0 and two months after the first bugfix release 3.0.1, the main development focus in 3.1 has been getting Qt6 / KDE Frameworks 6 based version closer. We are not quite there yet, but not that far away anymore. And there are some quite nice new features too! Amarok 3.1.0 brings in a refreshed Last.fm integration, which uses more up-to-date account connection mechanisms, and is better at informing users of any Last.fm errors. Similar Artists context applet does a comeback, and there's naturally also a nice bunch of smaller features and bug fixes; this time the oldest fulfilled feature request was filed just under 15 years ago.

Changes since 3.0.1

FEATURES:
  • Last.fm plugin updated to use token-based authentication method and to notify user of session key errors (BR 414826, BR 327547)
  • Reintroducing Last.fm Similar Artists context applet - a new Amarok 3 version
  • Remember the previous destination provider when saving playlist (BR 216528)
CHANGES:
  • Amarok now depends on KDE Frameworks 5.89.
  • Cleanup of unused code and various changes that improve Qt6 compatibility but shouldn't affect functionality. (n.b. one won't be able to compile a Qt6 Amarok with 3.1 yet, but perhaps with the eventual 3.2)
  • Remove old derelict openDesktop.org integrations from about dialog. This also removes the dependency to Attica framework.
  • Disable gapless playback if ReplayGain is active and the following track is not from same album, to avoid volume spikes due to delay in the applying of ReplayGain (BR 299461)
BUGFIXES:
  • Small UI and compilation fixes
  • Fix saving and restoring playlist queue on quit / restart (BR 338741)
  • Fix system tray icon menu reordering
  • Fix erroneous apparent zero track progresses on track changes, which caused playcount updates and scrobbles to get skipped (BR 337849, BR 406701)
  • Fix 'save playlist' button in playlist controls
  • Sort playlist sorting breadcrumb menu by localized names (BR 277146)
  • Miscellaneous fixes to saving and loading various playlist file formats, resulting also in improved compatibility with other software (including BR 435779, BR 333745)
  • Don't show false reordering visual hints on a sorted playlist (BR 254821)
  • Fix multiple instances of web services appearing in Internet menu after saving plugin config.
  • Show podcast provider actions for non-empty podcast categories, too (BR 371192)
  • Fix threading-related crashes in CoverManager (BR 490147)

In comparison to changes between 2.9 to 3.0, the git repository statistics between 3.0 and 3.1 are somewhat short:

Tuomas Nurmi: 164 commits, +11910, -29957
l10n daemon script: 97 commits, +207075, -237380
Pino Toscano: 13 commits, +1, -11152

However, this is an excellent spot to send a huge thank you out to everyone who has been on board outside the git history; translators, packagers, bug reporters, writers, commenters, and of course: users - music fans all around the world! Happy listening, everyone! You rok!

Getting Amarok

In addition to source code, Amarok is available for installation from many distributions' package repositories, which are likely to update to 3.1.0 soon. A flatpak is currently available on flathub-beta.

Packager section

You can find the package on download.kde.org and it has been signed with Tuomas Nurmi's GPG key.