28 May 2016

feedPlanet KDE

Debian: Outreachy, Debian Reproducible builds Week 1 Progress Report

It has been an exciting first week of my internship. I was able to produce a few patches,
and submitted upstream, as well as into debian packaging. I am hopeful they will get accepted,
preferably upstream so all can benefit!

kapptemplate:
https://bugs.kde.org/show_bug.cgi?id=363448
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=825122

choqok:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=825322

However, after speaking with Lisandro ( choqok maintainer ) I decided a better course of action
is to try and fix the actual source of the problem, kconfig_compiler from kde4libs is generating
non utf-8 cpp and header files under certain conditions like an environment that does not have a
locale set. Of course, I have some help with this from wonderful folks in KDE, which is good
because kde4libs codebase is HUGE! So I hope to have two new bugs early next week for choqok.

I checked up on my existing kdevplatform bug:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=815962

And noticed it has not received attention, so I created upstream bug:
https://bugs.kde.org/show_bug.cgi?id=363615

And updated the debian bug patch DEP 3 with upstream bug url.

I have been working on kdevelop-php without success yet, looks like build-id
( I still need to find the source ) and embedded kernel which I think I found,
though I will reach out to my awesome mentor to get some help on this one.

I did not knock out quite as many builds as I wanted, but I picked some hard ones
that are new to me 🙂 So in the end it was a very successful first week, because I
have learned several new things that will help me with future reproducible builds.

Have a great weekend.

28 May 2016 12:00am GMT

27 May 2016

feedPlanet KDE

Mass edit your tasks with t_medit

If you are a Yokadi user or if you have used other todo list systems, you might have encountered this situation where you wanted to quickly add a set of tasks to a project. Using Yokadi you would repeatedly write t_add <project> <task title>. History and auto-completion on command and project names makes entering tasks faster, but it is still slower than the good old TODO file where you just write down one task per line.

t_medit is a command to get the best of both worlds. It takes the name of a project as an argument and starts the default editor with a text file containing a line for each task of the project.

Suppose you have a "birthday" project like this:

yokadi> t_list birthday
                             birthday
ID|Title               |U  |S|Age     |Due date
-----------------------------------------------------------------
1 |Buy food (grocery)  |0  |N|2m      |
2 |Buy drinks (grocery)|0  |N|2m      |
3 |Invite Bob (phone)  |0  |N|2m      |
4 |Invite Wendy (phone)|0  |N|2m      |
5 |Bake a yummy cake   |0  |N|2m      |
6 |Decorate living-room|0  |N|2m      |

Running t_medit birthday will start your editor with this content:

1 N @grocery Buy food
2 N @grocery Buy drinks
3 N @phone Invite Bob
4 N @phone Invite Wendy
5 N Bake a yummy cake
6 N Decorate living-room

By editing this file you can do a lot of things:

Let's say you modify the text like this:

2 N @grocery Buy drinks
1 N @grocery Buy food
3 D @phone Invite Bob
4 N @phone Invite Wendy & David
- @phone Invite Charly
5 N Bake a yummy cake
- S Decorate table
- Decorate walls

Then Yokadi will:

You can even quickly create a project, for example if you want to plan your holidays you can type t_medit holidays. This creates the "holidays" project and open an empty editor. Just type new tasks, one per line, prefixed with -. When you save and quit, Yokadi creates the tasks you entered.

One last bonus: if you use Vim, Yokadi ships with a syntax highlight file for t_medit:

t_medit syntax highlight

This should be in the upcoming 1.1.0 version, which I plan to release soon. If you want to play with it earlier, you can grab the code from the git repository. Hope you like it!

27 May 2016 11:02pm GMT

Wiki, what’s going on? (Part 2)

WTLGoinOn

Hello everybod,

I'm here to give you some updates on our work with the WikiToLearn community and, since I like this idea, I was thinking that "Wiki, what's going on?" could become a nice section of our blog where to give updates on our work and things like that.

So, let's start: recently the promo team had a (mini) sprint where some important features were discussed. Mainly we focused on participation: both on how to involve new users and on how to enforce the community structure. In my opinion, this is an extremely important task to be accomplished and I appreciate all the efforts we are doing to come up with an effective organization. We came up with cool ideas, such as local groups, "wiki-thons" and others but now it's time to test them. The editors group is working hard as well: review of the contents, definition of an internal structure and writing new contents are our daily work. Actually I'm not part of the tech group, so I can not give you any update but the certainty that our guys work day after day to improve ux experience, to a better and always effective infrastructure and to solve other problems of which I have no expertise to talk about.

For today it's everything. I'd like to conclude this post with something I am pretty sure about: if you ask "Wiki, what's going on?", "working hard to improve" can be a good answer!

Bye,

Matteo

L'articolo Wiki, what's going on? (Part 2) sembra essere il primo su Blogs from WikiToLearn.

27 May 2016 1:48pm GMT

KDE Partition Manager 2.2.0

KDE Partition Manager and KPMcore 2.2.0 are now released with a proper LUKS support! This is a fairly big feature release but it also got tested more than usual, so a lot of bugs were fixed (including some crashes). Unfortunately there is still one more reproducible crash (bug 363294) on exit when file open/save dialogs are used (and very similar crashes actually exist in some other KDE programs, e.g. kdebugdialog or Marble). If anybody has any idea how to fix it I would be grateful.

Changes in this release:

There is also a slightly older (e.g. now we use KPasswordDialog to unlock LUKS partitions) video demonstrating LUKS support.

Note for packagers: Calamares 2.2.2 will most likely work with KPMcore 2.2.0 after recompilation but Calamares 2.3 will be recommended as soon as it is released. Older versions of KDE Partition Manager are not compatible with KPMcore 2.2.0, so you need to update KPMcore and KDE Partition Manager at the same time. Qt 5.6.1 also fixes one minor NTFS bug in KPMcore but unfortunately it is not released yet.

Download links:

KPMcore 2.2.0

KDE Partition Manager 2.2.0

There are already packages for Arch and Gentoo, hopefully other distros will package it too.

27 May 2016 12:16pm GMT

Answer about “Akonadi for e-mail needs to die” blog

Yesterday morning I read planetkde.org as usual before to hack on kdepim and I saw this blog.

I thought that it was a constructive blog, but not!

(As all your articles on your blog about kdepim. I don't understand why you are not able to switch to another mailer before.)
Mr "Andreas K. Hüttel" is just an user which was frustrated by a bug about his IMAP server.

I can confirm that KMail is not free bug, Akonadi is not perfect too. We work a lot each days to fix the bugs. You can make the same blog about each application which doesn't work as you want. You can criticize all these programs and wrote that developers lose their time to work on. I hope that you wrote some blog as it for Kernel Linux, Xorg, LibreOffice etc. for sure they are not perfect too.

KDEPIM team is small but I think that we make a good work. Perhaps you should read kde-commit to see all fixes that we did…

But Mr "Andreas K. Hüttel" I can tell you:

Now Mr "Andreas K. Hüttel" with a blog as it you will discourage for sure some new user/developer, but also people which helps us, they will think that they're wasting their time. It's unacceptable.

Mr "Andreas K. Hüttel" you just have NOT ANY respect for all work done by the KDEPIM team, by the doc team, by the i18n team, by all user support guys, by the users which reported bugs.

Mr "Andreas K. Hüttel" if a day you are able to work on a project you will see that it's not possible to reproduce all bugs because we don't have all the time, we don't have the same environment. Fixing a bug take time when we can't reproduce when it's a corner case. Some time we don't have the good technology as a specific server IMAP etc. But perhaps it's too hard for you to understand it.

Ok Mr "Andreas K. Hüttel" it's sad that we were not able to fix your bug, but it's more sad that you think that all kdepim team work is a lost of time.

As I wrote who are you to tell us that it's a lost of time ?

Do you provide a technical solution ? NO

So for your information we will not stop to develop KMail because you think it's a lost of time. We will continue, I will continue because I know that a lot of people uses it and they are happy with KMail based on Akonadi. I will continue to "lose my time" each day as I respect users which use KMail, it's not your case.

I want to thank all people which participate, all guys was participating to KMail improvement. We make KMail better for sure. Thanks guys. Thanks Doc Team, Thanks I18n Team, Thanks User Team Support, Thanks happy users, Thanks not happy users which understand our work.

To conclude we are in open-source you are not happy you can use another application, all developer is able to choice on which technology he wants to develop, but it's really unacceptable as you reduce kdepim team work (and other teams) to a lost of time because you are just a frustrated person.

27 May 2016 5:07am GMT

26 May 2016

feedPlanet KDE

Akonadi for e-mail needs to die

So, I'm officially giving up on kmail2 (i.e., the Akonadi-based version of kmail) on the last one of my PCs now. I have tried hard and put in a lot of effort to get it working. However, it costs me a significant amount of time and effort just to be able to receive and read e-mail - meaning hanging IMAP resources every few minutes, the feared "Multiple merge candidates" bug popping up again and again, and other surprise events. That is plainly not acceptable in the workplace, where I need to rely on e-mail as means of communication. By leaving kmail2 I seem to be following many many other people... Even dedicated KDE enthusiasts that I know have by now migrated to Trojita or Thunderbird.

My conclusion after all these years, based on my personal experience, is that the usage of Akonadi for e-mail is a failed experiment. It was a nice idea in theory, and may work fine for some people. I am certain that a lot of effort has been put into improving it, I applaud the developers of both kmail and Akonadi for their tenaciousness and vision and definitely thank them for their work. Sadly, however, if something doesn't become robust and error-tolerant after over 5 (five) years of continuous development effort, the question pops up whether the initial architectural idea wasn't a bad one in the first place - in particular in terms of unhandleable complexity.

I am not sure why precisely in my case things turn out so badly. One possible candidate is the university mail server that I'm stuck with, running Novell Groupwise. I've seen rather odd behaviour in the IMAP replies in the past there. That said, there's the robustness principle for software to consider, and even if Groupwise were to do silly things, other IMAP clients seem to get along with it fine.

Recently I've heard some rumors about a new framework called Sink (or Akonadi-Next), which seems to be currently under development... I hope it'll be less fragile, and less overcomplexified. The choice of name is not really that convincing though (where did my e-mails go again)?

Now for the question and answer session...

Question: Why do you post such negative stuff? You are only discouraging our volunteers.
Answer: Because the motto of the drowned god doesn't apply to software. What is dead should better remain dead, and not suffer continuous revival efforts while users run away and the brand is damaged. Also, I'm a volunteer myself and invest a lot of time and effort into Linux. I've been seeing the resulting fallout. It likely scared off other prospective help.

Question: Have you tried restarting Akonadi? Have you tried clearing the Akonadi cache? Have you tried starting with a fresh database?
Answer: Yes. Yes. Yes. Many times. And yes to many more things. Did I mention that I spent a lot of time with that? I'll miss the akonadiconsole window. Or maybe not.

Question: Do you think kmail2 (the Akonadi-based kmail) can be saved somehow?
Answer: Maybe. One could suggest an additional agent as replacement to the usual IMAP module. Let's call it IMAP-stupid, and mandate that it uses only a bare minimum of server features and always runs in disconnected mode... Then again, I don't know the code, and don't know if that is feasible. Also, for some people kmail2 seems to work perfectly fine.

Question: So what e-mail program will you use now?
Answer: I will use kmail. I love kmail. Precisely, I will use Pali Rohar's noakonadi fork, which is based on kdepim 4.4. It is neither perfect nor bug-free, but accesses all my e-mail accounts reliably. This is what I've been using on my home desktop all the time (never upgraded) and what I downgraded my laptop to some time ago after losing many mails.

Question: So can you recommend running this ages-old kmail1 variant?
Answer: Yes and no. Yes, because (at least in my case) it seems to get the basic job done much more reliably. Yes, because it feels a lot snappier and produces far less random surprises. No, because it is essentially unmaintained, has some bugs, and is written for KDE 4, which is slowly going away. No, because Qt5-based kmail2 has more features and does look sexier. No, because you lose the useful Akonadi integration of addressbook and calendar.
That said, here are the two bugs of kmail1 that I find most annoying right now: 1) PGP/MIME cleartext signature is broken (at random some signatures are not verified correctly and/or bad signatures are produced), and 2), only in a Qt5 / Plasma environment, attachments don't open on click anymore, but can only be saved. (Which is odd since e.g. Okular as viewer is launched but never appears on screen, and the temporary file is written but immediately disappears... need to investigate.)

