Ivan Čukić

RSI and a peculiar development setup contd.

RSI (Repetitive strain injury) is not an uncommon disorder in the geek world. It can range from a slight tiredness to a very unpleasant pain.

I don’t know how it should really be treated, but I know two things – it should not be ignored, and you should not, when you stop ignoring it, try to relax and rest your fingers by playing guitar after not playing it for more than a year. Air guitar should be fine if you don’t overdo it. :)

One of the first things I started doing as a precaution was to switch the mouse hand every once in a while, and to lessen the number of clicks by making a no-click application launcher.

The last step I took was a few days ago. Mainly because this summer is going to be very stressful for my hands, and my fingers don’t seem up to it at the moment. The last step was to remove the resistance of the keys on my keyboard. That is, to replace the keyboard with something else.

RSIstop

As you can see, I have replaced it with a virtual one (xvkbd) running on the exopc tablet under plasma active. It controls my main computer.

I expected it to be quite a productivity killer at first, but it turned out to be quite a pleasant exercise both for my hands (different motions, no resistance) and by mind (thinking of the shortest way to type a variable name by using the fuzzy completion of the vim’s YouCompleteMe plugin – haven’t typed more than three letters per variable in a whole day).

All in all, a rather fun setup. The only issue I’m having is that xvkbd is not meant for multi-touch so if somebody knows of a full-qwerty+special keys virtual keyboard that can be shown on one display and control a different one, I’d be much obliged.

Singletons, shared instances, the modern way

The last post showed how to create a modern and safe d-ptr (pimpl) idiom. There were a few questions regarding the purpose of such a thing, when you can directly use std::unique_ptr or QScopedPointer. The main reason is that it provides additional safeguards from abuse by making the interface minimal. Most importantly, it does not provide an interface to get the raw pointer. (note: it does, but if you are able and want to write something like delete d.operator->() who am I to stop you)

Today, we’ll talk about something evil – singletons. Or, more precisely, the lesser evil brother of a singleton that lasts only while someone holds a pointer to it. Again, it is not something that is difficult to implement, even in old C++, but thanks to the new smart pointers of C++11 it starts to be more elegant.

template <typename Target>
class shared_singleton {
public:
    static std::shared_ptr<Target> instance()
    {
        auto ptr = s_instance.lock();
 
        if (!ptr) {
            ptr = std::make_shared<Target>();
            s_instance = ptr;
        }
 
        return ptr;
    }
 
private:
    static std::weak_ptr<Target> s_instance;
};
 
template <typename Target>
std::weak_ptr<Target> shared_singleton<Target>::s_instance;

There’s room for improvement (thread safety, interface), but it works quite well as it is.

And yes, I’m aware that it can be done with Qt’s pointer classes, or QShared* ones. :)

Splashed across plasma

In order to have an elegant way of switching plasma shells at runtime, we need to hide the process from the user. Is there a nicer way of doing that than showing a pretty splash screen on top of everything? (this is a rhetoric question – don’t answer, it has already been decided)

:)

This is aimed at Plasma Workspaces 2 and is pure Qt5/QML2 thingie. It will also be used as a base for the future versions of KSplashQML (aka TSP).

Here’s the obligatory looped gif showing what it looks like.

splash

D-Ptr, the modern way

The KDE libraries (and some other parts as well) require that the code uses the so called d-pointer or pimpl (private implementation) idiom (see [1] and [2]). It makes it easier to keep the ABI unchanged, and it speeds up the compilation with insignificant runtime costs.

It usually goes like this – declare a Private class and a const pointer to it named d and (de)initialize it properly. Instead of having private class members, put them in that class. [2]

-- .h -------------------

class MyClass {
    :::
private:
    class Private;
    Private * const d;
};

-- .cpp -----------------

class MyClass::Private { ::: };

MyClass::MyClass()
    : d(new Private())
{
    d->name = "I'm a private class member to replace m_name :)";
}

MyClass::~MyClass()
{
    delete d;
}

