From 22a3ab4a81006943acfb8b1afe9908975937f3a5 Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Sun, 26 Jun 2022 13:35:16 +0200 Subject: [PATCH] Detect wayland WM _much_ faster --- src/detection/displayserver/wayland.c | 27 ++++++++++++++++++++++++++- src/detection/displayserver/wmde.c | 23 ++++++++++++++++------- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/detection/displayserver/wayland.c b/src/detection/displayserver/wayland.c index 5ed8b9008..993ee77cc 100644 --- a/src/detection/displayserver/wayland.c +++ b/src/detection/displayserver/wayland.c @@ -1,3 +1,5 @@ +#define _GNU_SOURCE //required for struct ucred + #include "displayServer.h" #include @@ -7,6 +9,7 @@ #include #include #include +#include typedef struct WaylandData { @@ -19,6 +22,25 @@ typedef struct WaylandData struct wl_output_listener output_listener; } WaylandData; +static void waylandDetectWM(int fd, FFDisplayServerResult* result) +{ + if(fd < 1) + return; + + struct ucred ucred; + socklen_t len = sizeof(struct ucred); + if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1) + return; + + FFstrbuf procPath; + ffStrbufInit(&procPath); + ffStrbufAppendF(&procPath, "/proc/%d/cmdline", ucred.pid); //We check the cmdline for the process name, because it is not trimmed. + ffReadFileBuffer(procPath.chars, &result->wmProcessName); + ffStrbufSubstrBeforeFirstC(&result->wmProcessName, '\0'); //Trim the arguments + ffStrbufSubstrAfterLastC(&result->wmProcessName, '/'); //Trim the path + ffStrbufDestroy(&procPath); +} + static void waylandGlobalRemoveListener(void* data, struct wl_registry* wl_registry, uint32_t name){ FF_UNUSED(data, wl_registry, name); } @@ -81,6 +103,7 @@ bool detectWayland(const FFinstance* instance, FFDisplayServerResult* result) FF_LIBRARY_LOAD(wayland, instance->config.libWayland, false, "libwayland-client.so", 1) FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_connect, false) + FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_get_fd, false) FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_dispatch, false) FF_LIBRARY_LOAD_SYMBOL(wayland, wl_display_roundtrip, false) FF_LIBRARY_LOAD_SYMBOL(wayland, wl_proxy_marshal_constructor, false) @@ -89,7 +112,7 @@ bool detectWayland(const FFinstance* instance, FFDisplayServerResult* result) WaylandData data; - FF_LIBRARY_LOAD_SYMBOL_ADRESS(wayland, data.ffwl_proxy_marshal_constructor_versioned, ffwl_proxy_marshal_constructor, false) + FF_LIBRARY_LOAD_SYMBOL_ADRESS(wayland, data.ffwl_proxy_marshal_constructor_versioned, wl_proxy_marshal_constructor_versioned, false) FF_LIBRARY_LOAD_SYMBOL_ADRESS(wayland, data.ffwl_proxy_add_listener, wl_proxy_add_listener, false) FF_LIBRARY_LOAD_SYMBOL_ADRESS(wayland, data.ffwl_output_interface, wl_output_interface, false) FF_LIBRARY_LOAD_SYMBOL_ADRESS(wayland, data.ffwl_proxy_destroy, wl_proxy_destroy, false) @@ -101,6 +124,8 @@ bool detectWayland(const FFinstance* instance, FFDisplayServerResult* result) return false; } + waylandDetectWM(ffwl_display_get_fd(display), result); + struct wl_registry* registry = (struct wl_registry*) ffwl_proxy_marshal_constructor((struct wl_proxy*) display, WL_DISPLAY_GET_REGISTRY, ffwl_registry_interface, NULL); if(registry == NULL) { diff --git a/src/detection/displayserver/wmde.c b/src/detection/displayserver/wmde.c index 5327fe89b..c5264a7b2 100644 --- a/src/detection/displayserver/wmde.c +++ b/src/detection/displayserver/wmde.c @@ -56,8 +56,21 @@ static void applyPrettyNameIfWM(FFDisplayServerResult* result, const char* proce if(!ffStrSet(processName)) return; - if(strcasecmp(processName, "kwin_wayland") == 0 || strcasecmp(processName, "kwin_x11") == 0 || strcasecmp(processName, "kwin") == 0) - ffStrbufSetS(&result->wmPrettyName, "KWin"); + if( + strcasecmp(processName, "kwin_wayland") == 0 || + strcasecmp(processName, "kwin_wayland_wrapper") == 0 || + strcasecmp(processName, "kwin_x11") == 0 || + strcasecmp(processName, "kwin_x11_wrapper") == 0 || + strcasecmp(processName, "kwin") == 0 + ) ffStrbufSetS(&result->wmPrettyName, "KWin"); + else if( + strcasecmp(processName, "gnome-session-binary") == 0 || + strcasecmp(processName, "Mutter") == 0 + ) ffStrbufSetS(&result->wmPrettyName, "Mutter"); + else if( + strcasecmp(processName, "cinnamon-session") == 0 || + strcasecmp(processName, "Muffin") == 0 + ) ffStrbufSetS(&result->wmPrettyName, "Muffin"); else if(strcasecmp(processName, "sway") == 0) ffStrbufSetS(&result->wmPrettyName, "Sway"); else if(strcasecmp(processName, "weston") == 0) @@ -72,10 +85,6 @@ static void applyPrettyNameIfWM(FFDisplayServerResult* result, const char* proce ffStrbufSetS(&result->wmPrettyName, "Marco"); else if(strcasecmp(processName, "xmonad") == 0) ffStrbufSetS(&result->wmPrettyName, "XMonad"); - else if(strcasecmp(processName, "gnome-session-binary") == 0 || strcasecmp(processName, "Mutter") == 0) - ffStrbufSetS(&result->wmPrettyName, "Mutter"); - else if(strcasecmp(processName, "cinnamon-session") == 0 || strcasecmp(processName, "Muffin") == 0) - ffStrbufSetS(&result->wmPrettyName, "Muffin"); else if( // WMs where the pretty name matches the process name strcasecmp(processName, "dwm") == 0 || strcasecmp(processName, "bspwm") == 0 || @@ -379,7 +388,7 @@ void ffdsDetectWMDE(const FFinstance* instance, FFDisplayServerResult* result) getWMProtocolNameFromEnv(result); //We don't want to detect anything in TTY - //This can't happen if a X11 connection succeeded, so we don't need to clear wmProcessName + //This can't happen if a connection succeeded, so we don't need to clear wmProcessName if(ffStrbufIgnCaseCompS(&result->wmProtocolName, FF_DISPLAYSERVER_PROTOCOL_TTY) == 0) return;