Question: I have bugfixes / patches for kmail1. What should I do?
Answer: Send them!!! I'll be happy to test and forward.

Question: What will you do when Qt4 / kdelibs goes away?
Answer: Dunno. Luckily I'm involved in packaging myself. :)


26 May 2016 10:48am GMT

Gsoc 2016 Neverland #1

So it started.

After recovering from the "marathon" final exams (4 subjects a week), I'm getting back to Neverland.

One crazy idea which about building Neverland again from scratch is naming folders. I call it "crazy" because I was thinking about Neverland and Peter Pan story. Yes !!! I pretended naming the folders like Tinker Bell, Hook …

Of course it's just my imagination. My first commit on gsoc branch is almost folder structure. Now it's more express.

Before taking the next step, I considered reading the old source code again. And I've discovered some problems with some packages. As I had a chatting with my mentor about npm ecosystem, it is growing quickly and yet npm packages arent fully mature. Some packages are out of date or unmaintained or having new version (it's fast too).

The core package is which we are using is Gulp - a common package for frontend dev. We had to choose whether gulp3 or gulp4. Finally the answer was gulp3 and we are ready to update to gulp4 anytime.

And for some deprecated packages, we are looking for another packages or finding a way to hack around.


26 May 2016 4:16am GMT

25 May 2016

feedPlanet KDE

Plasma Wayland ISO Checkup

My Plasma Wayland ISOs are building nicely fresh each day. I asked Betty the fuzzy Guinea Pig to gave one a try today and there's still obvious bugs like no text on task bar and the blue window bars are back but she's generally impressed at how this is likely to be a good replacement for X in the near future.

Download 1.0GB ISO

Betty the Fuzzpig Tries Plasma Wayland

facebooktwittergoogle_pluslinkedinby feather

25 May 2016 5:26pm GMT

Virtual keyboard support in KWin/Wayland 5.7

Over the last weeks I worked on improved input device support in KWin/Wayland and support for virtual keyboard. KWin 5.7 will integrate the new QtVirtualKeyboard module which is now available under GPLv3. For us this means that we have access to a high quality QML based keyboard. For Qt it means that the virtual keyboard is exposed to more users and thanks to the open source nature it means that we can upstream fixes.

The virtual keyboard is integrated into KWin/Wayland making it part of our platform. To support it we implemented the text input interface in KWayland. If an application supports it, then the virtual keyboard can input text from the compositor side.

Video on youtube:

As you can see in the video the virtual keyboard is only enabled by default if no hardware keyboard is available. If a hardware keyboard gets plugged in the virtual keyboard gets disabled automatically. In addition there is a Status Notifier Item registered which allows to enable/disable the virtual keyboard independently of the hardware keyboard state. So on a notebook with a touch screen it's possible to get the virtual keyboard even if there is (of course) a hardware keyboard.

Implementing support for the virtual keyboard was an interesting journey which required many unexpected changes and improvements all over the place. First of all wl_text_input interface needed to be implemented as that's what is used in QtWayland 5.6. At one point I hit a wall and saw that the implementation in QtWayland is incomplete. So I checked how it looks like in QtWayland 5.7 and alas the complete implementation changed, it's using zwp_text_input_unstable_v2, which is not even in wayland-protocols. I'm not happy about QtWayland using not standardized interfaces as I think that's very bad for compatibility. Nevertheless I also added support for it in KWayland as otherwise we would not be able to communicate with applications using Qt 5.7. As the QtVirtualKeyboard will only be available with Qt 5.7, we need to support Qt 5.7's interface as well. In KWayland this is implemented in a transparent way and KWin announces support for both interfaces.

Another area which needed lots of work is the support for input devices in KWin. We need to properly detect whether a real keyboard is available. We needed to add further support for touch events in KWin. So thanks to the integration of virtual keyboard KWin now supports touch much better on Wayland.

The improvements for input devices are also useful in other areas. E.g. today I landed a change to not show the cursor image if no pointer device (mouse or touchpad) is connected.

25 May 2016 1:06pm GMT

Very explicit operator bool

From time to time I scroll through Qt-related forums and mailing lists, and whenever possible I try to help fellow developers out. The other day a StackOverflow thread caught my attention: a developer was asking "What is the purpose of operator RestrictedBool in QScopedPointer?"

Indeed, looking at QScopedPointer's implementation, one notices the strange RestrictedBool usage. Removing the other code, the bulk is:

template <typename T, typename Cleanup = QScopedPointerDeleter<T> >
class QScopedPointer
{
    typedef T *QScopedPointer:: *RestrictedBool;
public:
    inline operator RestrictedBool() const
    {
        return isNull() ? Q_NULLPTR : &QScopedPointer::d;
    }

    inline bool isNull() const
    {
        return !d;
    }
protected:
    T *d;
};

What is the reason for all of this machinery? The answer is quite simple: to make QScopedPointer usable in a boolean context. Thanks to the above we can write in our code:

QScopedPointer<int> sp;
if (sp) { ... }

Is that complicated implementation necessary to realize this? Unfortunately, it is, and the reason is rather cryptic and historical, so let's start our journey…

Conversion operators

In C++98, it was already possible to write custom conversion operators for our classes, to allow their objects to be converted to other types. Since we're interested in conversions to bool, given a type T, we can write an operator bool to convert it to a boolean:

struct T {
    operator bool() const { return true; }
};

This allows the usage of objects of type T whenever a boolean is expected:

T t;
if (t) { ... }
do { ... } while (t);
bool ok = t;

This is great, right? Unfortunately, not so much. One of the most prominent mis-features of C++ is the ability to happily convert and promote primitive types. In particular, bool has an implicit promotion towards int, causing any boolean to be promoted to 1 or 0 if true or false, respectively.

This unfortunately applies to our type as well. It is therefore legal to write code like this, although it does not make any sense:

T t;
int i = t;
t >> 4;
if (t < 42) { ... }
AnotherClassWithOperatorBool t2;
if (t == t2) { ... }

The Safe Bool Idiom

Since this is detrimental to type safety, people have come up with an ingenious solution which goes under the name of the Safe Bool Idiom, exploiting the fact that integer promotions and pointer arithmetic are disabled for pointers to data members and pointers to member functions, but they're still testable in a boolean context.

Our type T can therefore be rewritten as:

struct T {
private:
    typedef void (T::*bool_type)() const;
    // or, in C++11:
    // using bool_type = void (T::*)() const;
    void some_unused_function() const;
public:
    operator bool_type() const {
     // return &some_unused_function if true,
     // return nullptr if false
    }
};

And now T instances are still usable in a boolean context, but without the dangerous promotions and conversions. This is the same trick used by QScopedPointer and by many other classes in Qt, such as the other Qt smart pointers (QScopedPointer actually uses a pointer to a data member instead of a pointer to a member function).

Enter Modern C++

In C++11 the operator conversion functions gained an interesting feature: they could be marked explicit, just like we could mark constructors in C++98. The idea was indeed filling the semantic gap of implicit conversions between two types: while one could disable an implicit conversion by means of an explicit constructor, one couldn't do the same for an operator conversion function, which was always implicit.

This means, for instance, in C++98 we could do this:

struct A {};

struct B {
    explicit B(const A &);
};

void f(const B &);

// it is _not_ possible to implicitly convert a A to B
// because of the explicit constructor. This will fail:
A a;
f(a); // error: implicit conversion requested

However, we could not disable this implicit conversion:

struct D {};
struct C {
    operator D() const;
};

void f(const D &);

// since the conversion operator from C to D is implicit,
// it is legal to write:
C c;
f(c); // works: operator D() is implicit

This asymmetry was closed in C++11 with the introduction of explicit conversion operators, which forbid implicit conversions but still allow explicit ones:

struct D {};
struct C {
    explicit operator D() const;
};

void f(const D &);

C c;
f(c); // error; requires explicit conversion
f(static_cast<D>(c)); // works

Explicit operator bool

