My Projects

QCoro

QCoro is a C++ library that makes it possible to use C++20 coroutines with Qt. It provides the necessary tools to create coroutines as well as coroutine-friendly wrappers for native Qt types.

KDE

I have been contributing to KDE for over a decade. I was involved in KDE Telepathy, KScreen and most prominently in KDE PIM. I am Akonadi maintainer and author or Google integration.

cmake-package

A Rust crate for Cargo build scripts that provides a simple way to find and use CMake package installed on the system.

Randa Report Part 2

Let me start by annoying you with some pictures:

<3 Randa
The misty mountains below which the coders dwell.
We totally had snow in September. Well, not in Randa, but in the valley next to it, but still. SNOW!

And now for the serious part: in my [last blog post]({% post_url 2017-09-14-randa-report-the-fall-of-kdatetime %}), I talked about achieving our main goal for this year’s Randa meetings - we successfully ported the entire Kontact away from the obsoleted KDateTime class. Since we finished this on Thursday, there was still enough time left to start working on something new and exciting.

Volker and Frederik went on to work on a KWin plugin to simulate various kinds of color blindness which will help developers to see how visually impaired users see their software, I did a bit more code clean-up after the porting and a bit of code-review.

On Friday morning Volker and I discussed search in KDE PIM. Broken and unreliable search was one of the most often mentioned issues in the KMail User Survey, which we ran for the past month and a half, so I decided to tackle the problem and make our indexing and searching infrastructure fast and reliable.

The final plan consists of several phases - starting with reorganizing our current code to put related pieces of code (like email indexing and querying code) into a single place to make the code easier to maintain. This phase is already progressing and I hope to finish it within the next week. The second phase will involve moving the code that is responsible for indexing data into the backend Resources - whenever a backend retrieves an email from an IMAP server or an event from Google Calendar it will also index it and will send the index data alongside the raw data to Akonadi. Akonadi will then take care for just writing the data into the Xapian database. This will speed up indexing, reduce the IO load and will ensure that all data are reliably indexed and stored before they are presented in Kontact. The third phase will involve changing Kontact to query the index database directly, instead of asking Akonadi to do it for us. This will speed up the search and provide results faster. The final phase will focus on which data we are actually indexing. As they say - less is sometimes more - so having fewer, but better-defined data will allow us to provide better and more exact search results to the user.

Once this is settled, we can make applications to depend on the search index - for example KOrganizer will be able to query the index to only get events from e.g. December 2017 instead of fetching all events from the calendar and then figuring out if they should be displayed or not, making calendars of even the busiest people to load instantaneously.

All in all, it was an extremely productive hackfest for the PIM team and I’d again like to thank Mario, Christian and the rest of the Randa team for organizing the hackfest. You guys rock!

And remember, you can still donate to the Randa fundraiser to make future productive sprints possible!

Randa Report: The Fall of KDateTime

The main goal for me and Volker for this year Randa Meeting was to port KCalCore, our calendaring library, away from KDateTime. KDateTime/KTimeZone are classes for handling date, time and time zones which were used back in the KDE4 (and earlier) days when Qt’s QDateTime wasn’t good enough for us, mainly due to missing time zone support.

In Qt5 QDateTime finally gained all the necessary features we need which made it possible for us to leave KDateTime behind. But we couldn’t just go and replace “K” with “Q” everywhere - there are many subtle (and not-so-subtle) differences in API, behavior and some missing features of QDateTime that required us to carefully consider each step. The fact that we started working on this over 2 years ago shows how challenging task this was.

We did not expect to finish the port here, but once we dived into it, things went fairly well and I’m glad to say that after four days of intensive hacking, surrounded by Swiss Alps and mountains of chocolate, we succeeded. KCalCore is now free of KDateTime and KTimeZone and that in turn made (after some minor adjustments) the rest of KDE PIM free of KDELibs4Support. That’s a huge milestone for us.

Many thanks to John Layt for laying the initial ground for the porting and to Mario and Christian for the steady stream of chocolate and sweets to soothe our nerves :-)

If you want to help us to continue improving Kontact and other parts of KDE, please donate to the Randa fundraiser so that we can continue organizing similar productive sprints in the future. Thank you!

Developing KDE PIM with Docker

Getting started with contributing to KDE PIM can be hard - we have nearly 60 repositories with complicated dependencies - just getting that right can discourage many people from even trying. And then there’s, of course, the risk factor of running development build alongside your production Kontact, endangering your precious emails.

To address all these issues I have created a Docker image. It’s based on the KDE Neon Developer edition and it has all the dependencies pre-installed and pre-configured and comes with a set of handy shell scripts to make your life easier. It also has the environment set up properly so that you can run the development build of Kontact inside of the container - completely isolated from your production installation.

