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.
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.
There were quite a few comments on my last post. I’d
like to clear up a few (imo) misconceptions there.
What I wrote in the last post is not enabled by the default in Qt.
So, you should not have any problems during development while using auto
with Qt5 (btw, it has almost the same behaviour in Qt4).
From my POV, it is not a bug, but rather an expected behaviour. I
only tested the code after writing the blog
post - already knowing and expecting the result I got.
If you explicitly enable the optimization, it
is expected that you know what you are doing.
The lazy evaluation here is a new feature that auto provides. And, as
with any other new feature, you just need to learn how to use it.
That, combined by the desire to be as efficient as possible which
makes QStringBuilder to use const references instead of copying the
QString object, makes it behave like this.
This can not break the existing code for two reasons - you don’t use
auto in it, and you probably do not define the QT_USE_FAST_OPERATOR_PLUS
macro before including QString.
Question
What is the output of the following code:
QString separator = "/";
auto date = "14" + separator + "7" + separator + "2013";
separator = " ";
auto datetime = date + separator + "17:32";
qDebug() << datetime;
Scroll down…
Expected output: "14/7/2013 17:32"
Actual output: "14 7 2013 17:32"
What happened?
In his great talk, Volker
mentioned the optimizations of QString concatenation via the auto,
expression templates and QStringBuilder that allow to do a single memory
allocation for all the concatenations in the
example above.
I just wanted to repeat a warning I gave to the audience - for the
people who were not present.
In this case, auto allows the lazy evaluation of the result (which
provides the actual optimization). “Lazy” means that the separator value
is only taken at the point of the actual evaluation which happens only
when the QStringBuilder is being converted to a string in order to be
able to output it via qDebug. At that point, the value of separator is ”
“, and the old value”/” has been forgotten.
The lazy evaluation is usually a trait of pure functional languages
(Haskell) where there is no mutable state. When you have the mutable
state, you need to really pay attention whether you are using an
expression template-based API.
When?
This mechanism is only used when either QT_USE_FAST_OPERATOR_PLUS or
QT_USE_QSTRINGBUILDER are defined. And those are, by default, in KDE
Frameworks 5.
A working mock for testing the underlying framework for Plasma shell
switching:
{% youtube RoC4l3eTriE %}