A direct application of an explicit conversion operator is defining an explicit operator bool for our class, with the hope that it would disable the unwanted integral promotions. For instance, we could write something like:

struct T {
    explicit operator bool() const { return true; }
};

This, indeed, makes our type system much, much better:

T t;

bool b1 = t; // fails to compile, implicit conversion

bool b2(t); // works, explicit conversion
bool b3{t}; // works
bool b4 = (bool)t; // works
bool b5 = static_cast<bool>(t); // works

int i = t; // fails to compile
int i(t); // fails to compile
t + 42; // fails to compile

How about a statement like if (t)? Does that trigger implicit or explicit conversion?

Well, neither. According to the Standard it actually triggers a contextual conversion to bool, which in practice means an explicit conversion (the exact wording is in §4.0.4 [conv]).

There are many places scattered around the Standard where such a "contextual conversion to bool" will happen:

Back to hacking Qt

How does this apply to our original issue with QScopedPointer?

Since Qt 5.7 requires C++11, I have decided to have a try at getting rid of the Safe Bool Idiom and replacing it with an explicit operator bool. After all, at KDAB we love hacking, and Qt is our favourite codebase :-).

From that, I learned an important lesson: there are at least two things that you could do with the Safe Bool Idiom that you can't do out of the box with explicit operator bool.

Comparison against literal 0

Consider this code:

T t;
if (t == 0) { ... }
if (0 == t) { ... }

This compiles and works with the Safe Bool Idiom, because 0 gets promoted to the null pointer, and the comparison happens between pointers. But this same code fails to compile with an explicit operator bool, because of the disabled promotion from boolean to integral.

The workaround I have found (which, at least, can be applied and makes total sense if T is a smart pointer class) is that you can add comparison operators against nullptr_t, triggering therefore a conversion from 0 to nullptr:

bool operator==(const T &lhs, std::nullptr_t) { return lhs.isNull(); }
bool operator==(std::nullptr_t, const T &rhs) { return rhs.isNull(); }

In case T is not a smart pointer class of sorts, I'm not 100% sure of a viable strategy, but I could argue that code that did t == 0 was very questionable in the first place…

This first workaround got implemented here in Qt.

Functions returning bool

Again, consider this code:

struct S {
    T t;
    bool isValid() const { return t; }
};

This works if T implements the Safe Bool Idiom, but fails to compile with explicit operator bool. The sad truth is that return statements use implicit conversion, not contextual conversion to bool (§ 4.0.2.4 [conv]). I'm quite surprised that this issue happily slipped through the Standard, but this is the way it is.

I do not see how to overcome this in an API compatible way, so this blocked my efforts of getting rid of the Safe Bool Idiom in Qt. In the meanwhile, the patch for QScopedPointer, QSharedPointer and QWeakPointer (which works, modulo these API breaks) is available here.

Conclusions

What have we learned? Well, we now know how the C++ type system gets better and better despite its roots in the C world, and we know why many classes in libraries employ this strange pattern for providing conversions to bool. We have also learned that explicit operators are not a replacement for the Safe Bool Idiom. And while doing that, we have improved the code of our favourite UI toolkit. Most importantly, we've had lots of fun!

The post Very explicit operator bool appeared first on KDAB.

25 May 2016 12:23pm GMT

Verdigris: Qt without moc

Verdigris is a header-only library that can be used with Qt. It uses macros to create a QMetaObject that is binary compatible with Qt's own QMetaObject without requiring moc. In other words, you can use Verdigris macros in your Qt or QML application instead of some of the Qt macros and then you do not need to run moc.

A verdigris statue

TL;DR: Github repository - Tutorial

Introduction

CopperSpice is a fork of Qt 4. Its main raison d'être is to get rid of moc because they consider it bad enough (IMHO wrongly). To do so, they replaced the user-friendly Qt macro with some less friendly macros.

However, CopperSpice is a whole fork of Qt, meaning they are maintaining the whole library. This also means they are recreating an ecosystem from scratch. If they had made it binary compatible, then they could have removed moc without the need to maintain the full Qt library. This is what Verdigris is.

Another problem of CopperSpice compared to Qt is that it generates and registers the QMetaObject at run-time when loading the application. Meanwhile, Verdigris uses constexpr to generate the QMetaObject at compile time. For this reason, binaries using CopperSpice are much bigger than binaries using Qt (moc or Vedrigris), and take also more time to load because of the massive amount of relocations.

Previous work

Most of the ground work is based on the code I wrote already in my previous blog post: Can Qt's moc be replaced by C++ reflection?. In that blog post, I was trying to see if reflection could help replace moc, while keeping the convenience of the current Qt macros. The goal was was to influence source compatibility as little as possible.

CopperSpice decided to use different macros that are less convenient. The macros of Verdigris are based or improved upon the CopperSpice ones.

Differences between CopperSpice and Verdigris

Pure Qt Verdigris CopperSpice
Requires moc Yes No No
Usage Convenient macros Ugly macros Ugly macros
Qt Compatibility Obviously Yes No
MetaObject generation Compile Time
(By moc)
Compile Time
(By the compiler)
Run-time
(At load time)
MetaObject location Shared read-only memory Shared read-only memory Heap

Macros

