How to Run a KWin Script from Console to Set Window Focus in KDE

focuskwinscriptingwindow

I need to set focus to VirtualBox in KDE, I've written a KWin script for the purpose but I cannot figure out how to run it from console.

What I have tried:

This KWin script works in the Desktop Shell Scripting Console

How to open the Desktop Shell Scripting Console:

  1. Press Alt+F2, type

  2. Run wm console

The script:

// Main reference: http://techbase.kde.org/Development/Tutorials/KWin/Scripting
// API: https://techbase.kde.org/Development/Tutorials/KWin/Scripting/API_4.9

// Sets focus to VirtualBox
var clients = workspace.clientList(); 
for (var i=0; i<clients.length; i++) {
  print(clients[i].caption);
  var cap = clients[i].caption;
  if (cap.indexOf("- Oracle VM VirtualBox") != -1) {
    workspace.activeClient = clients[i];
  }
}

But when I try to run it in Bash (according to this method) scripting does not seem to be setup as I get these errors:

Error org.freedesktop.DBus.Error.ServiceUnknown: The name org.kde.kwin.Scripting was not provided by any .service files
Error org.freedesktop.DBus.Error.ServiceUnknown: The name org.kde.kwin.Scripting was not provided by any .service files

I don't know how dbus works internally so from here on I just try things.

I tried to fix these problems caused by things changing in newer versions of KDE:

QDBusViewer

So I run the qdbusviewer to have a look.

It should be KWin instead of kwin.Scripting.

I find org.kde.KWin in the left hand list and Scripting to the right, under org.kde.kwin.Scripting I find the methods loadScript and start. I'm able to use these methods manually by double clicking on them, loading my script file and it works, my script gets run and VirtualBox receives focus.

So I try to modify the loading commands accordingly:

dbus-send --print-reply --dest=org.kde.KWin /Scripting org.kde.kwin.Scripting.loadScript string:"/home/jk/msexcel_setfocus.kwinscript"

dbus-send --print-reply --dest=org.kde.KWin /Scripting org.kde.kwin.Scripting.start

These commands does not give an error but it does not work either.

Is dbus working at all?

I try something else just to see if dbus is working at all, and this works (enabling/disabling the FPS effect):

dbus-send --print-reply --session --dest=org.kde.KWin /Effects org.kde.kwin.Effects.loadEffect string:"showfps"

dbus-send --print-reply --session --dest=org.kde.KWin /Effects org.kde.kwin.Effects.unloadEffect string:"showfps"

Numbered entries

So there is this business in the script linked to above with a numbered path of some kind, I find that in QDBusViewer sometimes there are numbered entries in the right pane (they come and go). And there actually a Scripting item and a run method in there when a number exists. So I try this:

This command does give a number that corresponds to the number appearing in QDBusViewer.

num=$(dbus-send --print-reply --dest=org.kde.KWin /Scripting org.kde.kwin.Scripting.loadScript string:"/home/jk/msexcel_setfocus.kwinscript" | awk 'END {print $2}')
echo $num
dbus-send --print-reply --dest=org.kde.KWin /$num org.kde.kwin.Scripting.run

But the last command does not work, neither does it work run the start method (as above) before the run method, then it complains that the number is gone.

Error org.freedesktop.DBus.Error.UnknownObject: No such object path '/1'

Best Answer

After far more trial and error than I would have liked, it seems it is possible to run a string containing a script directly by communicating with plasmashell, as in the following example (which happens to be what I was trying, as part of moving the panel when I rotate the screen):

qdbus org.kde.plasmashell /PlasmaShell evaluateScript \ "panelById(panelIds[0]).location='right'"

Related Question