pythonwaylandgobject-introspection

Get GDK Window from xid, under Wayland


In a nutshell: this is a repeat of How to get Gdk window from xid?, but under Wayland.

Code like the following worked fine until I updated Debian from Stretch to Buster:

#!/usr/bin/env python3
from gi.repository import Gdk
from gi.repository import GdkX11

Gdk.Window.process_all_updates()
xlib_window = 0x2a00005 # for example. From wmctrl; xwininfo used in the previous question.
gdk_display = GdkX11.X11Display.get_default()
gdk_window = GdkX11.X11Window.foreign_new_for_display(gdk_display, xlib_window)
print gdk_window.get_geometry()

Unfortunately, gdk_display is now a __gi__.GdkWaylandDisplay, so GdkX11.X11Window.foreign_new_for_display throws

TypeError: argument display: Expected GdkX11.X11Display, but got __gi__.GdkWaylandDisplay

So how do I get my gdkWindow now? (I couldn't see the necessary docs online at all, so pointers to then would also be appreciated.)

I'm happy to also get the gdkWindow from PID or process name, since that's where I get the XID from.


Solution

  • As a general answer, judging by your "for example. From wmctrl" comment, there is no solution.

    By design, Wayland doesn't allows applications to meddle with or inspect each other's windows for security reasons.

    X11 applications like wmctrl run inside a compatibility layer named XWayland and don't have permission to meddle with native Wayland applications.

    You're getting that error because you're trying to use GdkX11 inside an application that started up as a native Wayland application and it's not fundamentally different from the error you'd get from trying to call Win32 APIs in a C# application that's running natively on Linux.

    The only way to make it work is to either look up how to force any relevant applications to fall back to running via XWayland or write whatever you're trying to accomplish as a patch for the Wayland compositor itself.