Subscribe to Planet KDE feed
Planet KDE - http://planetKDE.org/
Updated: 19 min 40 sec ago

Kirigami and QtWebEngine in KDE neon

Wed, 08/10/2016 - 10:18

A couple for the developers out there, the lovely new slidy and shiny mobile UI framework Kirigami just got released and packages are available in KDE neon.

And Qt’s new web widget QtWebEngine with Chromium goodness now has packages in neon, will we see a KDE web browser appear again?

Facebooktwittergoogle_pluslinkedinby feather

QReadWriteLock gets faster in Qt 5.7

Wed, 08/10/2016 - 08:55

In Qt 5.0 already, QMutex got revamped to be fast. In the non contended case, locking and unlocking is basically only a simple atomic instruction and it does not allocate memory making it really light. QReadWriteLock however did not get the same optimizations. Now in Qt 5.7, it gets on par with QMutex.

QReadWriteLock

QReadWriteLock's purpose is about the same as the one of QMutex: to protect a critical section. The difference is that QReadWriteLock proposes two different locking modes: read or write. This allows several readers to access the critical section at the same time, and therefore be potentially more efficient than a QMutex. At least that was the intention. But the problem is that, before Qt 5.7, QReadWriteLock's implementation was not as optimized as QMutex. In fact, QReadWriteLock was internally locking and unlocking a QMutex on every call (read or write). So QReadWriteLock was in fact slower than QMutex, unless the read section was held for a very long time, under contention.

For example, the internals of QMetaType were using a QReadWriteLock for the QMetaType database. This makes sense because that database is accessed very often for reading (every time one creates or operates on a QVariant) and very seldom accessed for writing (only when you need to register a new type the first time it is used). However, the QReadWriteLock locking (for read) was so slow that it took a significant amount of time in some QML application that use lots of QVariants, for example with Qt3D.
It was even proposed to replace QReadWriteLock by a QMutex within QMetaType. This would have saved 40% of the time of the QVariant creation. This was not necessary because I improved QReadWriteLock in Qt 5.7 to make it at least as fast as QMutex.

QMutex

QMutex is itself quite efficient already. I described the internals of QMutex in a previous article. Here is a reminder on the important aspects on QMutex:

  • sizeof(QMutex) == sizeof(void*), without any additional allocation.
  • The non-contended case is basically only an atomic operation for lock or unlock
  • In case we need to block, fallback to pthread or native locking primitives
QReadWriteLock in Qt 5.7

I optimized QReadWriteLock to bring it on par with QMutex, using the the same implementation principle.

QReadWriteLock only has one member: a QAtomicPointer named d_ptr. Depending on the value of d_ptr, the lock is in the following state:

  • When d_ptr == 0x0 (all the bits are 0): unlocked and non-recursive. No readers or writers holding nor waiting on it.
  • When d_ptr & 0x1 (the least significant bit is set): one or several readers are currently holding the lock. No writers are waiting and the lock is non-recursive. The amount of readers is (d_ptr >> 4) + 1.
  • When d_ptr == 0x2: we are locked for write and nobody is waiting.
  • In any other case, when the two least significant bits are 0 but the remaining bits contain data, d_ptr points to a QReadWriteLockPrivate object which either means that the lock is recursive, or that it is currently locked and threads are possibly waiting. The QReadWriteLockPrivate has a condition variable allowing to block or wake threads.

In other words, the two least significant bits encode the state. When it is a pointer to a QReadWriteLock, those two bits will always be 0 since pointers must be properly aligned to 32 or 64 bits addresses for the CPU to use them.

This table recap the state depending on the two least significant bits:

if d_ptr is fully 0, then the lock is unlocked. 00If d_ptr is not fully 0, it is pointer to a QReadWriteLockPrivate. 01One or several readers are currently holding the lock. The amount of reader is (d_ptr >> 4) + 1. 10One writer is holding the lock and nobody is waiting

We therefore define a few constants to help us read the code.

enum { StateMask = 0x3, StateLockedForRead = 0x1, StateLockedForWrite = 0x2, }; const auto dummyLockedForRead = reinterpret_cast<QReadWriteLockPrivate *>(quintptr(StateLockedForRead)); const auto dummyLockedForWrite = reinterpret_cast<QReadWriteLockPrivate *>(quintptr(StateLockedForWrite)); inline bool isUncontendedLocked(const QReadWriteLockPrivate *d) { return quintptr(d) & StateMask; }

Aside: The code assumes that the null pointer value is equal to binary 0, which is not guaranteed by the C++ standard, but holds true on every supported platform.

lockForRead

The really fast case happens when there is no contention. If we can atomically swap from 0 to StateLockedForRead, we have the lock and there is nothing to do. If there already are readers, we need to increase the reader count, atomically. If a writer already holds the lock, then we need to block. In order to block, we will assign a QReadWriteLockPrivate and wait on its condition variable. We call QReadWriteLockPrivate::allocate() which will pop an unused QReadWriteLockPrivate from a lock-free stack (or allocates a new one if the stack is empty). Indeed, we can never free any of the QReadWriteLockPrivate as another thread might still hold pointer to it and de-reference it. So when we release a QReadWriteLockPrivate, we put it in a lock-free stack.

lockForRead actually calls tryLockForRead(-1), passing -1 as the timeout means "wait forever until we get the lock".

Here is the slightly edited code. (original)