Interested now? Follow the instructions how to build the Docker image and how to run the container on our KDE PIM Docker wiki page.

The section regarding GPU drivers is still incomplete, if you have any knowledge regarding running OpenGL-enabled applications inside a Docker container with Nouveau or AMD/ATI drivers, let us know, please!

You can probably use our Docker image to develop other KDE applications in there as well, or you can take a look at Jos’ blog about Developing KDE with Docker and create your own Docker image to work on your favorite KDE application.

Happy hacking!

KDE PIM in Randa 2017

Randa Meetings is an annual meeting of KDE developers in a small village in Swiss Alps. The Randa Meetings is the most productive event I ever attended (since there’s nothing much else to do but hack from morning until night and eat Mario’s chocolate :-)) and it’s very focused - this year main topic is making KDE more accessible.

Several KDE PIM developers will be present as well - and while we will certainly want to hear other’s input regarding accessibility of Kontact, our main goal in Randa will be to port away from KDateTime (the KDE4 way of handling date and time in software) to QDateTime (the Qt way of handling date and time). This does not sound very interesting, but it’s a very important step for us, as afterward, we will finally be free of all legacy KDE4 code. It is no simple task, but we are confident we can finish the port during the hackfest. If everything goes smoothly, we might even have time for some more cool improvements and fixes in Kontact ;-)

I will also close the KMail User Survey right before the Randa meetings so that we can go over the results and analyze them. So, if you haven’t answered the KMail User Survey yet, please do so now and help spread the word! There are still 3 more weeks left to collect as many answers as possible. After Randa, I will be posting a series of blog posts regarding results of the survey.

And finally, please support the Randa Meetings by contributing to our fundraiser - the hackfest can only happen thanks to your support!

Konqi can't wait to go to Randa again!

You can read reports from my previous adventures in Randa Meetings in 2014 and 2015 here:

KDE PIM on Akademy

Akademy is over and so here’s a short summary of what the PIMsters have worked on during the past week.

Wiki Cleanup

Me and Volker sat down and went through all KDE PIM wikipages on community.kde.org, userbase.kde.org and techbase.kde.org. Most of our wiki pages are horribly outdated, so we tried to clean them up, remove pages that are no longer relevant or useful. With fewer pages to take care of and better overview of what all content we have, we should be able to keep them more up-to-date than we did in the past years.

Developer Story

Contributing to KDE PIM is hard and we know that. Getting all the dependencies and environment set up correctly is not trivial, and you can’t run stable and development Kontact alongside each other easily.

We decided to address all those issues and make contributing to KDE PIM substantially easier. We are working on a Docker image that has all the dependencies and environment set up, so developers just need to run a single command to build entire KDE PIM. And thanks to the containerization, it’s also possible to use the development version of Kontact in parallel with the stable version.

We hope that having ready-made development environment it will be easier for new contributors to get involved with KDE PIM. We will post a more details once the Docker image is ready.

Kontact Homepage

Right now kontact.kde.org and kontact.org just redirect to our page on the Userbase wiki. We decided that we want a simple, but professionally-looking web site to market Kontact as an actual product so that it appears more attractive to new users, especially those who will be coming from Windows in the future and contains comprehensive information for both users and developers.

KMail User Survey

During QtCon 2016 we started working on KMail user survey to get a better idea of what our user base is like, how they use KMail and what their impressions of it are. And now the survey is finally live, so please go and fill it if you haven’t done so yet.

Wayland Support

Volker has finished porting Kontact to Wayland, so if you have Qt 5.9, you can now run Kontact natively on Wayland. Our main limitation was Wayland support in QWebEngine, which we use to render emails, but that has been resolved in Qt 5.9.

Merging Exchange Support

Krzysztof Nowicki has been working on Microsoft Exchange support for Kontact for a while now. We now have plans to merge his code into kdepim-runtime repository, so if everything goes right the Exchange support will be available out-of-the-box to all our users starting with the December release of KDE Applications.

Next Sprint

We will be meeting soon again in Randa. Our main plan for the sprint is to continue with removal of KDateTime from our code, and thus making KDE PIM free of kdelibs4support.

There’s some more that I did not mention here, you can check the full notes for details.

Facebook Events in KOrganizer

Sounds like déjà vu? You are right! We used to have Facebook Event sync in KOrganizer back in KDE 4 days thanks to Martin Klapetek. The Facebook Akonadi resource, unfortunately, did not survive through Facebook API changes and our switch to KF5/Qt5.

