KWin Scripting from 5.x to 6.x -- Compatible?

I have several complex (non-KDE) scripts that handle my window placement. They are called via Custom Shortcuts and move and manage windows using xdotool and wmctrl. With Wayland and KDE 6 coming, I am looking at replacing them with KWin scripts. If I begin now, using KDE 5.x KWin scripts, will they generally be compatible with KWin as used in KDE 6.x or is there any kind of breaking overhaul?

I have looked online and seen nothing to suggest this, but I figured it was worth asking here before I committed many hours on converting everything over. Thanks for any answer you can give!

No, unfortunately Plasma 6 will bring breaking changes to the KWin scripting API that will make scripts incompatible between the two versions.

1 Like

Thank you very much for the reply. I had put together a very preliminary test script, but I’ll wait for the 6.x API.

Is there anywhere to get early access to information about the breaking changes in how KWin Scripts work?

I’m trying out the KDE Neon Unstable ISO and I’m having difficulty even installing a simple script of type “KWin/Script” that has never given me any trouble on KDE 5.x distros.

Kpackagetool6 is saying that the metadata is invalid for the type specified, but I don’t know where to go to start figuring out how to fix it for the coming KDE 6.x release.

@zzag Is the autogenerated API documentation for v6 already accessible somewhere? Is there going to be a porting guide? Given that the 5 → 6 transition will break every KWin script written for 5 it would be good to give developers a chance to adapt before the release.

1 Like

Just ported my script over. Had to change one line:
workspace.clientList()
→
workspace.windowList()

I looked here for reference:

And kpackagetool6 -t KWin/Script --install . worked in my case. My metadata.json looks like:

{
    "KPackageStructure": "KWin/Script",
    "KPlugin": {
        "Authors": [
            {
                "Email": "m.liu.jin@gmail.com",
                "Name": "Jin Liu"
            }
        ],
        "Description": "toggle dropdown",
        "Icon": "preferences-system-windows-script-test",
        "Id": "toggle-dropdown",
        "License": "GPL",
        "Name": "ToggleDropdown",
        "Version": "1.0"
    },
    "X-KDE-PluginKeyword": "dropdown",
    "X-Plasma-API": "javascript",
    "X-Plasma-MainScript": "code/main.js"
}
2 Likes

Thanks @nclarius and @jinliu.

Looks like I was able to get it working, after making sure my installer would use the “kblahblah6” commands instead of “kblahblah5” and changing workspace.clientActivated() to workspace.windowActivated() in the script.

And adding the KPackageStructure element to my metadata.json file, which I didn’t have for some reason.

Everything seems to be working fine now. :crossed_fingers:

Sigh, not really… I started Porting your scripts to KWin 6 · Wiki · Plasma / KWin · GitLab but forgot about it.

will have to go over the list of changes in src/scripting/ and put them on the wiki page.

5 Likes

changes in src/scripting/

And I assume some changes in Q properties such as due to the client → window renaming would affect scripting as well?

Definitely. I don’t think there have been major changes. The most annoying one is either dropping “client” prefix or replacing it with “window”. The remaining ones are using more Output and VirtualDesktop + adding support for qtquick effects, e.g. examples/quick-effect · master · Plasma / KWin · GitLab

2 Likes

@zzag @nclarius

So I suppose at this early stage there isn’t an official guide on how to handle installing the correct version of a KWin script that needs to be installable on both KDE 5 and KDE 6?

With the GNOME 45 transition there was some indication their extension hosting system would just keep separate copies of extensions for the different GNOME versions. That seemed to happen automatically. The two devs that I kind of worked with to port their extensions to G45 had no real issue uploading a new version and still serving older GNOME versions. But it was unclear how they were supposed to handle having the non-backwards-compatible changes in a GitHub repo, for instance. Without making a new branch for the pre-G45 version of the extension, it wouldn’t necessarily be easy to fix a problem with the older version independently of the G45+ version of the same extension in the same repo.

Seems like there is about to be a similar sort of choice needing to be made for KWin scripts, and I wonder if there are any thoughts about that from any KDE devs.

Currently my project that uses a custom KWin script now has two different versions of it, in “kde5” and “kde6” folders, and the project installer does what it can to figure out whether it is being installed on KDE 5 or 6. Right now that’s being done by checking for “kpackagetool6” and deciding that the system must be KDE 6 if that tool exists in the path. (KDE Neon Unstable has both the “6” and the “5” versions of the tool, so I just check for the newer version first.)

