Ivan Čukić

All is well that ends^Wstarts well

The summer is over, but we are only at the beginning of the wonderful Plasma2/KF5 voyage. So, what did I do so far, you ask?

A few things.

Shell switching

For some reason, I always start singing “Shell switching with my two favourite allies” when I get to think about this new Plasma mechanism.

This was the main part of my project for the summer – making the infrastructure to let Plasma adapt itself based on the environment it is running in. For the details on this, check out “Switching the Plasma Shells” post.

The main, and most fun side-effect of this work is that from now on, any QML-based application is able to access the hardware information provided by the uber-awesome Solid library, while it got even more hardware support – namely, it now detects the input devices under udev-based systems.

Activities for the new age

Porting KActivities to KF5/Qt5 was not supposed to be a part of the GSoC. The reason it came to be was that is it much more important for the rest of the development process of Plasma, than some of the originally planned tasks. Though, those are mostly done as well, but will be merged at a later stage – no point in putting finishing touches to something that is still under heavy development.

For more information about the changes in KActivities, see “KActivities for Qt5/KF5″.

KActivities for Qt5/KF5

KActivities has been ported to Qt5. The main service and the core library work without a glitch.

There are a few things left to finish like the Nepomuk integration and virtual desktop switching, but those will have to wait for the dust to settle in the required libraries.

API changes

The porting has not been only about making it compile on the new platform, but was a last chance that I’m going to have for a long time to fix the API of the library, by removing the deprecated methods, and making the interface asynchronous.

The old API was created with one thing in mind – to be as simple as possible for the user. Unfortunately, that meant not caring much about the fact that the clients have to communicate with the activities service via DBus which can get slow at the times and block the client.

Now, the library took a different path – it still has a similar (95% same) API to the old one, but the behaviour has changed a bit – it will never block. As soon as you create an instance of KActivities::Info or Consumer class, it will start syncing its internal one-per-client-application cache with the service.

It is up to the client to test for the status of the synchronization before trusting the values the library returns. This is essentially the same check that the clients should have already be doing in the old version – checking whether the activities service is running at all. The only change is that the status can now be ‘Syncing’, and not only ‘Running’ and ‘NotRunning’.

What does it mean for QML users

Since everything is exported via well-behaving properties, you don’t even need to care about the state of the synchronization – just connect something to a property and relax – the value will be set as soon as possible.

What does it mean for C++ users

You just create an instance of Consumer or Info and:

  1. Cover the case when the results are not valid (if the service is not running, or the data has not been synced yet) – In this case, the client gets a single activity with no name and a null uuid (like before).
  2. Hook into the signal which will tell you when the data is ready (or just into the signal of the property you want)

Advice: At least one instance of Consumer/Info should be long-lived for best performance. For heavy activities users like plasma and kwin, it would be the best if one Consumer instance was always-living.

A bigger change

The only class whose API has changed dramatically is the Controller, a class that should only have a few users – activity switching/creation applets and similar (aka Plasma and its children). All methods that were blocking are modified to be asynchronous by using non-thread-based QFutures.

No change

For the users of KActivities::ResourceInstance (Gwenview, Okular, Calligra etc.), no changes are needed – the class API was already perfect. :)

Honestly, I can not wait for Plasma 2.

Switching the Plasma shells

For Plasma 2, we are aiming to have one plasma to rule them all, but not in the way the others are doing it. We still believe that different form factors need different UIs (I refuse to use UX instead of UI, so sue me :) ). We just want the same application to be able to load the fitting interfaces for the desktop, netbook or tablets. And we want it to be able to dynamically switch between those.

The dynamic switching part I’m working on is almost finished. Namely, everything is prepared for the last step – integrating the new system with the current shells.

Each shell needs the following components:

  • A simple and lightweight loader object
  • And an actual shell implementation that can be done as a C++ plugin or a pure QML thing to make it easier for the common people to create the custom ones.

How does it work?

Note: To avoid confusion, from now on when I write Plasma, I mean the plasma-shell executable that loads the actual shells.

Plasma first gets all the loaders. Loaders need to have two properties defined:

  • ‘willing’ which tells whether it wants to be loaded for the current environment (for example, Plasma Active shell would say ‘yes’ when we have a touch-screen);
  • and ‘priority’ which will allow Plasma to choose between multiple willing shells (for example, an alternative desktop shell that the user installed).

None of these are hard-coded, so a loader can change its mind and, for example, the Desktop shell can set its priority to be as high as possible if we have more than one screen while having a lower one compared to the Active otherwise.

When a suitable shell is found, the loader is requested to create it.

When the environment changes, and the ‘willing’-ness of a loader has been changed, Plasma checks whether it should load a new shell or stick to the old one.

System upgrade

I’ve had an unfortunate situation this week – my system went bust. I’ve been forced to use my netbook for a few days which was rather painful. Fortunately, now it is all over, I’m enjoying a no-swap-ever-needed-8-cpu-core system. Enjoining… if you disregard a very noisy cpu cooler which will need changing.

Switching shells

A working mock for testing the underlying framework for Plasma shell switching:

video on youtube

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.

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

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