-------------------------

This works. But having explicit new and delete operators is generally frowned upon in the modern C++ world. It is quite easy to forget to add the delete d to the destructor. And it is nothing more than unnecessary boilerplate. The example at [1] improves this situation by using the QScopedPointer which automatically does the deletion for you.

With the new C++11 features (these are available since gcc 4.4), this can be made even cleaner.

.h ----------------------

class MyClass {
    :::
private:
    class Private;
    d_ptr<Private> d;
};
.cpp ----------------------------

class MyClass::Private { ::: };

MyClass::MyClass()
{
}

MyClass::~MyClass()
{
}

No special handling of d, no new and no delete. Even if the Private class had a constructor with arguments, the implementation would be pretty:

.h ----------------------

class MyClass {
    :::
private:
    class Private;
    d_ptr<Private> d;
};
.cpp ----------------------------

class MyClass::Private {
    
    Private(t1 arg1, t2 arg2)
    { ::: }
};

MyClass::MyClass()
    : d(arg1, arg2)
{
}

MyClass::~MyClass()
{
}

For the implementation of d_ptr class, you can see the d_ptr.h and d_ptr_implementation.h from kactivities repo [3].

Now, the code is perfectly safe. If you make a mistake, it will be detected by the compiler, and will not propagate to runtime.

[1] Library_Code_Policy:D-Pointers
[2] Binary Compatibility Issues With C++
[3] kde:kactivities

Writing a KWin effect in CoffeeScript

If you realize you don’t like JavaScript as much as everybody around you seems to, but still want to write platform-independent KWin scripts or effects, you can try out its most promising alternative – CoffeeScript

The code below creates a KWin effect that fades and zooms in the windows when a user switches the activities.

Edit: Fixed a small bug. Now it works quite well!

# Martin G. likes defining variables in a namespace,
# so we are not going to make him angry - 
# we are creating a namespace that has only one
# variable in it - the duration

activitySwitchEffect =
    duration: animationTime(250)

# We don't really need anything else in the namespace
# for this simple example since we are about to abuse
# lambdas (aka anonymous functions) all over the place.

# We are connecting our function to the
# currentActivityChanged signal, and processing
# all the main windows we can find

effects.currentActivityChanged.connect (activity) ->
    effects.stackingOrder.map (client) ->
        if (activity in client.activities && client.visible)

            # If the client should be shown in
            # the current activity, we are starting
            # the animations - one to fade the window in
            # and another to scale it.

            animate(
                window: client
                animations: [
                    type:     Effect.Opacity
                    duration: activitySwitchEffect.duration
                    from:     0
                    to:       1
                ]
            )

            animate(
                window: client
                animations: [
                    type:     Effect.Scale
                    duration: activitySwitchEffect.duration
                    curve:    QEasingCurve.OutCubic
                    from:     0
                ]
            )

# And that's it!

Mind that this is only for demonstration – it has a few bugs in it :)

A peculiar development setup

I always liked to keep the things clean, so the idea of having development environments for both KDE SC 4.x and KF5 on the same machine was not something that thrilled me. Apart from that, when I realized my versions of mesa+xcb are crashing the new plasma, I decided to go to the other side – the weird side.

My laptop is now dedicated to the new plasma developments, while my main system remains on the 4.x branch.

My Setup

The problem is that the laptop is much slower than my main machine, has a small screen and keyboard which makes writing code on it painful. That is why I don’t use it directly – I work on my main system, while everything executes on the little guy. Everything, but compilation. Thankfully, the icecream distributed compilation system works without a glitch on any distribution although it was created by opensuse KDE people (kudos!).

I have to say that this is perfect – I can crash anything ranging from kded to kwin and plasma without interrupting my workflow, and can test plasma on a slower device so that I don’t introduce some big performance issues that I wouldn’t even notice on a real computer.

Whatever you want, whatever you like

