I wrote a really basic kwin script to tile windows how I like them,

// Main reference: http://techbase.kde.org/Development/Tutorials/KWin/Scripting

// Top-level parameters. Adjust these as suitable for your desktop.
var width = 3840;
var third = Math.round(width / 3);

var clients = workspace.clientList();
for (var i=0; i<clients.length; i++) {
  var client = clients[i];
  var cap = client.caption.toLowerCase();
  var g = client.geometry;

  if (cap.indexOf("firefox") != -1) {
    g.x = 0;
    g.width = third;
  } else if (cap.indexOf("vim") != -1) {
    g.x = third;
    g.width = third;
  } else if (cap.indexOf("konsole") != -1) {
    g.x = third * 2;
    g.width = third;

  client.geometry = g;

using the scripting console (qdbus org.kde.plasma-desktop /MainApplication showInteractiveKWinConsole, or wm console from krunner).

I want to bind this to a hotkey.

I've only been able to find resources about building Plasma packages, which I haven't gotten to work (I have a metadata.desktop that's similar to the ones in /usr/share/kde4/apps/kwin/scripts, and similar directory contents, but it says plasmapkg(3980)/libplasma Plasma::Package::installPackage: Could not register package as service (this is not necessarily fatal): "kwin-script-tilewindows").

I'm a little tired of mucking with Plasma packaging. How can I invoke my JavaScript-based kwin script from the command line?

EDIT / Note

In case you're not familiar, it's easy to bind command to hotkeys in KDE -- just right-click the application launcher, go to "Edit Applications", add a new item, enter the shell command in the "Command" box, and then set the shortcut key in the "Advanced" tab.

3 Answers 3


With some hints from here, I managed to get the following to work:


num=$(dbus-send --print-reply --dest=org.kde.kwin.Scripting \
  /Scripting \
  org.kde.kwin.Scripting.loadScript \
  string:"$script" |
  awk 'END {print $2}' )

dbus-send --print-reply --dest=org.kde.kwin.Scripting \
  /$num \
  • Outdated. Getting Error org.freedesktop.DBus.Error.ServiceUnknown: The name org.kde.kwin.Scripting was not provided by any .service files.
    – Ashark
    Commented Jul 16, 2023 at 4:11

This is what I had to do in 2022 to get this to work


num=$(dbus-send --print-reply --dest=org.kde.KWin \
    /Scripting org.kde.kwin.Scripting.loadScript \
    string:"$script" | awk 'END {print $2}' )

dbus-send --print-reply --dest=org.kde.KWin /$num \

# I'm not sure if some delay is in order here to let your script complete?
dbus-send --print-reply --dest=org.kde.KWin /$num \

Note: in 2019 I needed to use org.kde.kwin.Scripting.run instead of org.kde.kwin.Script.run.

I'm not clear if the "stop" commands are needed, but they seem to clean up the dbus tree, so perhaps they should be used. I'm not sure if there are negative implications to using them, so if they cause trouble, perhaps try without.

  • But I cannot see the actual prints from the script. In script I wrote print("Hello world"). The output of last command is method return time=1652908699.636159 sender=:1.343 -> destination=:1.556 serial=2148 reply_serial=2. What I am doing wrong?
    – Ashark
    Commented May 18, 2022 at 21:21
  • Thanks -- updated. Yes, they seem to have changed it to "Script". I also added "stop" commands because otherwise the /1, /2, /3... get left behind. I don't know enough about this to know if that's a good idea, but I added them to my answer.
    – user272901
    Commented May 19, 2022 at 2:01
  • 1
    As a workaround, I can read journalctl, the kwin_wayland command writes there. Here bugs.kde.org/show_bug.cgi?id=445058 it is described how to do it.
    – Ashark
    Commented Jun 16, 2022 at 16:27
  • 1
    The python variant is available in my repo: github.com/Ashark/Ashark-bin/blob/master/get_list_of_windows
    – Ashark
    Commented Jun 16, 2022 at 18:18
  • 1
    Probably, also need to run org.kde.kwin.Scripting.unloadScript, like here: gist.github.com/academo/… (was linked here: unix.stackexchange.com/a/658994/264065) Also, probably it is possible to avoid using script file: unix.stackexchange.com/a/413873/264065
    – Ashark
    Commented Jun 16, 2022 at 21:58

I also gave an answer updated for May 2024 for the Python version of this in this question about listing windows in KDE Wayland.

The main thing that needs to change is the path to the script object, if you have a recent package version and are getting errors such as org.freedesktop.DBus.Error.UnknownObject: No such object path '/0' or whatever value for $num you currently have. Instead of /$num, it should be /Scripting/Script$num.

My script below fixes the object path, and it uses some tricks from Ashark's code to print only the output of the kwin script using journalctl. The | sed 's/^js: //' after the journalctl command is optional, as it simply removes the js: prefix from each line in the output.


now=$(date +%T)

num=$(dbus-send --print-reply --dest=org.kde.KWin \
    /Scripting org.kde.kwin.Scripting.loadScript \
    string:"$script" | awk 'END {print $2}')

dbus-send --print-reply --dest=org.kde.KWin /Scripting/Script$num \
    org.kde.kwin.Script.run >/dev/null

dbus-send --print-reply --dest=org.kde.KWin /Scripting/Script$num \
    org.kde.kwin.Script.stop >/dev/null

journalctl _COMM=kwin_wayland -o cat --since "$now" | sed 's/^js: //'

I found the correct script paths by running qdbus org.kde.KWin to list all the valid object paths.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .