Skip to content

Tuesday, 18 June 2019

Wayland needs a different mindset when you are programming, you cannot just assume things works the same way as in as X11. One of my first patches to konsole was the rewrite of the Tab Bar, and a different way to deal with Drag & Drop of the tabs. In my mind - and how wrong I was - I could assume that I was dragging to a konsole main window by querying the widget below the mouse. Nope, this will not work. As Wayland has security by default, it will not give you anything global. What if I was a spy app trying to record another one to send to NSA? Security in Wayland is much stricter, and because of that I had to redo my drag & drop patch.

Konsole should work now with drag & drop of tabs in Wayland, as soon as the patch hits master. I also have other patches waiting that will make the wayland transition smoother, I’ll write about them in due time.

Monday, 17 June 2019

Yes, I know. The last post on the assistants is rather boring. And yet these days I have been working on the snapshot docker, though it still seems a little (just a little, you see) unfinished as Dmitry is said to experience a relatively high delay when switching between snapshots. However this is not what I can reproduce on my older laptop, so I am really waiting for his test results in order to further investigate the problem.

But there is something interesting happening just when I am randomly testing things. From Krita's debug output, I saw QObject::connect() complaining about the arguments I passed, saying it is expecting parenthesis. "Okay," I thought, "then there have to be something wrong with the code I wrote." And that was quite confusing. I remember having used member function pointers in those places, got a compile-time error since KisSignalAutoConnectionsStore did not support the new syntax, then switched back to the SINGAL() and SLOT() macros. KisSignalAutoConnectionsStore is a helper class to quickly (dis)connect a group of connections. One can use the addConnection() method to add a connection, and use clear() to remove all connections made before.

Well, everything good, apart from the fact that I missed the parenthesis, which I did not discover until I looked into the debug output. So I asked Dmitry why not add the new syntax to KisSignalAutoConnectionsStore, and he said we should.

What is good about the new syntax is compile-time checking. We probably do not want our connections to fail to be made only when you run the program, just because there is a typo in the signature. That is definitely tiring and hard to catch (hmm, I did not notice the problem until today I randomly glanced at the command line; it might be worse if I shipped the snapshot docker together with those careless bugs).

The modification to the code seems straightforward. All what happens is in the KisSignalAutoConnection class. In its constructor, the connection is made using QObject::connect(); in its destructor, the connection is removed by passing the same sets of arguments to QObject::disconnect() currently in master. The signature is just KisSignalAutoConnection(const QObject *, const char *, const QObject *, const char *), as SIGNAL() and SLOT() macros are but to append their arguments to the string "1" and "2" respectively.

So the problem we have is we do not want the arguments that specify the signals and/or slots to be just strings. We want them to be pointers to member functions, or maybe lambdas. According to QObject document, the signature for new-style connect() is:

1
QMetaObject::Connection QObject::connect(const QObject *sender, PointerToMemberFunction signal, const QObject *context, Functor functor, Qt::ConnectionType type = Qt::AutoConnection)

Okay, so we know that sender and receiver should be pointers to QObjects, and either the type of signal or functor we do not know. Now let's make our KisSignalAutoConnection constructor a template function:

1
2
3
4
template<class Signal, class Method>
inline KisSignalAutoConnection(const QObject *sender, Signal signal,
const QObject *receiver, Method method
Qt::ConnectionType type = Qt::AutoConnection);

But when these parameters are passed to QObject::connect(), we get a compile-time error, saying there is no matching overload for connect().

Why?

The answer is the Qt documentation is simplifying, if not hiding, the truth. The real definition for connect() is found in Line 227 of qobject.h:

1
2
3
4
template <typename Func1, typename Func2>
static inline QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
const typename QtPrivate::FunctionPointer<Func2>::Object *receiver, Func2 slot,
Qt::ConnectionType type = Qt::AutoConnection)

And tracking down the definition of QtPrivate::FunctionPointer, we get it in qobjectdefs_impl.h:

1
2
3
4
5
template<class Obj, typename Ret, typename... Args> struct FunctionPointer<Ret (Obj::*) (Args...)>
{
typedef Obj Object;
...
};

And seeing what we have passed to KisSignalAutoConnection (in the test code):

1
2
KisSignalAutoConnectionsStore conn;
conn.addConnection(test1.data(), &TestClass::sigTest1, test2.data(), &TestClass::slotTest1);

We can see that Func1 is a member function of TestClass, so QtPrivate::FunctionPointer<Func1>::Object is just TestClass. But the constructor of KisSignalAutoConnection receives a const QObject *. The problem here is that connect() is expecting a const TestClass *, but we give them a const QObject *. A base class pointer cannot be implicitly converted to a derived class pointer, so we have that error.

The resolution seems pretty simple, as we only need to include the types of sender and receiver into the template, and pass everything as-is to QObject::connect():

1
2
3
template<class Sender, class Signal, class Receiver, class Method>
inline KisSignalAutoConnection(Sender sender, Signal signal, Receiver receiver, Method method,
Qt::ConnectionType type = Qt::AutoConnection);

Sounds viable. But how can we store the four parameters? It might be intuitive to make another base class, say, KisSignalAutoConnectionBase(), and make KisSignalAutoConnection a template class, so we can store sender, receiver, etc.

But wait, isn't this just too complex? First of all, we do not have any overridden functions except for the destructor. What is more, we do not seem to have any valuable things in that base class -- it would be an empty class. The use of inheritance here is ugly and useless.

And, we do not need to store the four parameters at all. QObject::connect() returns a QMetaObject::Connection, which can be used later to disconnect() it. So instead of the parameters passed to connect(), we just store the Connection object. And that is not part of the template:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public:
template<class Sender, class Signal, class Receiver, class Method>
inline KisSignalAutoConnection(Sender sender, Signal signal, Receiver receiver, Method method,
Qt::ConnectionType type = Qt::AutoConnection)
: m_connection(QObject::connect(sender, signal, receiver, method, type))
{
}

inline ~KisSignalAutoConnection()
{
QObject::disconnect(m_connection);
}

private:
QMetaObject::Connection m_connection;

And with the test code mentioned above, we do make sure that the new implementation works well with both syntaxes.

So, great, krita developers, we can use the new syntax for auto connections as well.

PS: There will soon be another post on my work of the snapshot docker -- it's almost finished!

Tuesday, 14 May 2019

Hello, my name is Sharaf. My nick on IRC is sh_zam.

My project is to port Krita to android devices. We've been successful in making the APK, but it only works if I build it, as it requires tweaking qt libraries, a bit. At the moment, my goal is to make the build system fully automatic and spit out the signed APKs for different architectures at the end.

Once I do that, I'll move on to UI, events and other fun stuff!

So, there's a lot to do and learn. Now I will go back to coding. (-:

So, thank you KDE for choosing me and I hope I'll learn a lot from this community!

Friday, 14 October 2016

One afternoon twenty years ago Matthias Ettrich and Martin Konold sat at a stone table in the cafeteria of the university Tübingen and talked computers. They talked Linux and they talked desktop. They talked about making Linux accessible to everyone. This was the moment where KDE was born. This afternoon they walked away with a mission. Matthias went on to write the call to action to found the KDE project, and Martin to create the very first KDE mailing list kde@fiwi02.wiwi.uni-tuebingen.de.


On October 14th 1996 the famous announcement arrived on the newsgroups comp.os.linux.development.apps, comp.os.linux.misc, and de.comp.os.linux.misc:

    New Project: Kool Desktop Environment. Programmers wanted!

The new project quickly attracted a group of enthusiastic developers and they pushed out code with a frentic pace. kdelibs-0.0.1 was released in November, containing the first classes KConfig and KApplication. In May 1997 the young project presented at the Linux-Kongress in Würzburg. In August Kalle Dalheimer published the famous article about KDE in the German computer magazine c't which attracted a whole generation of KDE developers to the project. On Jul 12th 1998 KDE 1.0 was done and released. The community had not only implemented a friendly face for Linux but also a bunch of applications while going, including a full web browser.