Qt Verdigris CopperSpice
Q_OBJECT W_OBJECT(MyClass)
...
W_OBJECT_IMPL(MyClass)
CS_OBJECT(MyClass)
public slots:
mySlot(int x);
void mySlot(int x);
W_SLOT(mySlot)
CS_SLOT_1(Public, void mySlot(int x))
CS_SLOT_2(mySlot)
signals:
void mySignal(int x);
void mySignal(int x)
W_SIGNAL(mySignal,x)
CS_SIGNAL_1(Public, void mySignal(int x))
CS_SIGNAL_2(mySignal,x)
Q_PROPERTY(int myProperty
WRITE setProp
READ getProp
NOTIFY propChanged)
W_PROPERTY(int, myProperty
WRITE setProp
READ getProp
NOTIFY propChanged)
CS_PROPERTY_READ(myProperty, getProp)
CS_PROPERTY_WRITE(myProperty, setProp)
CS_PROPERTY_NOTIFY(myProperty, propertyChanged)
private slots:
myPrivateSlot(int x);
void myPrivateSlot(int x);
W_SLOT(myPrivateSlot, (int), W_Access::Private)
CS_SLOT_1(Private, void myPrivateSlot(int x))
CS_SLOT_OVERLOAD(myPrivateSlot,(int))

The first difference of Verdigris is the W_OBJECT_IMPL macro that needs to be written in the .cpp file. This is one of the few points for which Verdigris is less convenient than CopperSpice as they do not need this macro.

In CopperSpice, you cannot define a slot inline in the class definition. You don't have this restriction with Verdigris.

Both CopperSpice and Verdigirs can have templated QObject class or nested QObject. Verdigris cannot, however, have function local QObjects (because of the static member staticMetaObject) and local classes cannot have static members.

From an implementation point of view, CopperSpice macros use __LINE__ to build an unique identifier, which means that two macros cannot be put on the same lines. So you can't declare several slots in a line or declare properties or signals/slots from a macro. (which ironically is one of the "problems" they raised about Qt4's moc). Verdigris's macros do not have this problem.

Tutorial

The best way to learn about how to use Verdigris is to read through the tutorial (conveniently brought to you through our Code Browser).

Benchmarks

All benchmarks were done with CopperSpice 1.2.2, Qt 5.6.0 or Qt 4.8.3, GCC 6.1

KitchenSink

I made the KitchenSink example from CopperSpice compile both with CopperSpice, Qt 5 with moc or with Verdigris (patch). This table show the amount in minutes:seconds taken by make -j1

Qt 5 (moc) Verdigris CopperSpice
Compilation time 1:57 1:26 16:43
Binary size 1.32 MB 1.36 MB 115 MB

I was surprised to see that Verdigris compiles faster than using moc. The cost of compiling the generated code in a separate compilation unit is what makes it slower, and including the generated file is a common way to speed up the compilation (which was not done in this case). CopperSpice is probably so slow because each translation unit needs to re-generate the code that generates the meta object for all the included objects (including the headers from CsCore, CsGui, ...). Verdigris, however, moves most of the slow-to-compile code in a W_OBJECT_IMPL macro in the .cpp code that is only parsed for the corresponding translation unit. Still, the tests take a very long time to compile, that's because they have many objects with lots of special methods/properties and we are probably hitting non-linear algorithms within the compiler.

Library loading time

Any program that links to a C++ library has some overhead because of the relocations and the init section. This benchmark simply links an almost empty program with the libraries, and compute the time it takes to run.

CopperSpice
(CsCore, CsGui)
Qt 4
(QtCore, QtGui)
Qt 5
(Qt5Core, Qt5Gui, Qt5Widgets)
56ms 16ms 17ms

Loading CopperSpice is much slower because all the MetaObjects needs to be created and the huge amount of relocations.
Note: Since the program is empty and has no QObject on his own, neither moc nor Verdigris were used. Qt5 and Qt4 themselves were compiled with moc as usual.

Signals/Slots run-time performance

I built the Qt benchmarks for testing connecting and emitting of Qt signals. There is no difference between Verdigris or the normal Qt. As expected since the QMetaObject structure is the same and the moc generated code is equivalent to the templated code.

CopperSpice is faster for signal emission because they inlined everything including QMetaObject::activate . Something we don't do in Qt because we want to maintain binary compatibility and inlining everything means we can't change much of the data structures used until the next major version of Qt. This contributes largely to the code size which is two order of magnitude more than using Qt.

Implementations details

As said previously, most of the constexpr code was based on what I wrote for the previous research. I had to replace std::tuple with another data structure because std::tuple turned out to be way too slow to compile. The GNU's libstdc++ implementation of std::tuple does about 16 template recursion per parameter only to compute the noexpect clause of its copy constructor. Which is quite limiting when the default limit of template recursion is 256 (so that means maximum 16 types in a tuple). There is also the fact that the compiler seems to have operation of quadratic complexity depending on the amount of template parameter or instantiation. I therefore made my own binary tree structure that can compile in a reasonable time. Instead of having tuple<T1, T2, T3, T4, T5, ....> we have Node<Node<Node<Leaf<T1>,Leaf<T2>>,Node<Leaf<T3>,Leaf<T4>>>, ...>