bool QReadWriteLock::tryLockForRead(int timeout) { // Fast case: non contended: QReadWriteLockPrivate *d; if (d_ptr.testAndSetAcquire(nullptr, dummyLockedForRead, d)) return true; while (true) { if (d == 0) { if (!d_ptr.testAndSetAcquire(nullptr, dummyLockedForRead, d)) continue; return true; } if ((quintptr(d) & StateMask) == StateLockedForRead) { // locked for read, increase the counter const auto val = reinterpret_cast<QReadWriteLockPrivate *>(quintptr(d) + (1U<<4)); if (!d_ptr.testAndSetAcquire(d, val, d)) continue; return true; } if (d == dummyLockedForWrite) { if (!timeout) return false; // locked for write, assign a d_ptr and wait. auto val = QReadWriteLockPrivate::allocate(); val->writerCount = 1; if (!d_ptr.testAndSetOrdered(d, val, d)) { val->writerCount = 0; val->release(); continue; } d = val; } Q_ASSERT(!isUncontendedLocked(d)); // d is an actual pointer; if (d->recursive) return d->recursiveLockForRead(timeout); QMutexLocker lock(&d->mutex); if (d != d_ptr.load()) { // d_ptr has changed: this QReadWriteLock was unlocked before we had // time to lock d->mutex. // We are holding a lock to a mutex within a QReadWriteLockPrivate // that is already released (or even is already re-used). That's ok // because the QFreeList never frees them. // Just unlock d->mutex (at the end of the scope) and retry. d = d_ptr.loadAcquire(); continue; } return d->lockForRead(timeout); } } lockForWrite

Exactly the same principle, as lockForRead but we would also block if there are readers holding the lock.

bool QReadWriteLock::tryLockForWrite(int timeout) { // Fast case: non contended: QReadWriteLockPrivate *d; if (d_ptr.testAndSetAcquire(nullptr, dummyLockedForWrite, d)) return true; while (true) { if (d == 0) { if (!d_ptr.testAndSetAcquire(d, dummyLockedForWrite, d)) continue; return true; } if (isUncontendedLocked(d)) { if (!timeout) return false; // locked for either read or write, assign a d_ptr and wait. auto val = QReadWriteLockPrivate::allocate(); if (d == dummyLockedForWrite) val->writerCount = 1; else val->readerCount = (quintptr(d) >> 4) + 1; if (!d_ptr.testAndSetOrdered(d, val, d)) { val->writerCount = val->readerCount = 0; val->release(); continue; } d = val; } Q_ASSERT(!isUncontendedLocked(d)); // d is an actual pointer; if (d->recursive) return d->recursiveLockForWrite(timeout); QMutexLocker lock(&d->mutex); if (d != d_ptr.load()) { // The mutex was unlocked before we had time to lock the mutex. // We are holding to a mutex within a QReadWriteLockPrivate that is already released // (or even is already re-used) but that's ok because the QFreeList never frees them. d = d_ptr.loadAcquire(); continue; } return d->lockForWrite(timeout); } } unlock

The API has a single unlock for both read and write so we don't know if we are unlocking from reading or writing. Fortunately, we can know that with the state encoded in the lower bits. If we were locked for read, we need to decrease the reader count, or set the state to 0x0 if we are the last one. If we were locked for write we need to set the state to 0x0. If there is a QReadWriteLockPrivate, we need to update the data there, and possibly wake up the blocked threads.

void QReadWriteLock::unlock() { QReadWriteLockPrivate *d = d_ptr.load(); while (true) { Q_ASSERT_X(d, "QReadWriteLock::unlock()", "Cannot unlock an unlocked lock"); // Fast case: no contention: (no waiters, no other readers) if (quintptr(d) <= 2) { // 1 or 2 (StateLockedForRead or StateLockedForWrite) if (!d_ptr.testAndSetRelease(d, nullptr, d)) continue; return; } if ((quintptr(d) & StateMask) == StateLockedForRead) { Q_ASSERT(quintptr(d) > (1U<<4)); //otherwise that would be the fast case // Just decrease the reader's count. auto val = reinterpret_cast<QReadWriteLockPrivate *>(quintptr(d) - (1U<<4)); if (!d_ptr.testAndSetRelease(d, val, d)) continue; return; } Q_ASSERT(!isUncontendedLocked(d)); if (d->recursive) { d->recursiveUnlock(); return; } QMutexLocker locker(&d->mutex); if (d->writerCount) { Q_ASSERT(d->writerCount == 1); Q_ASSERT(d->readerCount == 0); d->writerCount = 0; } else { Q_ASSERT(d->readerCount > 0); d->readerCount--; if (d->readerCount > 0) return; } if (d->waitingReaders || d->waitingWriters) { d->unlock(); } else { Q_ASSERT(d_ptr.load() == d); // should not change when we still hold the mutex d_ptr.storeRelease(nullptr); d->release(); } return; } } Benchmarks

Here is the benchmark that was run: https://codereview.qt-project.org/167113/. The benchmark was run with Qt 5.6.1, GCC 6.1.1. What I call Qt 5.7 bellow is in fact Qt 5.6 + the QReadWriteLock patch so it only compares this patch.

Uncontended

This benchmark compares different types of lock by having a single thread running in a loop 1000000 times, locking and unlocking the mutex and doing nothing else.

QReadWriteLock (Qt 5.6)38 ms███████████████████ QReadWriteLock (Qt 5.7)18 ms█████████ QMutex 16 ms████████ std::mutex 18 ms█████████ std::shared_timed_mutex33 ms████████████████▌ Contented Reads

This benchmark runs as much threads as logical cores (4 in my cases). Each thread will lock and unlock the same mutex 1000000 times. We do a small amount of work inside and outside the lock. If no other work was done at all and the threads were only locking and unlocking, we would have a huge pressure on the mutex but this would not be a fair benchmark. So this benchmark does a hash lookup inside the lock and a string allocation outside of the lock. The more work is done inside the lock, the more we disadvantage QMutex compared to QReadWriteLock because threads would be blocked for longer time.

QReadWriteLock (Qt 5.6)812 ms████████████████████▍ QReadWriteLock (Qt 5.7)285 ms███████▏ QMutex 398 ms██████████ std::mutex 489 ms████████████▎ std::shared_timed_mutex811 ms████████████████████▎ Futex Version

On platforms that have futexes, QMutex does not even need a QMutexPrivate, it uses the futexes to hold the lock. Similarly, we could do the same with QReadWriteLock. I made an implementation of QReadWriteLock using futex (in fact I made it first before the generic version). But it is not in Qt 5.7 and is not yet merged in Qt, perhaps for a future version if I get the motivation and time to get it merged.

Could we get even faster?

As always, nothing is perfect and there is always still room for improvement. A flaw of this implementation is that all the readers still need to perform an atomic write at the same memory location (in order to increment the reader's count). This causes contention if there are many reader threads. For cache performance, we would no want that the readers write to the same memory location. Such implementations are possible and would make the contended case faster, but then would take more memory and might be slower for the non-contended case.

Conclusion

These benchmarks shows the huge improvement in QReadWriteLock in Qt 5.7. The Qt classes have nothing to envy to their libstdc++ implementation. std::shared_timed_mutex which would be the standard equivalent of a QReadWriteLock is surprisingly slow. (I heard rumors that it might get better.)
It is optimized for the usual case of Qt with relatively low contention. It is taking a very small amount of memory and makes it a pretty decent implementation of a read write lock.

In summary, you can now use QReadWriteLock as soon as there are many reads and seldom writes. This is only about non recursive mutex. Recursive mutex are always slower and should be avoided. Not only because they are slower, but it is also harder to reason about them.

I'm here

Tue, 08/09/2016 - 23:38

It's been over a year since I posted anything. That's way too long. So what's going on in the projects I care about lately? Speech-dispatcher will soon have a 0.8.5 release. There's a set of patches in the works on a branch on github that moves the audio to the server so we will be able to do useful things like label each pulse audio output with the client application name rather than a generic sd_espeak, sd_pico name for each output module. This way you'll see stuff like "Konsole speech", "Konversation speech" etc. volume controls for the speech volume control of the application's speech output. In order for this to work some other refactoring needs to be done in the espeak and other modules so stopping audio playback will be immediate etc. QtSpeech has had some work done. The android and windows versions have been seeing some love lately. I'm optimistic that it can be included in an upcoming Qt release. Though I'm not sure why it hasn't been included yet. KMouth has been waiting a QtSpeech release in order for it's kf5/qt5 branch to be merged to master. KNewStuff could use some work. There was talk at a recent conference about adding the properties and such necessary for it to be used from QML. I'll follow up on that and see what has become of it. All in all I feel like I haven't been around as much in the above projects as I'd like to have been. Life is busy and work is busy and such. I plan to spend a bit more time on these though. Even if it means I get slightly less sleep. Looking forward to a good rest of the year.

digiKam 5.1.0 is published...

Tue, 08/09/2016 - 21:29

Dear digiKam fans and users,

After a first release 5.0.0 published one month ago, the digiKam team is proud to announce the new release 5.1.0 of digiKam Software Collection. This version introduces a new huge bugs triage and some fixes following first feedback from end-users.

read more

Opt-in header-only libraries with CMake

Tue, 08/09/2016 - 20:00

Using a C++ library, particularly a 3rd party one, can be complicated affair. Library binaries compiled on Windows/OSX/Linux can not simply be copied over to another platform and used there. Linking works differently, compilers bundle different code into binaries on each platform etc.

This is not an insurmountable problem. Libraries like Qt distribute dynamically compiled binaries for major platforms and other libraries have comparable solutions.

There is a category of libraries which considers the portable binaries issue to be a terminal one. Boost is a widespread source of many ‘header only’ libraries, which don’t require a user to link to a particular platform-compatible library binary. There are also many other examples of such ‘header only’ libraries.

Recently there was a blog post describing an example library which can be built as a shared library, or as a static library, or used directly as a ‘header only’ library which doesn’t require the user to link against anything to use the library. The claim is that it is useful for libraries to provide users the option of using a library as a ‘header only’ library and adding preprocessor magic to make that possible.

However, there is yet a fourth option, and that is for the consumer to compile the source files of the library themselves. This has the
advantage that the .cpp file is not #included into every compilation unit, but still avoids the platform-specific library binary.

I decided to write a CMake buildsystem which would achieve all of that for a library. I don’t have an opinion on whether good idea in general for libraries to do things like this, but if people want to do it, it should be easy as possible.

Additionally, of course, the CMake GenerateExportHeader module should be used, but I didn’t want to change the source from Vittorio so much.

The CMake code below compiles the library in several ways and installs it to a prefix which is suitable for packaging:

cmake_minimum_required(VERSION 3.3) project(example_lib) # define the library set(library_srcs example_lib/library/module0/module0.cpp example_lib/library/module1/module1.cpp ) add_library(library_static STATIC ${library_srcs}) add_library(library_shared SHARED ${library_srcs}) add_library(library_iface INTERFACE) target_compile_definitions(library_iface INTERFACE LIBRARY_HEADER_ONLY ) set(installed_srcs include/example_lib/library/module0/module0.cpp include/example_lib/library/module1/module1.cpp ) add_library(library_srcs INTERFACE) target_sources(library_srcs INTERFACE $<INSTALL_INTERFACE:${installed_srcs}> ) # install and export the library install(DIRECTORY example_lib/library DESTINATION include/example_lib ) install(FILES example_lib/library.hpp example_lib/api.hpp DESTINATION include/example_lib ) install(TARGETS library_static library_shared library_iface library_srcs EXPORT library_targets RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib INCLUDES DESTINATION include ) install(EXPORT library_targets NAMESPACE example_lib:: DESTINATION lib/cmake/example_lib ) install(FILES example_lib-config.cmake DESTINATION lib/cmake/example_lib )

This blog post is not a CMake introduction, so to see what all of those commands are about start with the cmake-buildsystem and cmake-packages documentation.

There are 4 add_library calls. The first two serve the purpose of building the library as a shared library and then as a static library.

The next two are INTERFACE libraries, a concept I introduced in CMake 3.0 when it looked like Boost might use CMake. The INTERFACE target can be used to specify header-only libraries because they specify usage requirements for consumers to use, such as include directories and compile definitions.

The library_iface library functions as described in the blog post from Vittorio, in that users of that library will be built with LIBRARY_HEADER_ONLY and will therefore #include the .cpp files.

The library_srcs library causes the consumer to compile the .cpp files separately.

A consumer of a library like this would then look like:

cmake_minimum_required(VERSION 3.3) project(example_user) find_package(example_lib REQUIRED) add_executable(myexe src/src0.cpp src/src1.cpp src/main.cpp ) ## uncomment only one of these! # target_link_libraries(myexe # example_lib::library_static) # target_link_libraries(myexe # example_lib::library_shared) # target_link_libraries(myexe # example_lib::library_iface) target_link_libraries(myexe example_lib::library_srcs)

So, it is up to the consumer how they consume the library, and they determine that by using target_link_libraries to specify which one they depend on.


Rainbow Folders

Mon, 08/08/2016 - 21:37

Breeze Icons follow the colorscheme that’s not new but now the folder icons also follow the color scheme.

That’s how it look like with the breeze color scheme

breeze

as you can see there is no difference between the old and new folder icons but if you play with different color schemes in the color setting, …

folderIcons

you see there openSUSE, Manjaro, Krita, Ubuntu, Elementary, Arch Dark and any other style you would design by yourself. So don’t stop playing with your plasma desktop, it’s designed for your flavor.


My experiences with SOCIS 2016

Mon, 08/08/2016 - 16:00



Hello dear readers!

This post is a small synopsis of my experiences so far as a student in this years Summer of Code in Space, where I shall recount the whole adventure of integrating Sentinel-2 data into Marble Virtual Globe.

Sentinel-2 data.So what exactly is this data, and why is it important to us? Well, Copernicus is the worlds largest single earth observation programme directed by the European Commission in partnership with the European Space Agency (ESA). ESA is currently developing seven missions under the Sentinel programme. Among these is Sentinel-2, which provides high-resolution optical images, which  is on one hand of interest to the users of Marble and the scientific community as a whole.
Our goal with this years SOCIS was to adapt this data into Marble. Since Marble has quite the track record of being used in third party applications with great success, this would essentially be a gateway for many developers to get easy access to high quality images through the Marble library.So first order of business? Adapt the world. The summer has begun to get exciting. First Acquaintance with Marble   Of course, nothing can happen so quickly, and the first task was obviously on a smaller scale. In order to familiarize me with the inner workings of Marble, my mentor gave me a task to adapt an already available dataset into a map theme for Marble. This is how I came to know TopOSM.

The TopOSM maptheme in Marble.
This task came with its own fair share of challenges, from getting Marble to display the legend icons correctly, to creating a suitable level 0 tile, but in the end it did give an insight into exactly how the creation of a map theme, from the first steps to uploading goes. At this point, the challenge was underway, and so began the real part of our ambitious project to tackle the whole world through Sentinel-2's lens and integrate it into Marble.Sentinel-2 - From drawing board to tilerenderingAfter many discussions with my mentor, regarding ideas on how to make the data suitable for use in Marble, we finally came up with a plan. That plan would let us use the currently available Data Hub as a source for our images (since we don’t have a simple server we could just get the data from, as in the case of TopOSM). At that point, we just have to edit these images into a suitable format, and everything will be fine. A three step process:Step 1. Download some data.Step 2. Edit it.Step 3. Use it in Marble.As you may have guessed, step 2. was to be troublesome. Around this time my mentor came up with the first iteration of the guide for this “three-step” process. We also found an application that would suit our needs for the editing, this was to be QGIS, but we would also be using GDAL.The now mostly finalized guide can be found here, however here are the original steps:Step 1. Find some suitable (has few clouds, isn’t very dark, etc.) data on the Data Hub, and download it.

The Data Hub.
This step was to be the least troublesome, since what do you need? A good internet connection (check?), and hard drive space, since each dataset we download is about 4-7 gigabytes (also check). The only problem was the downloads seemed to fail, without warning or rhyme, or reason. One could move the mouse constantly, and it might fail, one could leave the computer unattended and the same thing would happen, even though the last 5 datasets were downloaded without fail. It was quite a mystery, but thankfully the browser could restart the download (after refreshing the page and logging in again to make sure). Another helpful site was an archive, where some of the more recent datasets were uploaded. These could be easily downloaded with wget without any issues, so the troublesome downloading (the Data Hub only allows two concurrent downloads at a time) was more or less solved.
Step 2.  Edit the data.

Here's how a few tilesets look when loaded, after you applied the styles.
So you finally downloaded your first dataset, the first thing you’re going to have to do, is run a small script that generates vrt files from the images. These will then be loaded up in QGIS, where you’ll need to apply a style to them (that’s right click on each layer, load style, and navigate to the style file. At first, adding these numbers stored in the style file was done by hand). Thankfully you can only do that to the first one, and then copy it to the rest of them. Even with hotkeys, that’s about 10 – 16 styles to apply. But now, you can save your images in tif format! Just right click, save as, apply the correct settings, and…wait 1 to 4 minutes while it generates. Now do that all again for the other 15 layers. And all the other datasets.As any reader may have felt profound despair at this point, so did I. My mentor most likely as well, as we both, very rightly, felt that there had to be a better, faster, more efficient way.Who knew that the whole solution for all this would be a script?So from then out, I was knee deep in the documentation to find exactly which classes store file-saving settings in QGis (hint: it’s this one). Applying the style was something I’ve seen used in plugins, so that was a good stepping stone. A second great discovery was the fact that QGIS provides an easy way to generate the query window (so I didn’t have to meddle with the appearance, just finding the relevant settings in the documentation) through the processing toolbox. So much easier.Soon, the first version of the script was ready: Load the vrts in QGIS, open the script window, select where you want to save it, and which styles you want to use, and presto. An hour later you might be done (with that dataset. Onto the next!). My mentor was quite happy with the fact that you didn’t have to sit there and apply settings every 1 to 4 minutes, instead just once every half an hour or so (to load the next batch up). The sky, or in this case processing power of your computer, was the limit.
The last step in editing involves the creation of the actual slippy map tiles. Thankfully, that was already available in QGIS plugin (QTiles), so we didn’t have to find another way to make that. Tile creation however is a very slow process (it takes more than a day to process about 10 datasets), so this step is still a bit problematic. Even splitting the project into smaller sections doesn’t do much speedwise, but it’s fairly reasonable: there are 15 levels we need to create, with level 0 being a single image of the entire Earth, level 1 being four images, level 2 being those four split into 4 again, and you can soon see that at level 14, there are manytiles being generated. Such as it is.
Step 3. Upload and use the tiles in Marble.This step is fairly obvious, you need to upload your freshly generated tiles onto the Marble servers, and soon you will be able the see the fruits of your labour with your own eyes. As of this post, more than 70 tilesets have been generated anduploaded, but there’s still a long way to go.ConcludingFor now I’m just glad to say that I’ve had a wonderful experience this summer here at Marble, by having helpful mentors around who welcomed me into the community, heard all my issues and tried to support me whenever I got stuck. Overall I’m really happy that I took part, because I learned a lot about communication, project management, problem solving, both on my own, and with help. Of course, this is just the beginning of everything, and I hope to become much more productive and helpful in the future. As for everyone, I wish you all a great summer and many great experiences to you all.

Qt Creator 4.1 RC1 released

Mon, 08/08/2016 - 10:06

We are pleased to announce the release of Qt Creator 4.1.0 RC1.

Read the beta blog post for an overview of the new features coming in the 4.1 release. Since then we have been fixing bugs and polishing the new features. We believe that what we have now is very close to what we can release as the final 4.1 release soon.

A few visual improvements that happened since the Beta are the addition of the dark and light Solarized editor color schemes, a new “Qt Creator Dark” editor color scheme as companion for the new Flat Dark theme and the polishing of the new Flat Dark and Flat Light themes.

See some items of the above list in action:
Flat Dark Theme - Qt Creator 4.1Flat Light Theme - Qt Creator 4.1

Now is the best time to head over to our download page or the Qt Account Portal, get and install the RC and give us your feedback, preferably through our bug tracker. You also find us on IRC on #qt-creator on chat.freenode.net, and on the Qt Creator mailing list.

Known issue #1
Unfortunately, an incompatibility between MSVC 2015 Update 3 and Clang 3.8 causes an issue with the Clang Static Analyzer plugin. We will try to iron this out until the final release.

Known issue #2
The changes-4.1.0 file in the source package does not contain what happened (and who additionally contributed) between 4.1.0-beta1 and this 4.1.0-rc1. Here is the updated changes-4.1.0.md

The post Qt Creator 4.1 RC1 released appeared first on Qt Blog.

GCompris release 0.61 and reoganization

Sun, 08/07/2016 - 21:43

Some of you are aware that I (Bruno) have a new “day” job and I don’t have time anymore to be active on GCompris. I created this project in 2000 and maintain it since then. So this release note is important to me because it will also be my last one. From now on, the releases will be handled by Johnny Jazeix.

As I cannot be active anymore, it would not make sense to continue selling GCompris. After investigating several options and in accordance with the most active members in our community, I decided to transfer the business operation to Timothée Giet. Timothée is a graphic artist with a long list of contributions on GCompris and in the KDE community. For now, all sales go to Timothée and he is in charge of the commercial support. There are no changes in the licensing nor in the development process which is still under the responsibility of the KDE community (Johnny Jazeix being the most active contributor).

r0-61-smallConcerning the release notes, the new activities are:

  • A simple wordprocessor (baby_word_processor by Bruno Coudoin), this activity is not available on mobile platforms due to issues with the virtual keyboard: if we only use the real keyboard, styles don’t apply and if we only use the virtual keyboard, we can’t navigate in the text, select it…
  • A tangram (by Bruno Coudoin). It starts with children friendly levels to introduce each concepts little by little and end up in the real tangram.
  • Explore the monuments of the world (explore_monuments by Ayush Agrawal during SoK).
  • An activity in which the children must color a graph so that no two adjacent nodes have the same color (graph_coloring by Akshat Tandon during SoK).
  • Pilot the spaceship towards the green landing area (land_safe by Holger Kaelberer).
  • Find the differences between the two pictures (photo_hunter by Stefan Toncu).

 

middlegcomprislogo

Timothée Giet updated images for chess, hangman and horizontal/vertical reading activities along with the gcompris logo.

 

Lots of little fixes/improvements have been done (storing and restoring the window’s width/height at start-up, docbook updated, levels/images bonus, adding an internal dataset for words games so that we no more expect the network to run GCompris (except for the voices but they also can be bundled in the binary).

On translation side, we have 17 languages fully supported: Belarusian, British English, Brazilian Portuguese, Catalan, Catalan (Valencian), Chinese Simplified, Dutch, French, Galician, Italian, Norwegian Nynorsk, Polish, Portuguese, Romanian, Spanish, Swedish, Ukrainian and some partially: Breton (88%), Chinese Traditional (97%), Estonian (82%), Finnish (74%), German (93%), Russian (83%), Slovak (76%), Slovenian (82%), Turkish (82%)

If you want to help, please make some posts in your community about GCompris.

The source code tarball is available here (GNU/Linux packagers are welcome)


Some details about Qt properties system

Sun, 08/07/2016 - 18:18

As I promised, in this post I shall tell you about some details of Qt properties system. Most probably, you’ll find it useful if you are only familiar but haven’t used Qt properties much in your code yet. Using them is a good way to start integrating your application to QtQuick, where, as far as I know, Qt properties are mostly used. Correct me, if I’m not accurate. I shan’t explain you what Qt properties are, so if you don’t know about them, you may want to read the following article: http://doc.qt.io/qt-5/properties.html. This post actually will be quite short.

Investigating archive operations

Sun, 08/07/2016 - 17:23

In this post I’m going to tell you about some advanced using of terminal utilities for zip, 7z and rar archive types. It’ll cover the following operations: add files to specific folder in archive, move or rename files and copy files within archive. There will be described both solutions with using only classic command line programs for mentioned archive formats and programmed workarounds for solving the problems, if those tools are inefficient.

Time flies for FBSD updates, too

Sun, 08/07/2016 - 10:16

So it’s been some time since I last wrote something about the KDE-FreeBSD ports. Time flies when you’re having fun (in my case, that means biccling around Zeeland and camping). In the meantime, Ralf has been hammering on the various Qt ports updates that need to be done — official ports are still Qt 5.5.1, but we have 5.6 done and 5.7 on the way. Tobias has been watching over the plasma5 branch of the unofficial ports, so that it’s up-to-date with KDE Frameworks, Plasma and Applications.

The older KDE stuff — that is, KDE4, which is still the current official release for the desktop on FreeBSD — is also maintained, although (obviously) not much changes there. We did run into a neat C++-exceptions bug recently, which was kind of hard to trigger: running k3b (or ksoundconverter and some other similar ones) with a CD that is unknown to MusicBrainz would crash k3b. There’s not that many commercially-available CDs unknown to that database, so I initially brushed off the bug report as Works For Me.

Good thing Methyl Ethel is still relatively obscure (but a nice band to listen to). They trigger the crash, too.

At issue is the visibility of C++ exception symbols; when -fvisibility=hidden is used and C++ exceptions are thrown out of a shared object, then users of that shared object may not catch the exceptions. Making exception classes explicitly visible fixes the problem — which in our case was because libkcddb catches exceptions from MusicBrainz, except when -fvisibility=hidden is used in linking and executable that uses libkcddb and libmusicbrainz5, in which case the exception isn’t caught and ends up crashing the application.

https://gcc.gnu.org/wiki/Visibility has been very useful in sorting this bug out. After Tobias identified the exceptions as the root cause, I played with code across the shared-object-dependency chain until I came up with a patch which I’ve proposed upstream (e.g. libmusicbrainz5) and in the packaging for FreeBSD.

Even older software sometimes shows interesting bugs. And time flies when you’re having fun, but also when tracking down unhandled exceptions.

QRPC: A Qt remoting library

Sun, 08/07/2016 - 09:42

This project of mine has been around for quite a while already. I’ve never much publicised it, however, and for the past year the code hasn’t seen any changes (until a few days ago, anyway). But related to my current job, I’ve found a new need for remote procedure calls, so I came back to the code after all.

QRPC is a remoting library tightly integrated with Qt: in simplified terms, it’s an easy way to get signal-slot connections over the network. At least that was its original intention, and hence comes the name (QRPC as in “Qt Remote Procedure Call”).

But actually, it’s a little more than that. QRPC pipes the whole of Qt’s meta-object functionality over a given transport. That can be a network socket, unix domain socket or something more high-level like ZeroMQ. But it could, for example, also be a serial port (not sure why anybody would want that, though).
The actual remoting system works as follows: A server marks some objects for “export”, meaning they will be accessible by clients. Clients can then request any such object by its identifier. The server then serialises the whole QMetaObject hierarchy of the exported object and sends it to the client. There, it is reconstructed and used as the dynamic QMetaObject of a specialised QObject. Thus, the client not only has access to signals and slots, but also to properties and Q_CLASSINFOs (actually anything that a QMetaObject has to offer). The property support also includes dynamic properties, not only the statically defined QMetaProperties.
Method invocations, signal emissions and property changes are serialised and sent over the transport – after all, a QMetaObject without the dynamics isn’t that useful ;).

To give an impression of how QRPC is used, here’s an excerpt from the example included in the repository:

Server:

Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget), localServer(new QLocalServer(this)), exporter(new QRPCObjectExporter(this)) { ui->setupUi(this); // Export the QSpinBox with the identifier "spinbox". exporter->exportObject("spinbox", ui->spinBox); // Handle new connections, serve under the name "qrpcsimpleserver". connect(localServer, &QLocalServer::newConnection, this, &Widget::handleNewConnection); localServer->listen("qrpcsimpleserver"); } void Widget::handleNewConnection() { // Get the connection socket QLocalSocket *socket = localServer->nextPendingConnection(); // Create a transport... QRPCIODeviceTransport *transport = new QRPCIODeviceTransport(socket, socket); // ... and the server communicating over the transport, serving objects exported from the // exporter. Both the transport and the server are children of the socket so they get // properly cleaned up. new QRPCServer(exporter, transport, socket); }

Client:

Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget), socket(new QLocalSocket(this)), rpcClient(0) { // ... // Connect to the server on button click connect(ui->connect, &QPushButton::clicked, [this]() { socket->connectToServer("qrpcsimpleserver"); }); // Handle connection events connect(socket, &QLocalSocket::connected, this, &Widget::connectionEstablished); connect(socket, &QLocalSocket::disconnected, this, &Widget::connectionLost); } void Widget::connectionEstablished() { // Create a transport... QRPCIODeviceTransport *transport = new QRPCIODeviceTransport(socket, this); // ... and a client communicating over the transport. QRPCClient *client = new QRPCClient(transport, this); // When we receive a remote object (in this example, it can only be the spinbox), // synchronise the state and connect the slider to it. connect(client, &QRPCClient::remoteObjectReady, [this](QRPCObject *object) { ui->horizontalSlider->setValue(object->property("value").toInt()); ui->horizontalSlider->setMinimum(object->property("minimum").toInt()); ui->horizontalSlider->setMaximum(object->property("maximum").toInt()); connect(ui->horizontalSlider, SIGNAL(valueChanged(int)), object, SLOT(setValue(int))); }); // Request the spinbox. client->requestRemoteObject("spinbox"); // Clean up when we lose the connection. connect(socket, &QLocalSocket::disconnected, client, &QObject::deleteLater); connect(socket, &QLocalSocket::disconnected, transport, &QObject::deleteLater); // ... }

Argument or property types have to be registered metatypes (same as when using queued connections) and serialisable with QDataStream. The QDataStream operators also have to be registered with Qt’s meta type system (cf. QMetaType docs).
At the moment, one shortcoming is that references to QObjects (i.e. “QObject*”) can’t be transferred over the network, even if the relevant QObjects are “exported” by the server. Part of the problem is that Qt doesn’t allow us to register custom stream operators for “QObject*”. This could be solved by manually traversing the serialised values, but that will negatively impact the performance. Usually one can work around that limitation, though.

Furthermore, method return values are intentionally not supported. Supporting them would first require a more complex system to keep track of state and secondly impose blocking method invocations, both of which run contrary to my design goals.

In some final remarks, I’d like to point out two similar projects: For one, there’s QtRemoteObjects in Qt’s playground which works quite similarly to QRPC. I began working on QRPC at around the same time as QtRemoteObjects was started and I didn’t know it existed until quite some time later. Having glanced over its source code, I find it to be a little too complex and doing too much for my needs without offering the same flexibility (like custom transports). I must admit that I haven’t checked it out in more detail, though.
Then there’s also QtWebChannel which again offers much of the metaobject functionality over the web, but this time specifically geared towards JavaScript/HTML5 clients and Web apps. I thought about reusing part of its code, but ultimately its focus on JS was too strong to make this a viable path.

Tip of the iceberg !

Sat, 08/06/2016 - 14:50

So we have previously seen how Davide, Alessandro and I designed the Rating Engine for our  WikiRating:Google Summer of Code project. Now this is the time for our last step , that is to connect the engine to the Website for displaying the computed results and for providing voting functionality to WikiToLearn users.

In MediaWiki additional functionalities like this are added via extensions. You can think of extensions in the literal sense too as something that provides some extension points on the top of the current code base. This make the life of developers easier since by using extensions we can add new code in a modular fashion and thereby not much fiddling with the Wiki code base.

So now I needed to write an extension that can the following:

  • Fetch the information about the page being viewed by the user.
  • Allowing the user to vote for the page.
  • Displaying additional information about the page is user demands.

So with the following things in mind I began to analyse the basic components of a MediaWiki Extension.

extension_components

So besides the boiler plate components that required minor tweaking extension.json , modules , specials are of our interest.

extension.json

extension_JSON

This JSON file stores the setup instructions for instance name of the extension, the author, what all classes to load etc.

modules

module_pic

The module folder of our WikiRating Extension contains these 2 components:

  • resources: where all the images and other resources are stored.
  • wikiRating.js: A java script file to fetch, send and display data between the engine and the Website instance.

It is the wikiRating.js script where we wrote most of our code.

specials

specials

This folder contains a php script whose function is display additional information about the page when asked for. The information will be passed to the script via the URL parameter by our master script (wikiRating.js).

So the final step(or first step !) is to enable our extension by adding this to LocalSettings.php file in the WikiToLearn local instance.

wfLoadExtension( 'WikiRating' );

So now it is the time to see the fruits of our labour:

score1Basic information about the page score2Additional information about the page 

So this is how the output of our engine looks , subtle like a tip of an iceberg😛

 


[GSoC] KDev-Embedded, OpenOCD and avrdude

Fri, 08/05/2016 - 18:15

KDev-Embedded  now have OpenOCD integration and a new interface to use avrdude in launcher.

With Arduino-Makefile, it's possible to use a makefile to perform compilation of Arduino projects. In the video one the the examples are used to shows how it is possible to use the new avrdude launcher to execute the upload process.

http://patrickjp.com/wp-content/uploads/2016/08/arduino1.mp4

In the avrdude new … Read the rest

Kontact build dependencies

Fri, 08/05/2016 - 12:45

kde pim

Adding KDE PIM to KDE neon I wondered if it really was as complex to build as it felt.  So I mapped them in Graphviz, and yep, it really is complex to build.  I’m quite amazed at the coders who work on this stuff, it’s an impressive beast.

Facebooktwittergoogle_pluslinkedinby feather

boot 25 % faster

Thu, 08/04/2016 - 19:46

My machine isn’t that fast, but I can improve the boot time for the plasma desktop up to 25%.

How, it’s simple turn of ksplash.

from plymouth to ksplash to the plasma desktop (movie)  8 sec plymouth (linux boot time) 11 sec ksplash 4 sec desktop is finished ===================== 23 sec (1/3 for linux 2/3 for plasma) from plymouth to the plasma desktop (movie) 8 sec plymouth (linux boot time) 11 sec desktop is finished ===================== 19 sec (42% for linux 58% for plasma)

So with ksplash the computer need 15 sec to start plasma without it need 11 sec (-27 %) but the god thing is that it looks even faster cause I see plasma instantly after the login and as you can see in the lined movies the desktop flickering is also visible with ksplash. To be honest I like the deskop flickering, cause I see how plasma work.


WIP: Plasma World Map Wallpaper & World Clock Applet, powered by Marble

Thu, 08/04/2016 - 17:18

The core of Marble, the virtual globe and world atlas, is a library, intended for reuse. Next to exposing its native C++ interface (see API dox of development version of the Marble library), there is also the option to use it in a QtQuick variant.

The Marble code repository itself holds a few application and tools based on the library. Additionally it also has extensions & plugins for other applications & workspaces, like the KIO thumbnailer plugins for previews of KML, GPX & Co. in KIO-using file manager or file dialogs, a Plasma Runner plugin for looking up geo coordinates or a world clock Plasma applet.

Moving to Plasma5, Marble KRunner plugin arrives first

Having extensions for external applications & workspaces in your repo requires yourself to keep up-to-date with those externals. When Plasma5 appeared with the big switch to QML-only plugin architecture, that left the Marble-based plugins a little behind for now.

Good news is that the KRunner/Plasma Runner plugin was not affected by that, and with Applications 16.08 and the new Marble release will now also be out in a version working in all locales.

Reviving the Marble world clock plasmoid from 2009

The Marble world clock plasmoid, introduced already in 2009 (see bottom of page), though needs a full rewrite, from C++ to QML, which is a bigger undertaking. It also needs a port from KTimeZone & KTimeZoneWidget to QTimeZone, and in that course a cleanup of the mapping between time zones to geocoordinates.

Good news here is that some initial work has been done now and is up for review. A lot of the features are still missing, and there are some glitches (e.g. vertical offset, license info displayed). But it is a start, and the current state might be even fancy enough for some users already:)

It is a short mutation from a Plasma Applet to a Plasma Wallpaper

With the applet initially working, the idea came to have the map also shown fullscreen as wallpaper. While I could not find documentation how to do a wallpaper plugin, the existing code and examples though gave enough hints, and one hour later there was the first incarnation of a Marble-powered Plasma Wallpaper plugin.

See here a screenshot with both the World Map Wallpaper and the World Clock Applet in their current state:
Plasma World Map wallpaper & world clock applet, powered by Marble

Tell what kind of world maps you want to see as wallpaper

Because the World Map wallpaper can make full use of all Marble plugins, a lot of different kind of setups are possible:

  • Plain political map view
  • Globe view with stars in the background
  • Map view of just a continent/country
  • Satellite-photos-based view with live cloud rendering

There could be also plugin variants for the Moon, Venus or Mars.

So start Marble, play around with the settings to learn what is possible. Then tell in the comments what other kind of maps (or globe views) you would like to use for a wallpaper, so we could consider them as predefined settings at least.

Create your own Plasma Wallpaper quickly by a new template

BTW, if you have other fancy ideas for Plasma “Wallpapers”, as by-product I did a template for Plasma Wallpaper plugins. It is currently up for review, so hopefully will be part of future KF5 Plasma frameworks releases. With that template, your first own wallpaper plugin is just a few clicks away e.g. in KAppTemplate or KDevelop.
When playing around with the settings, be aware there might be at least the issue of the wallpaper config page not reading current/default settings when switching the wallpaper type. As workaround one, after switching the wallpaper type, first has to close and reopen the dialog to be able to adjust the settings of the new wallpaper type.


Choqok 1.6 Beta 2 released

Thu, 08/04/2016 - 09:13

We are happy to announce a new upcoming release for Choqok after more than one year and half. We want to make this release more stable than ever and then we are going to release a beta today and the final version next month. Big news about this release is that Choqok is now based…

Pages