Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

XFetchName always returns 0

Tags:

c

linux

xlib

im trying to write a C code to get the title of the Active Window in my Linux System, but the Function XFetchName always returnes zero, i also tried XGetWMName, same result... but using xprop, i can see that there is a string in the "WM_NAME" property

can anyone tell me whats wrong with my code?

#include <X11/Xlib.h>
#include <stdio.h>
#include <stdarg.h>


int main( int argc, char* argv[] )
{
      Display *display;
      Window focus;
      char *window_name;
      int revert;

      display = XOpenDisplay(NULL);
      XGetInputFocus(display, &focus, &revert);
      int ret = XFetchName(display, focus, &window_name);
      printf("ret = %d\n", ret);
      if (window_name) printf("Title = %s\n", window_name);
      return 0;
}

thanks.

like image 901
killercode Avatar asked Oct 23 '22 12:10

killercode


1 Answers

You can try using XGetWMName function. Although the discriptions of XGetWMName and XFetchName both say they will return the WM_NAME property, it seems that they are different from each other. Some times, they return the same name. Some times, only XGetWMName returns the name.

You can also use xwininfo -root -tree to get all the windows' name, and compare with the result of XFetchName and XGetWMName.

This code can list all the windows and print the window id and result of XFetchName and XGetWMName. You can use the window id to look up in the output of xwininfo -root -tree.

#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

void enum_windows(Display* display, Window window, int depth) {
  int i;

  XTextProperty text;
  XGetWMName(display, window, &text);
  char* name;
  XFetchName(display, window, &name);
  for (i = 0; i < depth; i++)
    printf("\t");
  printf("id=0x%x, XFetchName=\"%s\", XGetWMName=\"%s\"\n", window, name != NULL ? name : "(no name)", text.value);

  Window root, parent;
  Window* children;
  int n;
  XQueryTree(display, window, &root, &parent, &children, &n);
  if (children != NULL) {
    for (i = 0; i < n; i++) {
      enum_windows(display, children[i], depth + 1);
    }
    XFree(children);
  }
}

int main() {
  Display* display = XOpenDisplay(NULL);
  Window root = XDefaultRootWindow(display);
  enum_windows(display, root, 0);
}

Here's a piece of output showing that the result of two functions may be different.

id=0x2c7, XFetchName="(no name)", XGetWMName="(null)"
    id=0x400001, XFetchName="(no name)", XGetWMName="(null)"
    id=0x800036, XFetchName="(no name)", XGetWMName="(null)"
        id=0x1400001, XFetchName="(no name)", XGetWMName="c - XFetchName always returns 0 - Stack Overflow - Chromium"
    id=0x1000001, XFetchName="terminator", XGetWMName="terminator"
        id=0x1000002, XFetchName="(no name)", XGetWMName="(null)"
    id=0x1200001, XFetchName="chromium", XGetWMName="chromium"
        id=0x1200002, XFetchName="(no name)", XGetWMName="(null)"

Here's a piece of the output of xwininfo -root -tree showing the name of these windows. xwininfo: Window id: 0x2c7 (the root window) (has no name)

  Root window id: 0x2c7 (the root window) (has no name)
  Parent window id: 0x0 (none)
     29 children:
     0x1200001 "chromium": ("chromium" "Chromium")  10x10+10+10  +10+10
        1 child:
        0x1200002 (has no name): ()  1x1+-1+-1  +9+9
     0x1000001 "terminator": ("terminator" "Terminator")  10x10+10+10  +10+10
        1 child:
        0x1000002 (has no name): ()  1x1+-1+-1  +9+9
     0x800036 (has no name): ()  1364x741+0+25  +0+25
        1 child:
        0x1400001 "c - XFetchName always returns 0 - Stack Overflow - Chromium": ("Chromium" "Chromium")  1364x741+0+0  +1+26
     0x400001 (has no name): ()  10x10+-20+-20  +-20+-20
like image 163
Haoshu Avatar answered Oct 27 '22 09:10

Haoshu