Nonetheless, the whole thing is some pretty heavy advanced template and macro tricks. While working on it I found and reported or even fixed compiler bugs in clang [1], [2], and GCC [1], [2], [3]

Conclusions

In conclusion, as CopperSpice has already shown, this shows that moc is not strictly necessary for Qt features. The trade-off is the simplicity of the macros. The alternative macros from CopperSpice and Verdigris are less convenient, and force you to repeat yourself. Complex template code can also increase compilation time even more than the overhead of moc.

On the other hand, we think the approach of CopperSpice was the wrong one. By forking Qt instead of being compatible with it, they give up on the whole Qt ecosystem, and the small CopperSpice team will never be able to keep up with the improvements that are made within Qt. (CopperSpice is a fork of Qt 4, it is way behind what Qt 5 now has)

Verdigris is a header-only library consisting on two headers that can easily be imported in a project to be used by anyone who has reasons not to use moc. You can get the files from the Github repository.

25 May 2016 11:08am GMT

Faster than Fast String Search in Qt

Is your code burning a lot of cycles hunting for strings? Maybe you need to find the proper charset nestled in a chunk of HTML, or look for the dimensions in an XPM image file, or locate the email attachment boundaries in a block of MIME. If you string search a lot and performance is important to you, you'll want to keep reading!

You may have encountered Boyer-Moore string searches if you have a formal education in Computer Science or if you're an algorithm junkie. When it comes to finding strings within text, Boyer-Moore is the gold standard for speed. It works by searching from the back end of the sought-after string and by using intelligent comparisons to skip over chunks of the test pattern.

Why is Boyer-Moore so darn fast?

As a very quick example, let's say we're looking for the string "</body>" within the following text:

<body>This is a block of sample text.</body>

The search starts at the back of the search string. Since "</body>" is seven characters long, the search looks at the seventh character of the text. It's a "T" which doesn't match the pattern's seventh character, so the string couldn't possibly match. Because "T" doesn't appear elsewhere in the pattern, the search skips another seven characters because that's the earliest next possible match. The text has a space at the fourteenth character - again not a match - so the search skips another seven characters. It continues skipping seven characters at a time until it encounters the end where it needs to check for a possible match. Our example doesn't hit any complicating cases but we'll get to that.

The diagram below highlights where the search makes comparisons against the text: it sniffs at it every once in a while (yellow), until it fully checks it at the end (green) and finds a match.

< b o d y > T h i s i s a b l o c k o f s a m p l e t e x t . < / b o d y >

Compared to a naïve implementation that would make 43 tests (one for each letter), the Boyer-Moore string search only needed six comparisons (length of text divided by length of pattern) before it found and verified the match. This algorithm performs very well if the pattern is long and doesn't contain repeats. However it still performs acceptably - at least as well as a standard string search - even in degenerate cases when the pattern and text contain all the same letters.

Substring matches and skip tables

There's just one problem - how does it know how far ahead to skip? This problem is apparent when we think about patterns containing duplicate letters, for example searching for "abba" within "aabacadabraabacabba". Because there are substring matches within the pattern and text, the algorithm can't just blaze forward by the length of the pattern or it may skip right over a match.

To solve this, we have to preprocess the test string to create a table that tells us how far ahead to skip. There's plenty of literature on how to create a Boyer-Moore skip table because there are a few alternative methods. All of them mean that the actual cost of a search is the search time plus the skip table generation time. (At least for the first search - for multiple searches using the same string, you can amortize the cost of the preprocessing against the subsequent searches provided you save your skip table.) That additional preprocessing can make a Boyer-Moore search slower than a standard string search under the wrong circumstances.

But that's where the power of C++ comes in. If you're looking for static strings anyway, shouldn't you be able to generate skip tables at compile time? Thanks to the extra power in the latest C++ standard - yes you can!

C++14 adds a crucial feature to implement compile-time Boyer-Moore string searching; namely a constexpr function is now allowed to contain loops and logic. With this additional functionality, we can build a skip table at compile time for any static search strings, eliminating the cost of the preprocessing step and making the already fast string searches even faster.

What's Qt got to do with it?

We've extended Qt's string searching by adding in compile-time Boyer-Moore string searches. This required a couple of constexpr functions and template changes to QByteArrayMatcher, giving us a new function qMakeStaticByteArrayMatcher(). Using this new string search capability is dead simple. Here's how you'd implement it in our earlier search example:

static const auto seekBodyEnd = qMakeStaticByteArrayMatcher("<.body>");

seekBodyEnd.indexIn(QByteArray("<body>This is a block of sample text.</body>"));

You'll notice we use another handy "new C++" feature, the auto keyword. If you're used to old-school C/C++, you might be fooled into thinking auto means "allocate this variable on the stack". That use has been deprecated since C++11 and ever since auto has become a lot more useful. Here, auto intelligently assigns the type of seekBodyEnd so we don't have to worry about the "under the covers" template magic that figures out the length of our search string.

Pretty cool, huh? Okay - now go out there and do some searching!

The post Faster than Fast String Search in Qt appeared first on KDAB.

25 May 2016 9:44am GMT

Some plans do not cooperate with you…

