Using EWMH to detect WM in X11 sessions

This commit is contained in:
Linus Dierheimer
2022-01-02 18:42:58 +01:00
parent bcf543e129
commit ecb1853d56
2 changed files with 97 additions and 1 deletions
+21 -1
View File
@@ -266,6 +266,13 @@ static void getWMProtocolNameFromEnv(FFDisplayServerResult* result)
return;
}
env = getenv("DISPLAY");
if(env != NULL && *env != '\0')
{
ffStrbufSetS(&result->wmProtocolName, FF_DISPLAYSERVER_PROTOCOL_X11);
return;
}
env = getenv("TERM");
if(env != NULL && *env != '\0')
{
@@ -308,7 +315,7 @@ static void getFromProcDir(const FFinstance* instance, FFDisplayServerResult* re
if(result->wmPrettyName.length == 0)
applyPrettyNameIfWM(result, processName.chars);
if(result->deProcessName.length > 0 && result->wmPrettyName.length > 0)
if(result->dePrettyName.length > 0 && result->wmPrettyName.length > 0)
break;
}
@@ -324,6 +331,19 @@ void ffdsDetectWMDE(const FFinstance* instance, FFDisplayServerResult* result)
if(result->wmProtocolName.length == 0)
getWMProtocolNameFromEnv(result);
//We don't want to detect anything in TTY
if(ffStrbufIgnCaseCompS(&result->wmProtocolName, FF_DISPLAYSERVER_PROTOCOL_TTY) == 0)
return;
//If we found the processName via display server, use it.
//This will set the pretty name if it is a known WM, otherwise the prettyName to the processName
if(result->wmProcessName.length > 0)
{
applyPrettyNameIfWM(result, result->wmProcessName.chars);
if(result->wmPrettyName.length == 0)
ffStrbufSet(&result->wmPrettyName, &result->wmProcessName);
}
const char* env = parseEnv();
//Connecting to a display server only gives WM results, not DE results.
+76
View File
@@ -3,6 +3,70 @@
#ifdef FF_HAVE_X11
#include <X11/Xlib.h>
typedef struct X11PropertyData
{
FF_LIBRARY_SYMBOL(XInternAtom)
FF_LIBRARY_SYMBOL(XGetWindowProperty)
} X11PropertyData;
static unsigned char* x11GetProperty(X11PropertyData* data, Display* display, Window window, const char* request)
{
Atom requestAtom = data->ffXInternAtom(display, request, False);
if(requestAtom == None)
return NULL;
Atom actualType;
unsigned long unused;
unsigned char* result = NULL;
data->ffXGetWindowProperty(
display,
window,
requestAtom,
0,
64,
False,
AnyPropertyType,
&actualType,
(int*) &unused,
&unused,
&unused,
&result
);
return result;
}
static void x11DetectWMFromEWMH(X11PropertyData* data, Display* display, FFDisplayServerResult* result)
{
if(result->wmProcessName.length > 0)
return;
Window root = DefaultRootWindow(display);
if(root == None)
return;
unsigned char* wmWindowID = x11GetProperty(data, display, root, "_NET_SUPPORTING_WM_CHECK");
if(wmWindowID == NULL)
return;
Window wmWindow = *(Window*) wmWindowID;
if(wmWindow == None)
return;
unsigned char* wmName = x11GetProperty(data, display, wmWindow, "_NET_WM_NAME");
if(wmName == NULL)
wmName = x11GetProperty(data, display, wmWindow, "WM_NAME");
if(wmName == NULL)
return;
const char* wmNameString = (const char*) wmName;
if(*wmNameString == '\0')
return;
ffStrbufSetS(&result->wmProcessName, wmNameString);
}
static void x11AddScreenAsResult(FFlist* results, Screen* screen, uint32_t refreshRate)
{
if(WidthOfScreen(screen) == 0 || HeightOfScreen(screen) == 0)
@@ -20,6 +84,10 @@ void ffdsConnectXlib(const FFinstance* instance, FFDisplayServerResult* result)
FF_LIBRARY_LOAD_SYMBOL(x11, XOpenDisplay,)
FF_LIBRARY_LOAD_SYMBOL(x11, XCloseDisplay,)
X11PropertyData propertyData;
FF_LIBRARY_LOAD_SYMBOL_ADRESS(x11, propertyData.ffXInternAtom, XInternAtom,)
FF_LIBRARY_LOAD_SYMBOL_ADRESS(x11, propertyData.ffXGetWindowProperty, XGetWindowProperty,)
Display* display = ffXOpenDisplay(x11);
if(display == NULL)
{
@@ -30,6 +98,8 @@ void ffdsConnectXlib(const FFinstance* instance, FFDisplayServerResult* result)
for(int i = 0; i < ScreenCount(display); i++)
x11AddScreenAsResult(&result->resolutions, ScreenOfDisplay(display, i), 0);
x11DetectWMFromEWMH(&propertyData, display, result);
ffXCloseDisplay(display);
dlclose(x11);
@@ -216,6 +286,10 @@ void ffdsConnectXrandr(const FFinstance* instance, FFDisplayServerResult* result
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRFreeMonitors, XRRFreeMonitors,);
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, data.ffXRRFreeScreenConfigInfo, XRRFreeScreenConfigInfo,);
X11PropertyData propertyData;
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, propertyData.ffXInternAtom, XInternAtom,)
FF_LIBRARY_LOAD_SYMBOL_ADRESS(xrandr, propertyData.ffXGetWindowProperty, XGetWindowProperty,)
data.display = ffXOpenDisplay(NULL);
if(data.display == NULL)
{
@@ -228,6 +302,8 @@ void ffdsConnectXrandr(const FFinstance* instance, FFDisplayServerResult* result
for(int i = 0; i < ScreenCount(data.display); i++)
xrandrHandleScreen(&data, ScreenOfDisplay(data.display, i));
x11DetectWMFromEWMH(&propertyData, data.display, result);
ffXCloseDisplay(data.display);
dlclose(xrandr);