XFetchName всегда возвращает 0 - PullRequest
3 голосов
/ 11 января 2012

я пытаюсь написать код на C, чтобы получить заголовок активного окна в моей системе Linux, но функция XFetchName всегда возвращает ноль, я также пробовал XGetWMName, тот же результат ... но используя xprop, я вижу, что в свойстве "WM_NAME" есть строка

Может кто-нибудь сказать мне, что не так с моим кодом?

#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;
}

спасибо.

Ответы [ 3 ]

2 голосов
/ 01 декабря 2014

Вы можете попробовать использовать функцию XGetWMName.Хотя различения XGetWMName и XFetchName оба говорят, что они вернут свойство WM_NAME, похоже, что они отличаются друг от друга.Иногда они возвращают одно и то же имя.Иногда только XGetWMName возвращает имя.

Вы также можете использовать xwininfo -root -tree, чтобы получить имя всех окон и сравнить с результатом XFetchName и XGetWMName.

Этот код может перечислить все окна и распечатать идентификатор окна и результат XFetchName и XGetWMName.Вы можете использовать идентификатор окна для поиска в выводе 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);
}

Вот фрагмент вывода, показывающий, что результат двух функций может отличаться.

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)"

Вот часть вывода xwininfo -root -tree, показывающая название этих окон.xwininfo: идентификатор окна: 0x2c7 (корневое окно) (без имени)

  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
0 голосов
/ 01 августа 2016
 /*
  * The following functions are internationalized substitutions
  * for XFetchName and XGetIconName using XGetWMName and
  * XGetWMIconName.  
  *
  * Please note that the third arguments have to be freed using free(), 
  * not XFree().
  */
 Status
 I18N_FetchName(dpy, w, winname)
     Display *dpy;
     Window w;
     char ** winname;
 {
     int    status;
     XTextProperty text_prop;
     char **list;
     int    num;

     status = XGetWMName(dpy, w, &text_prop);
     if (!status || !text_prop.value || !text_prop.nitems) return 0;
     status = XmbTextPropertyToTextList(dpy, &text_prop, &list, &num);
     if (status < Success || !num || !*list) return 0;
     XFree(text_prop.value);
     *winname = (char *)strdup(*list);
     XFreeStringList(list);
     return 1;
 }

// XFetchName использует XGetWMName

см .: введите описание ссылки здесь

0 голосов
/ 11 января 2012

Функция XFetchName возвращает имя указанного окна.Если это успешно, это возвращает ненулевой статус;в противном случае для окна не было задано имя, и оно возвращает ноль.

Вам необходимо установить имя для своего окна.

Я начал сеанс xterm, выполнил ваш код и получил следующий вывод:

sangeeth@home:~/work/test$ ./a.out 
ret = 1 
Title = sangeeth@home: ~/work/test
sangeeth@home:~/work/test$ 

OTOH, я попытался скомпилировать вашу программу и получил следующую ошибку:

(.text+0x18): undefined reference to `main'

Вам нужно изменить

int _main( int argc, char* argv[] )

на

int main(int argc, char* argv[]) 
...