But I also need to install another KWin script that comes from its own GitHub repo. Which currently just has its own simple Bash installer script that just references “kpackagetool5”, and needs its metadata modified and probably some client references modified in order to work with KDE 6. Updating the state of the GitHub repo to do this will obviously result in a KWin script that would only be compatible with KDE 6, unless I split it into new subfolders for 5/6.

There’s also the issue of the versioning of things like Plasma shell still showing as 5.81.x instead of some kind of 6.x version. Another reason I’m relying only on looking for “kpackagetool6” for now.

So what’s the plan to have a sane transition to KDE 6 for KWin scripts, and still supporting KDE 5 during its remaining lifetime, which will be several years depending on the distro? Separate GitHub/Gitlab repos for the KDE 6 version, or splitting the script into version-specific subfolders? Is there an official way of testing from a script to see if we are installing on KDE 6, better than looking for “kpackagetool6”?

Any insights, observations or discussion of this situation will be appreciated.

The script itself can probably check for KDE versions by:

if (workspace.windowList) {
    // kde6
} else {
   // kde5
}

and in bash scripts we have $KDE_SESSION_VERSION=6.

1 Like

And if you don’t like runtime checks, you can also use a template engine to generate js code, so you can write something like:

{{if kde5}}
...
{{else}}
...
{{/if}}

e.g.

It uses handlebars.

1 Like

That’s going to come in handy, for sure. Thanks.

The if/else inside the KWin script is a good idea. But I can imagine depending on the script it might be simpler just to have separate versions, instead of trying to merge them. Might be able to make it work. I’ll have to give it a try.

In the KDE store there will be separate categories for Plasma 5 and Plasma 6 extensions, so for the purpose of distribution you’ll need to two separate self-contained versions of the script anyway.

For Plasma widgets there is a mechanism in Plasma to detect version mismatches: src/plasmaquick/appletquickitem.cpp · 6c3ec3c91551d65c017b6881d16635e2212c4ab3 · Plasma / KDE Plasma Framework · GitLab It would be good to have something like that for KWin scripts too, ideally already in the install process. @Ismael @mart @zzag How feasible is this?

How you want to handle it in your code management is up to you; I would think that using branches to handle different versions of the same script is the most natural choice.

1 Like

That was something I suggested to the GNOME extension devs I was interacting with, just as a way to save the state of the older extension in case the pre-G45 version needed a bug fixed after the G45 transition, otherwise that state could be lost, and the new extensions were not backwards compatible. But that wouldn’t be as practical, I think, for a situation where you may be updating the same KWin script for KDE 5/6 in parallel.

I feel like that’s more of a separate repo sort of situation. Or at least separate subfolders in the same repo, with an installer script that would install the correct one.

In the KDE store there will be separate categories for Plasma 5 and Plasma 6 extensions, so for the purpose of distribution you’ll need to two separate self-contained versions of the script anyway.

Categories is fine, but what if the KWin script can actually be compatible with both, as suggested by @jinliu earlier? Will the metadata have to say that the script is only for 5 or 6 somehow?

Last night I actually went through the process of figuring out two different ways to use an if/else to conditionally engage the correct API references for 5 or 6, and in theory I saw no reason why either of those methods wouldn’t work. But I haven’t confirmed that the resulting KWin script actually works yet. I need to track down that arcane command that seemed to get some debugging info out of KWin scripts under a Wayland session. (Still testing KDE 6 on Neon Unstable, unless there is a better way.)

ChatGPT was of the opinion that KDE 5 would be fine with the element that I had to add to the metadata file to make it install on KDE 6 (“KPackageStructure”), so as of right now I’m not aware of any technical reason that there would actually need to be two separate (and different) KWin scripts for 5/6, rather than just two separate uploads of the same identical script.

Looking forward to further discussion. I just need to know which path to spend time on.

BTW, that command is:

journalctl --user --unit=plasma-kwin_wayland.service --grep='^js: ' --since='10min ago'

Just print('blah') in your scripts.

1 Like

Yeah, that’s the one. But I feel like there was also a corresponding environment variable that might need to go in ~/.profile and then logout/login to activate it.

Let me google that for me:

export QT_LOGGING_RULES="kwin_*.debug=true"

Something like that.

BTW for anyone who cares, I’ve never understood this reference in that documentation:

print(QVariant...)

Could KWin provide a compatibility layer for KWin5 scripts? E.g. in addition to workspace.windowList(), also provide workspace.clientList(), which returns wrapped Window objects that, say, in addition to window.desktops, also provide window.desktop as int, etc.

I don’t have that env variable, and in kdebugsettings all kwin.* are set to warning. So no, probably that is no longer required.

1 Like