I hate do re-work. You don't have any idea how much I hate redo something. But when I wrote my GSoC project, I did in the week of the submission and the mentor that I needed was on vacation. So you can see the *drama* that I had.

I reached the creator at the IRC channel of KDE to see if he could help me, and Jonathan Riddel gives me the help that I need it, at the selection of bugs that I could work and others things that I was thinking about Umbrello. After two days, one before the end of submission time, I submitted my project to the KDE Community.

I planned my GSoC work in the way that I think that was better. But in this couple days, I need it stop and think for one sec. I was trying to do 3 things at the same time and don't understand everything deep enough to do the best work.

The timeline that I did on my project went to garbage. And now I'm doing this new one, so I can achieve the goal of my project. I realize that was better divide my project in tasks to be accomplished, instead follow the timeline, because sometimes I could have some trouble with something, and wait for feedback from my mentor, so I guess that I will be effective doing in this way. So now I will write the tasks that I need to do, based on my GSoC project. Are you ready? GO!

Tasks

Well, those are the tasks that I set in this new view of my project, for sure new tasks will appear since I'm trying to use the Divide and Conquer logic, so some of this tasks will be smashed apart, and if I end the tasks, my mentor and I will define new tasks for keeping me busy =) .

I'm calmer now, after right this and define things again. I can complain about have re-work, but sometimes is need it to think better and set things in black and white.

I hope that works hahahaha

That's all for today! Bye =*


25 May 2016 12:43am GMT

Rest in peace, Ted Cowan 1926-2016

I've been a bit quiet online lately. A few weeks back, my father had a stroke, from which he seemed to at least partly recover. However, last week we found that he could not recover, and was in fact dying.

He died 12 May 2016. I wrote about that a bit here: http://genweblog.blogspot.com/2016/05/rest-in-peace-ted-cowan-1926-2016.html . I was holding his hand as he passed, as was my sister. We're both happy that he is free of his pain, but are both grieving that both our parents are now dead.

Grieving is strange. Sometimes life seems normal, but sometimes not. So I will help out when I have the energy and interest, and at other times, withdraw and recharge. Talking about this is fine in open channels or privately, if you want. This is not a sensitive subject; we'll all die in the end after all.

25 May 2016 12:19am GMT

24 May 2016

feedPlanet KDE

if (LaKademy 2016) goto Rio de Janeiro

Rio de Janeiro, the "Cidade Maravilhosa", land of the eternal Summer. The sunlight here is always clear and hot, the sea is refreshing, the sand is comfortable. The people is happy, Rio de Janeiro has good music, food, the craziest parties of the world, and beautiful bodies having fun with beach games (do you know futevolei?).

But while Rio de Janeiro is boiling, some Gearheads based in Latin America will be working together in a cold and dark room in the city, attending to our "multi-area" sprint named Latin America Akademy - LaKademy 2016.

In my plans I have a lot of work to do in Cantor, including a strong triage in bugs and several tests with some IPC technologies. I would like to choose one to be the "official" technology to implement backends for Cantor. Cantor needs a IPC technology with good multiplatform support for the main desktop operating systems. I am think about DBus… do you have other suggestions or tips?

Other contributors also want to work in Cantor. Wagner wants to build and test the application in Windows and begin an implementation of a backend for a new programming language. Fernando, my SoK 2015 student, wants to fix the R backend. I will be very happy seeing these developers dirtying their hands in Cantor source code, so I will help them in those tasks.

During LaKademy I intent to present for the attendees some ideas and prototypes of two new software I am working. I expect to get some feedback and I will think about the next steps for them. Maybe I can submit them for new KDE projects… Well, let's see. 🙂

Wait for more news from the cold and dark room of our LaKademy event in Rio de Janeiro. 🙂

24 May 2016 11:46pm GMT

Qt on Android: How to use Android Toast

To get you started on this, we'll be using KDAB's Android utils with the humble Toast. Toasts are small popups which are used to show the user some feedback. Check Google's API guide for more info about toasts.

The easiest way to show a toast is to use Toast.makeText(Context context, CharSequence text, int duration) static method. This method needs 3 params:

Then we just need to call the show method.

Of course all the calls MUST happen on the Android UI thread.

As usual we're going to make use (abuse) of QtAndroidExtras and KDAB's Android utils (check this article to see how to add them to your project).

Let's create a simple function to show the toast:

enum Duration {
    SHORT = 0,
    LONG = 1
};

void showToast(const QString &message, Duration duration = LONG) {
    // all the magic must happen on Android UI thread
    KDAB::Android::runOnAndroidThread([message, duration] {
        QAndroidJniObject javaString = QAndroidJniObject::fromString(message);
        QAndroidJniObject toast = QAndroidJniObject::callStaticObjectMethod("android/widget/Toast", "makeText",
                                                                            "(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;",
                                                                            QtAndroid::androidActivity().object(),
                                                                            javaString.object(),
                                                                            jint(duration));
        toast.callMethod<void>("show");
    });
}

Yep, it's that simple!

Now let's take a closer look at the code:

Enjoy!

showToast(QLatin1String("Hello from Qt"));

The post Qt on Android: How to use Android Toast appeared first on KDAB.

24 May 2016 3:20pm GMT