KDE did hundreds more releases over the years, continuously improving and maintaining the growing number of applications and amount of code. The community grew. It started to do annual conferences such as Akademy or the Desktop Summits and focused developer sprints such as the Osnabrück or the Randa meetings. KDE e.V., the organization behind KDE, which was founded as partner for the KDE Free Qt Foundation, grew with the community to be the corner stone of the organizational structure of KDE, using German association law as its secret superpower (read more about this in the book "20 Years of KDE: Past, Present and Future").

Millions and millions of people used KDE software over the years. Thousands of people contributed. KDE made appearances in Hollywood movies, it was subject of theses and scientific studies, and it won many awards. KDE's founder, Matthias Ettrich even received the German Federal Cross of Merit. The timeline of twenty years of KDE is an impressive demonstration of what Free Software is able to achieve.


Akademy 2014 group photo by Martin Holec (CC-BY)


KDE also was a breeding ground. Many people started their careers there. Hundreds of students went through mentoring programs such as the Summer of Code or the Season of KDE. Whole projects emerged from KDE, such as ownCloud and its sibling NextCloud, Kolab, or KHTML, which turned into WebKit and then Blink, powering most of web browsers on this planet today.

Today Linux has reached world domination in various, sometimes surprising, ways. KDE has contributed its share to that. With Plasma it provides a slick and powerful desktop which does make Linux accessible to everyone. This mission has been accomplished. But there is more. Following KDE's vision of bringing freedom to people's digital life there are amazing projects exploring new areas through Free Software, be it an application such as Krita to bring freedom to digital painters, or a project such as WikiToLearn to create collaborative text books for education. When KDE people meet you can feel the enthusiasm, the openness, and the commitment to change the world to the better just as in the days of the beginning.




I joined KDE in 1999 with my first patch to KOrganizer. I wrote a lot of code, maintained and founded applications, served on the board of KDE e.V. for nine years. Most importantly I found a lot of friends. Neither my personal nor my professional life would be what it is today without KDE. I owe a lot to this community. Thank you for the last twenty years.

Friday, 21 August 2015


Update 1: Google Play still not has the newest version, but it is incomming in the following days
Update 2: There is an open beta version now, you can get it from here from Google Play.

Marble Maps has the following features:
  • Wondering around on the map
    • You can move the map with one finger by dragging the map with it
    • It will increase the zoom if you touch double times fast to the map
    • You can also zoom with two fingers (only supported on multitouch devices)
  • Handling your position
    • You can check your position on the map
    • You can check the distance and direction to your position when your position is not visible
    • You can center the view to your position
  • Routing
    • You can plan routes via interactive placemarks, you have to search for something and after that, you can use the result as a waypoint
    • Also, you can modify the route instead of the interactive waypoints with the route editor which is available from the menu

    • To get the routing instructions, visit the menu too
    • You can select from three routing profile: with car, with bike or as a pedestrian
  • Navigation
    • You can navigate on the route what you have planned previously, or you can also navigate to a single destination
    • Marble Maps shows your position on the route with a different icon
    • It provides turn-by-turn based navigation
    • It uses the Text To Speech interface of the Android system to provide voice instructions. To use it, please install it from Google Play
    • It shows the next instruction and its distance too
    • The current speed and the distance to the destination is also visible 

Some techincal background:
Marble's base source code in this summer has become Android compatible. If you want an Android app can be built on the top of it. Any map can be loaded in, and all of the projections are available. It supports some plugins too.




And finally my personal experience about the summer:
I liked to work on this project very much because I have learned a lot of new things, like coding technics, I have got closer to QML and I also have had a deeper insight on how Android applications work. It was also good to work with the people of the community. I would like to thank to everybody who helped me this summer, especially to Dennis Nienhüser and to Torsten Rahn. Without them Marbe on Android would be still a dream.

Thank you Google for this fantastic opportunity!

But the story is not ending here, so stay tuned...