Is there a way to get list of windows on KDE Wayland?

In the era of X11, I could do wmctrl -l to list available windows, that I can use in my scripts.

$ wmctrl -l
0x01000050  0 my-pc project1 – Readme.md

But nowadays most application use Wayland. The above command only shows windows that are running with XWayland.

I want to be able to use applications in Wayland mode and at the same time be able to list their windows for my scripts. Is that possible? I am using Arch Linux with KDE.

Asked By: Ashark

||

Yes, it is possible. The idea is to ask kwin for this information. It is done via kwin script. It can only communicate the world with dbus, so we cannot run shell commands in kwin scripts (at least directly). But we can run kwin script from shell script.

Create the following script ~/bin/list_windows.js:

const clients = workspace.clientList();
for (var i = 0; i < clients.length; i++) {
  print(clients[i].caption);
}

Unfortunately, the output to stdout is currently broken, see bug report. But there is a workaround. Turn on the kde systemd startup. Now we can use journalctl to pull the output. The resulting get_list_of_windows script is the following:

#!/usr/bin/env python3

import subprocess
from datetime import datetime


def get_list_of_windows():
   datetime_now = datetime.now()

   script = "/home/andrew/bin/list_windows.js"

   reg_script_number = subprocess.run("dbus-send --print-reply --dest=org.kde.KWin 
                        /Scripting org.kde.kwin.Scripting.loadScript 
                        string:" + script + " | awk 'END {print $2}'",
                           capture_output=True, shell=True).stdout.decode().split("n")[0]

   subprocess.run("dbus-send --print-reply --dest=org.kde.KWin /" + reg_script_number + " org.kde.kwin.Script.run",
                  shell=True, stdout=subprocess.DEVNULL)
   subprocess.run("dbus-send --print-reply --dest=org.kde.KWin /" + reg_script_number + " org.kde.kwin.Script.stop",
                  shell=True, stdout=subprocess.DEVNULL)  # unregister number

   since = str(datetime_now)

   msg = subprocess.run("journalctl _COMM=kwin_wayland -o cat --since "" + since + """,
                        capture_output=True, shell=True).stdout.decode().rstrip().split("n")
   msg = [el.lstrip("js: ") for el in msg]

   return msg


print('n'.join(get_list_of_windows()))

Now run the script and you will get the output:

$ get_list_of_windows
Рабочий стол по умолчанию — Plasma
Plasma
Is there a way to get list of windows on KDE Wayland? - Unix & Linux Stack Exchange - Vivaldi
get_list_of_windows — Kate
Andrew Shark / Davinci Resolve Scripts · GitLab — Falkon
project1 – README.md

This is in my repo.

Answered By: Ashark
Categories: Answers Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.