KWin Effects written in JavaScript

Today I cannot make such a nice announcement as Aaron yesterday, but I can at least try announce something I personally consider as awesome.

This weekend I tried to make it possible to write KWin effects in JavaScript. After about two hours of work the effect loader was adjusted to load a Qt script instead of the library written in C++. This is a quite important step for the future of effects in KWin. It finally makes it possible to share effects via Get Hot New Stuff, so that our users can download new effects directly from the control module.

For packaging effects we use the well established Plasma Package structure, so that our script developers only need to know this one common way. The API itself will share as much as possible with the KWin scripting API – of course with adjustments for effects. For animating the API is based on the AnimationEffect introduced in 4.8.

From a performance point of view using JavaScript does not change anything. Our effect system has two phases: one to react on changes in the window manager (e.g. a window got activated) and one to perform the rendering. The scripting API only interacts with the window manager, so all the rendering is still good old C++ code – a similar approach to QML.

Now I guess you want to know what you can do with it. So here I present for example a Fade like effect written in JavaScript (for comparison: C++ version is > 200 SLOC):

var duration = 250;
effects.windowAdded.connect(function(w) {
    effect.animate(w, Effect.Opacity, duration, 1.0);
});
effects.windowClosed.connect(function(w) {
    effect.animate(w, Effect.Opacity, duration, 0.0, 1.0);
});

For us KWin core developers the scripted effects will be an important step as well. For quite some time we have been unhappy with the fact that there are too many effects which become difficult to maintain – especially if we have to adjust the API. With effects written in JavaScript this becomes much simpler. As we do not have to keep the ABI (API compatibility is enough) stable we can move effects written in JavaScript out of the source tree and make them available for download.

At the moment the JavaScript API is just at the beginning. But I expect it to evolve over the course of the current release cycle. For me the scripts are rather important as it also provides us an easy way to have device specific adjustments.

As I wrote currently the scripts do not operate during the rendering. Because of that we don’t have bindings for WebGL. This would at the moment not make any sense. Nevertheless it might be that we allow to upload custom shaders, but I won’t pursue such a task in the 4.9 cycle.

15 thoughts on “KWin Effects written in JavaScript

  1. You’re right, this is really awesome. KWin is getting really better in short time. Thanks for doing such wonderful things!

  2. Looks to me like kde is becoming more tightly integrated with qt as in using qt and its technologies/ideas directly like using qml instead of building some intermediate libraries etc.

    Makes me feel happy seeing how qt and kde are progressing together.

  3. Oh wow, you’re getting to my request :-)
    Just slightly different.. It’s nice to see effects can be done so easily, but looking at your example we’re still bound by the effects that KWIN provides through the API. So still no way for us to make real custom effects other then mixing the provided ones.

    What i was suggesting is really using QML for the effects from a – z.
    For example this, you example would look somewhat like this in QML:

    Window
    {
    Behavior on opacity
    {
    NumberAnimation { duration: 1000 }
    }
    }

    That’s it!.

    But more advanced things can also be done by using ShaderEffectItem. That’s the kinda stuff i meant :-)

    Yes, there you have to be aware of certain shaders not working on certain crappy hardware (ATI/AMD including the newest cards and drivers). Is that your end goal? Doing it in full QML like in my above example with Window?

    1. Is that your end goal? Doing it in full QML like in my above example with Window?

      No, I’m not planning to make normal effects in QML. Doing it in QML requires rendering through QML and as I explained to you more than once, this does not make sense for us.

      1. I know that – going fully through qml – ain’t gonna happen, but i thought there might be a way to use it’s features without it’s rendering.. I guess that means that KWIN should get some QML parser to make that happen..

        – not gonna happen –

        I’m dreaming on :) Good job so far!

        1. Well you spotted the problem. So even if we had our own QML parser, we would still be constrained to what we can do with effects. Giving you exactly the same API as what you will be able to do with the JavaScript bindings. Additionally the declarative way does not make much sense, as we don’t have Windows which you can declare, but windows just appear and disappear. And we also cannot add them into a Model – well we could, but QML is not very good with TreeModels and for KWin’s usecases we would need a very complex TreeModel with multiple FilterModels before to have nice wrappers (all windows of a desktop, all windows of a screen, all windows of an activity, etc. etc.). So JS is just the better solution for effects.

  4. My understanding of how this scripting works and what it can do is very limited, so please forgive me if the following seems like a stupid question to you:
    Would it be possible with this scripting engine to automatically activate the zooming lens effect when the mouse cursor enters a certain region of a window? (I’m thinking of this for zooming the snapping icons in inkscape).

    1. This is not yet possible but it is an interesting task, so I will try to design the API to make that possible.

  5. Is this going to be limited to javascript, or will it be a general API exposed through the various KDE bindings (python, ruby, mono, etc)?

    1. It’s limited to QtScript bindings. I don’t see a need for adding further language bindings.

      1. One reason is that not everyone knows javascript, and some people apparently prefer some languages over others.

        For instance, javascript is supposed to be the preferred language for scripted plasmoids. Nevertheless, according to a review a few months ago, more plasmoids were written in python (46%) than any other language (even C++), while javascript was much less popular (4% JS 6% QML). See here: http://blogs.kde.org/node/4469

        Overall there seems to be a great deal of demand for support for other scripting languages amongst small-time KDE developers, even if javascript is the preferred language amongst more core developers.

        1. Let’s see how the bindings are used, after that we can decide whether it makes sense to add more language bindings. But it needs someone else to implement these as I don’t know further languages.

Comments are closed.