How can I get current active screen (a screen with mouse) in KDE wayland?

Viewed 101

I want to be able to detect active screen in KDE from my python script. Previously I used Xlib and was looking for the screen with mouse like so:

from Xlib import display
def mousepos():
    data = display.Display().screen().root.query_pointer()._data
    return data["root_x"], data["root_y"]

current_pos = mousepos()
x_pos = current_pos[0]
y_pos = current_pos[1]

names_handling_y = []
names_handling_x = []
...
    if x_pos >= output["pos"]["x"] and x_pos <= output["pos"]["x"] + output["size"]["width"]:
        names_handling_x.append(output["name"])
    if y_pos >= output["pos"]["y"] and y_pos <= output["pos"]["y"] + output["size"]["height"]:
        names_handling_y.append(output["name"])
...
for name in names_handling_x:
    if name in names_handling_y:
        target_output = name

But how can I do similar thing when using Wayland?

1 Answers

I have found the following way. You can run a dbus query for the active screen (see api, added in commit) or run a kwin script. It is possible to run a kwin script from another script. So I can do it like this:

#!/usr/bin/env python3
import subprocess
from datetime import datetime

# KDE Active screen is a screen with mouse cursor.

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

    file = open("/tmp/get_active_screen.js", "w")
    script = """
    as = workspace.activeScreen;
    print(as + 1)
    """
    file.write(script)
    file.close
    del file, script

    script = "/tmp/get_active_screen.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]
    if len(msg) != 1:
        exit(1)

    return int(msg[0])


active_screen_id = get_active_screen_id()

And then I can use that id in my script. This method is even better than determining coordinates of screen at which mouse position is in Xlib method.

Related