Mutter api under X11 and Wayland

Hi all:

Not sure if here is the best place to ask this… I’m creating an extension for gnome shell, and for simplicity and security I want to keep as much code as possible running as an stand-alone program, instead of inside the extension. I also want to put the window in the “desktop”; this is, under all other windows. To do this, I connect to the “map” event, and when a new window is mapped, I ask the PID of the owner of that window, and if it is the PID of the program that the extension launched, it sets some properties in the window. I do it this way:

for(let windowActor of global.get_window_actors()) {
    let window = windowActor.get_meta_window();
    let pid = window.get_pid();
    global.log(pid);
    if (pid == appPid) {
        ... // move and resize the window here, and all other stuff
    }
}

In theory this should work both in X11 and in Wayland; but it seems that “window.get_pid()” returns -1 under wayland, even when I’m doing this from a gnome shell extension (I can understand that an user program should not be able to get access to that information… but an extension inside Gnome Shell??).

Also I’m not sure how can I send the window to the DESKTOP layer. I found that there is META_WINDOW_DESKTOP and META_LAYER_DESKTOP, but all the methods in MetaWindow are for reading the property, and I can’t find where can I set it.

So the first question is: how can I get the PID of the process that owns an specific window, under Wayland? And second: how can I set, under Wayland, the window type to “desktop” to ensure that it is shown in all desktops, always under all other windows, and without being shown in the window list? Of course, I’m asking how to do all this from a Gnome Shell extension (I know that, under wayland, a program itself can’t do any of that to avoid security problems, but a Gnome Shell extension is different).

The documentation for meta_window_get_pid() mentions the _NET_WM_PID property, which is part of the EWMH—an X11 specification. Wayland does not have anything of the sort.

GNOME Shell does not really use the PID to match a window with an application, as it’s not possible to match a PID to a desktop file, which is the canonical source for things like the application’s description, icon, and command line/DBus activation name. GNOME Shell uses the application id, if available; failing that, it’ll use the WM_CLASS property; and failing that, it’ll use the PID. Only old X11 applications will not have an application id and/or an WM_CLASS property set, so _NET_WM_PID support is mostly for legacy stuff.

Additionally, you won’t be able to use the Meta API from an application: you can only use it from within the compositor.

Thanks for your answer, Emmanuele.

About the MetaAPI, I know that it can be used only from within the compositor; that’s why I separate my application in the main program (which does all the heavy lifting work) and a little extension (which works from inside the compositor, and which is who launches the main program and move, resize and keep the windows in the right place).

About using an application id and/or WM_CLASS, the problem is that those values are set by the application, which means that a rogue app can fake them. Wayland uses unix sockets, and there is a way of ensuring that a PID value sent by an app is the right one or not (https://stackoverflow.com/questions/8104904/identify-program-that-connects-to-a-unix-domain-socket); I presumed that Wayland used that, but now I see that it probably is not. Another possibility would be to have the socket id, and check it in the list of open FDs for that process inside /proc, but I’m not sure how portable is that… (freebsd seems to not have /proc, but I’m not completely sure https://www.freebsd.org/doc/en/articles/linux-users/procfs.html).

The idea behind all this work is that, since it is the extension who launches the application, it knows its PID, so when it detects a window from that PID, it knows that it is a confiable application and can give those “superpowers” that, under Wayland, are completely forbidden to classic applications. But this method can’t use any data that is set by the application to identify it, because a malicious application can use it to fool the extension, and that is something that I want to avoid. That’s why I wanted to use the PID, presuming that it was obtained by a system that was resistant to tampering.

Of course, I can use stdin/stdout to set some kind of handshake between the confiable application and the extension, to make them to agree into a value to set as application id (it is not secure to pass it in the command line, because that is visible to others), but I see this a little bit overkill. Also, I don’t know if the application id is kept secret between normal applications… (which, BTW, comes to the big question: how can I set the wayland’s application id in GTK? Is it the “application id” value passed to gtk_application_new() ?)

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.