I’m using a Facebook event sync app on my Android phone, which is very convenient as I get to see all events I am attending, interested in or just invited to directly in my phone’s calendar and I can schedule my other events with those in mind. Now I finally grew tired of having to check my phone or Facebook whenever I wanted to schedule event through KOrganizer and I spent a few evenings writing a brand new Facebook Event resource.

Inspired by the Android app the new resource creates several calendars - for events you are attending, events you are interested in, events you have declined and invitations you have not responded to yet. You can configure if you want to receive reminders for each of those.

Additionally, the resource fetches a list of all your friend’s birthdays (at least of those who have their birthday visible to their friends) and puts them into a Birthday calendar. You can also configure reminders for those separately.

Facebook Resource Configuration dialog
Facebook events in KOrganizer

The Facebook Sync resource will be available in the next KDE Applications feature release in August.

Git trick #481: Prevent accidentally pushing into git instead of Gerrit

Some while ago I wrote about a little git hook that automatically sets up your commit author identity  after git clone based on the remote origin address. Recently I learned that in git 2.8 a new pre-push hook was introduced, and I immediately knew it will fix my second biggest pain point: accidentally pushing directly into git instead of Gerrit.

If you often switch between different projects where some use Gerrit for code review and some don’t, it’s very easy to just mistakenly do

git push master

when in fact you wanted to

git push HEAD:refs/for/master

There are some tricks how to make it harder for you to accidentally do this, like creating a “gpush” alias that pushes to refs/for/master and disabling pushing into the ‘origin’ remote by changing the push URL to something invalid. That, however, is not perfect because there are still ways how to by-pass it. And it becomes complicated if you use more than one remote and it’s clumsy if you sometimes do want to push directly into git (for example to submit a large patch series).

With a custom pre-push hook, we can check if the remote that we are pushing into is a Gerrit instance and then check if the remote ref that we are pushing into is a “Gerrit ref” (refs/for/foo) instead of a regular branch and we can have a nice “Are you sure you want to do this?” prompt:

#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# (C) 2017 Daniel Vrátil &lt;dvratil@kde.org&gt;
# License: GPL

import os
import sys

def remoteIsGerrit(remoteName, remoteUrl):
    # if the remote is called &quot;gerrit&quot;, assume it's Gerrit
    if 'gerrit' in remoteName:
        return True
    # if the remote URL contains the default Gerrit port, assume it's Gerrit
    if ':29418/' in remoteUrl:
        return True

    # TODO: Add custom checks to match your non-standard Gerrit configuration
    return False
def main():
    # name and URL of the remote we are pushing into is passed as arguments
    if not remoteIsGerrit(sys.argv[1], sys.argv[2]):
        # If we are not pushing into gerrit, then simply allow the push
        return
    # The pushed refs are passed in via stdin
    for line in sys.stdin:
        # line = &quot;localRef localRev remoteRef remoteRev&quot;
        remoteRef = line.split(' ')[2]
        # Check if the remoteRef contains the typical Gerrit 'refs/for/foo'.
        if not remoteRef.startswith('refs/for/'):
            print('!!')
            print('!! You are pushing directly into git instead of Gerrit !!')
            print('!! Do you want to continue? [y/N] ', end = '', flush = True)
            if open('/dev/tty', 'rb').readline().decode().strip().lower() == 'y':
                return
            else:
                sys.exit(1)

if __name__ == &quot;__main__&quot;:
    main()

Save this a file as “pre-push” and move it into .git/hooks/ folder in your local repository clone. Remember to make the script executable.

Here is how it works: trying to push into “gerrit” remote to branch “5.9” directly gets intercepted by our new hook and if you press ’n’ the push gets aborted. If I would’ve pressed ‘y’, then the push would proceed.

$ git push gerrit 5.9
Enter passphrase for key '/home/dvratil/.ssh/id_rsa.qt':  
!! 
!! You are pushing directly into git instead of Gerrit !! 
!! Do you want to continue? [y/N] n
error: failed to push some refs to 'ssh://dvratil@codereview.qt-project.org:29418/qt/qtbase.git'</pre>
<p>Now when we try to push to the correct ref (`refs/for/5.9`) the hook accepts the push without any complaints:</p>
<pre>$ git push gerrit HEAD:refs/for/5.9
Counting objects: 6, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 407 bytes, done.
Total 4 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2)
remote: Processing changes: new: 1, refs: 1, done    
remote: 
remote: New Changes:
remote:   https://codereview.qt-project.org/......
remote: 
To ssh://dvratil@codereview.qt-project.org:29418/qt/qtbase
 * [new branch] HEAD -&gt; refs/for/5.9

To have the hook automatically copied into every new repository that you clone, save it as “pre-push” into .git-templates/hooks/ and run the following command:

git config --global init.templatedir ~/.git-templates

Git will automatically copy everything from the ’templatedir’ into the .git directory after every new git clone, so you don’t need to bother with doing that manually. Unfortunately for all your existing checkouts, you have to copy the hook manually

KMail: "Multiple Merge Candidates" error and how to fix it

If you can’t synchronize a folder in KMail and you are seeing “Multiple Merge Candidates” error after the synchronization fails, here’s a how to fix the folder to make it synchronize again - basically you force KMail to forget and re-sync the folder again.

  1. Open Akonadi Console.
  2. Go to the Browser tab.
  3. Right-click the broken folder and select “Clear Akonadi Cache” - this will remove all emails from the folder in Akonadi. This will NOT delete your emails on the server.
  4. Akonadi Console will freeze for a while, wait until it unfreezes (sorry, it’s just a developer tool, we don’t have a very good UX there :-)).
  5. Logout and login to make sure all PIM components are restarted.

After login start KMail (or Kontact) and hit “Check mail". KMail will now re-download all emails from the previously broken folder. This may take a while depending on how large the folder is and how fast your internet connection is. After that the synchronization should work as expected.

In the upcoming KDE Applications 16.12.1 release Akonadi will have a fix that fixes the reason why the “Multiple Merge Candidates” error occurs, so hopefully in the future you should not see this error anymore.

Akademy 2016 is over :(

It’s actually been over for two days, but I’m still sitting in Berlin and only now got to write something.

As every year, it was great to see all my friends and fellow hackers again. Thanks everyone for being so awesome, I enjoyed every day of QtCon and Akademy with you. Can’t wait to meet everyone again next year :-)

In the terms of KDE PIM, this year’s Akademy was very productive. We had our KDE PIM BoF session on Monday afternoon, where we spent most of the time discussing KDE PIM User Survey - a plan of mine to get more information about our users and their use cases. The results will help us, the KDE PIM devs, to better understand how our users use our software and thus prioritize our focus. We ended up with an initial set of questions we intend to ask our users and next week I’ll meet with some more KDE PIM hackers that could not attend Akademy and we will finalize the set of questions so that we can publish the survey later this month.

We also talked about some other topics on the meeting, like releasing of some of our libraries that Kube wants to use and so on.

You can read the mostly complete meeting notes on the KDE PIM wiki.

Outside of the BoF session we touched the topic of KDE PIM sprints and meetings. We want them to be more focused in the future, i.e. having a specific topic for each meeting that we will all work on together. We hope to do one meeting in Autumn this year to finish porting KCalCore away from KDateTime and KDELibs4Support, then a Spring meeting in Toulouse (which has become our new regular place for Spring sprints), then Randaaaaaaaaaaa (which gives us full 6 days of uninterrupted hacking with only small breaks to eat Mario’s chocolate :-)) and then it’s Akademy time again!

Oh and I can’t forget to mention that the KDE PIM team was awarded the Akademy Award for our work on, well, KDE PIM :-). It was a great feeling to stand on the stage knowing that people appreciate our work.


Regarding my PIM work during Akademy, I think this year was pretty good. I did my share of partying during QtCon, so I could spent most of Akademy days hacking from morning until they kicked us out from the venue, and then continuing with some more hacking in the KDAB office until late night. Already before the event I merged a big change that improves the Akonadi change notification system. I managed to polish it during Akademy and fix several crashes and bugs.

Another big change was to our test-suite. It contains among other things integration tests, where we run an actual Akonadi server in an isolated environment (so that it does not touch any real data) and test whether clients interact with it as they are supposed to do. For these integration tests we’ve been only using the SQLite database until now, but I have now enabled MySQL and PostgreSQL too, so we run each test three times - once for each of the backends. This has revealed several corner-case issues that we weren’t aware of until now. The test still run into some issues on the CI on build.kde.org but locally they pass for me (with only one exception). Addressing those issues is on the top of my todo list now.

I also started working on an experimental XML->C++ generator, which would allow me to get rid of some 12,000 lines of hand-written C++ code that implements the communication protocol between Akonadi server and the clients. Instead I will generate the code from a simple XML. So far I managed to get it to generate a code that compiles, but there’s still a lot of work ahead to make it generate an optimal and correct code.

I’ll spend the next week meeting all my colleagues from KDAB, which I’m really looking forward to. Although I know many of them from KDE, there are lots of people I haven’t met yet, so it will be great to attach faces to the names. After that, it’s back to Prague and to regular work (and some more Akonadi hacking ;-)).

Oh and if you haven’t heard yet, KDE is celebrating 20th birthday. Go check out the timeline of KDE and get the amazing “20 Years of KDE” book!