Ivan Čukić

Plasma calendar mock-up

I’m working on different ideas for the activity switcher for plasma 2. Unfortunately, I haven’t had much inspiration for that. The only thing I had a real inspiration for was the calendar.

I really dislike out current calendar widget. It is confusing, and the layout is overcrowded and asymmetric (in a bad way :) ). It often confuses me when it shows events – I always think everything is today.

So I made this. It is just a mock-up, no real code yet. Opinions?

cal-mock

Slides from Qt Dev Days: continuations, asynchronous APIs, etc.

Presentation Announcement

I’ve been asked a few times to post the slides of my talk online. Lets hope we’ll have the videos soon as well.

The slides are now available on SlideShare.

Continuations and asynchronous programming at Qt Dev Days

There are quite a few nice talks in the C++ track of Qt Dev Days this year. So many that I don’t expect to move away from that room at all.

I’ll be talking about a fun and clean way to work with asynchronous APIs on Wednesday at the Cafe Moscow in Berlin. I hope I will not get sleepy after lunch.

The talk will be about dealing with asynchronous API using futures (QFuture, std::future, boost::future, QDBusPendingReply…) and continuations. It will be about inversion-of-control, variadic templates, lazy evaluation, functors etc. There will be a few c++11 headache-inducing features demonstrated.

See you in Berlin!

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″.

Clang Format

This is just a short one.

What would you say if I told you that you can have an indent-like command that actually understands your code?

And that it has plugins for vim, emacs and a few other editors/IDEs that will allow you to reformat your code on the fly?

If you would say ‘Yes please!’, just visit this page and enjoy: Clang Format.

It works quite nicely, except that it doesn’t really speak Qt. Qt’s macro-keywords like Q_SIGNALS, foreach and similar will still require your manual formatting.

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.

Curry with a lot of (syntax) sugar in C++11 (finished)

I know I’m getting boring with currying, but I have finished most of what I originally wanted. And I am publishing the code this time. It is published under GPL.

Now, a curried function can be invoked with a single call, like a regular function; in two calls; or in as many calls as you wish – the only limit is the actual number of arguments. So, all of the following works:

  f(1, 2, 3, 4, 5, 6)
  f(1, 2, 3, 4, 5)(6)
  f(1, 2, 3, 4)(5)(6)
  f(1, 2)(3)(4)(5, 6)
  f(1)(2)(3)(4)(5)(6)

On reddit, a very nice explanation of currying by m42a contained this piece of code:

  template <class Func>
  auto partially_apply_to_2(Func f)
  {
      return uncurry(curry(f)(2));
  }

It returns a new function that is same as f, but with the first argument set to 2. (see the post why this is more practical than std::bind). With the new version of curry.h, you don’t even need to uncurry the function, you can just do this:

  return curry(f)(2);
  // or:
  return curry(f, c);

Here are a few documented examples of what you can do:

curry/main.cpp

And here is the header file: curry/curry.h

Even more curry for C++11

After my initial post about currying in C++, I was wondering whether it is possible to make a universal curry transformation that will be applicable to any functor.

Fortunately, like most weird things, in C++ the answer to this question is yes.

Here, we’ll create a curry object from a lambda function:

  auto log = make_curry(
      [] (int type, int subtype, const std::string & message)
      {
          std::cerr
              << type << " / " << subtype
              << "\t" << message << std::endl;
      }
  );

And use it in all the different ways:

  int main(int argc, const char *argv[])
  {
      auto message = log(1);
      auto error = log(0, 0);

      // Only one argument already given
      message(0, "Normal message");
      message(1, "Important message");

      // We have two arguments already given
      error("No error, just kidding");

      // Or, we can call directly
      log(1, 1, "Arguments: 3 - 0")();
      log(1, 1)("Arguments: 2 - 1");
      log(1)(2, "Arguments: 1 - 2");
      log()(2, 2, "Arguments: 0 - 3");

      return 0;
  }

It allows only to split the function arguments into two sets. I might make it a bit more powerful at some point. I’m a bit sleepy now.

Anyone interested in the code?

Curry all over the C++11

Currying is all-present in functional programming. And we are not really using it.

What is currying? It is a technique of transforming a function that takes multiple arguments in such a way that it can be called as a chain of functions, each with a single argument.

For example, lets look at a simpler version of fprintf function that looks something like this:

  print: (stream, message) -> do something

  // Invoked like this:
  print(cout, "Hello")

If we use the method often with specific streams (like cout, cerr and a log file), we can define it in a different manner, so that we could easily make additional versions specific to those streams. And, we don’t need to impose our opinions of what a user wants by providing a set of convenience functions ourselves (ok, qDebug() is something that everybody wants, but you get the point).

  print: stream -> function called print_to
  print_to: message -> do something

  // It would be invoked like this:
  // (note that the print_to function doesn't
  // really need to be named)
  print(cout)("Hello")

  // or
  log = print(logging_stream)
  err = print(cerr)

  log("Hello")
  err("Error world")

So, this seems totally unneeded, right? It can be quite useful when working with generic code (for example STL algorithms). The following example demonstrates vector partitioning for different predicates.

  #include <string>
  #include <iostream>
  #include <algorithm>
  #include <iterator>

  auto less_than = [] (int i) {
      return [i] (int j) {
          return j < i;
      };
  };

  template <typename B, typename M, typename E>
  inline void write_partitions(B b, M m, E e)
  {
      std::copy(b, m, std::ostream_iterator<int>(std::cout, " "));
      std::cout << "  |  ";

      std::copy(m, e, std::ostream_iterator<int>(std::cout, " "));
  }

  int main(int argc, const char *argv[])
  {
      std::vector<int> ns { 1, -2, 3, -4, 5, -6, 7, -8, 9, -10 };

      // Original vector
      std::copy(ns.begin(), ns.end(),
              std::ostream_iterator<int>(std::cout, " "));
      std::cout << " - Original vector" << std::endl;

      // Partitions for numbers ranging from 0 to 9
      for (int i = 0; i < 10; i++) {
          auto p = std::partition(ns.begin(), ns.end(), less_than(i));

          write_partitions(
              ns.begin(), 
              p,
              ns.end());
          std::cout << " - Predicate: _ < " << i << std::endl;
      }

      return 0;
  }

This is the output it generates:

  -10 -2 -8 -4 -6   |  5 7 3 9 1  - Predicate: _ < 0
  -10 -2 -8 -4 -6   |  5 7 3 9 1  - Predicate: _ < 1
  -10 -2 -8 -4 -6 1   |  7 3 9 5  - Predicate: _ < 2
  -10 -2 -8 -4 -6 1   |  7 3 9 5  - Predicate: _ < 3
  -10 -2 -8 -4 -6 1 3   |  7 9 5  - Predicate: _ < 4
  -10 -2 -8 -4 -6 1 3   |  7 9 5  - Predicate: _ < 5
  -10 -2 -8 -4 -6 1 3 5   |  9 7  - Predicate: _ < 6
  -10 -2 -8 -4 -6 1 3 5   |  9 7  - Predicate: _ < 7
  -10 -2 -8 -4 -6 1 3 5 7   |  9  - Predicate: _ < 8
  -10 -2 -8 -4 -6 1 3 5 7   |  9  - Predicate: _ < 9

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.