There are some news in the Plasma, Lancelot, Shelf, QML components, blah blah whoop whoop land. As some of the people have noticed from the previous screenshots, I’ve begun working on a QML port of Lancelot.

The Launcher building toolkit

In Lancelot 1, I decided that it would be awesome to allow people to put parts of it on the desktop or panel or wherever even without using the Lancelot menu. Those were implemented as the Shelf (formerly known as Lancelot Parts) applet.

This time, for what will be known as Lancelot 2 I decided to go one step further – to break everything into QML components, be it data models or UI elements.

Lancelot UI Components

Now, you need only a few lines of QML to replicate the same functionality of the Shelf applet (the first column in the screenshot). The second is essentially the same, but uses the IconView.

LancelotComponents.ListView {
    modelsList: [
        LancelotModels.FavoriteApplications {},
        LancelotModels.ContactsTelepathy {},
        LancelotModels.Devices {}
    ]
}

You don’t need to stop there – you can create custom widgets and pass custom delegates (third column), custom item views (all the models have the same API) etc.

Lancelot specific

The menu itself is also going to be as changeable as possible – now that the UI is based on QML, the users will be able to create different layouts, and share them on the kde-look.org. So, for anyone who desired a simpler menu, a menu that shows the items in a grid of icons, and not in a list, for anyone who … I can only say – it will be possible.

It will even be possible to create a telepathy quick-send-message applet if you want to.

Maybe even the April 1st joke from a few years ago will be a fair game.

Lancelot - Raptor Mode

Activities need a volunteer or two

Good day everyone. I need a brave soul (or two) who have the guts to add a long-standing missing feature to the Activities system …

THE UNIT TESTING FRAMEWORK

… I know, I know. It is far from being a thrilling work, but everyone would benefit from it.

I’ve started introducing asserts all over the code to make it more predictable and tested at runtime, but that is not enough. Asserts are there to check whether somebody is abusing kactivitymanagerd, while unit testing will be for when we (whoever works on kamd) are using some methods in a wrong fashion.

Glow with the power of Awesome

Marco announced a new version (rework) of the Air theme for Plasma.

That reminded me of the fact I forgot to blog about the new version of Slim Glow that will be in 4.10.

The most noticeable change is that the system tray icons, share-like-connect icons, and others are now based on the awesome Font Awesome by Dave Gandy (http://fortawesome.github.com/Font-Awesome)

The second is that it is now even slimmer. The desktop widgets have smaller border, especially those like the folder view.

The theme is now again a regular citizen of kde-look.org. Since the non-default themes were moved from standard installations into kdegraphics module, I started receiving requests to make the theme available through the Get Hot New Stuff since rarely anyone wants to install kdegraphics kdeartwork. I understood the desire for this, so I complied.

Welcome to the family [Activities, Apps, SLC]

You say you want a revolution
Well, you know
We all want to change the world
You tell me that it’s evolution
Well, you know
We all want to change the world

~ The Beatles (John Lennon)

Calligra-SLC

I don’t know whether it is revolution, or evolution, but my favourite ideas that the Plasma team thought of a long time ago are finally getting to the users.

It is quite nice to see the positive experiences with the activities system in Plasma 4.9 all around the web. And that was just the tip of the iceberg. There are a few nice things coming to the following release.

The top feature for me is going to be the Share-Like-Connect applet, and the document scoring based on the usage. Lately, I’ve been on a patching spree to increase the number of applications that support activities and the number has increased substantially. Currently, these are the supported applications:

  • Dolphin
  • Gwenview
  • Kate and KWrite
  • Okular
  • Words, Stage and the rest of the Calligra family (except for Kexi which will be patched soon)
  • GVim

I plan to add a few applications to this list before the hard feature freeze slaps me in the face.

Thankfully, I’m not alone in this endeavour. (Edit: added the link for the following text) Tomaz Canabrava’s army of students are going through KDE’s extragear and doing the same thing I’m doing in integral parts of KDE SC. This really offloads a lot of work off my shoulders so big kudos to them!

Activities Settings