LINUX.ORG.RU

[Xlib] Список окон через XQueryTree, segfault

 


0

1

Привет, ЛОР!

Помоги, пожалуйста, искать ошибку в коде. Или подскажи, как сделать лучше. Хочу получить список окон. Получить-то получаю, но заодно и segfault там, где вроде-бы должно быть root window.

Еще вопрос: XQueryTree() возвращает у меня около 20 дочерних окон для root window, хотя вижу я только 3. Откуда остальные, что это за окна?

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
#include <X11/Xutil.h>

static Display * dpy;
static Window root;

int main(int argc, char ** argv)
{
  dpy = XOpenDisplay (NULL);
  assert (dpy);
  root = DefaultRootWindow (dpy);
  assert (root);

  Window rw, pw, *cw, *wlist;
  unsigned int nchildren, i, nwindows = 0, w_indexes[256];
  XWindowAttributes wa;

  assert (XQueryTree (dpy, root, &rw, &pw, &cw, &nchildren));
  for (i = 0; i < nchildren; i++)
  {
    assert (XGetWindowAttributes (dpy, cw[i], &wa));
    if (wa.map_state == IsViewable)
    {
      /* сохраню номер видимого окна в общем списке окон */
      w_indexes[nwindows++] = i;
    }
  }
  printf ("%d windows:\n", nwindows);
  wlist = malloc (sizeof (Window) * nwindows);
  assert (wlist);
  for (i = 0; i < nwindows; i++)
  {
    wlist[i] = cw[w_indexes[i]];
  }
  for (i = 0; i < nwindows; i++)
  {
    XTextProperty wp;
    XGetWMName (dpy, wlist[i], &wp);
    printf ("%s\n", wp.value);
  }

  XCloseDisplay (dpy);
  return EXIT_SUCCESS;
}

Результат:

% gcc pwkl.c -o pwkl -lX11 -ggdb3
% ./pwkl 
4 windows:
Xlib Programming Manual: XQueryTree - Chromium
emacs@lamarr
evgeny@lamarr:~/devel
Ошибка сегментирования


не совсем понял, какие именно окна вы хотите получить…

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

#include <assert.h>

static void* x11property(Display *dpy, Window win, Atom prop, Atom type, int *nitems) {
	Atom type_ret;
	int format_ret;
	unsigned long items_ret;
	unsigned long after_ret;
	unsigned char *prop_data = 0;

	if (XGetWindowProperty(dpy, win, prop, 0, 0x7fffffff, False, type,
			&type_ret, &format_ret, &items_ret, &after_ret, &prop_data) != Success)
		return 0;

	if (nitems)
		*nitems = items_ret;

	return prop_data;
}

int main() {
	Atom atom_client_list;
	Atom atom_active_window;
	Display *dpy;
	Window root, *winlist, activewin;
	int num;
	
	dpy = XOpenDisplay(NULL);
	assert(dpy != NULL);
	
	root = DefaultRootWindow(dpy);
	
	atom_client_list = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
	atom_active_window = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False);

	winlist = x11property(dpy, root, atom_active_window, XA_WINDOW, NULL);
	if (winlist) {
		activewin = *winlist;
		XFree(winlist);
	} else {
		activewin = None;
	}
	
	winlist = x11property(dpy, root, atom_client_list, XA_WINDOW, &num);
	if (winlist) {
		int i;
		for (i = 0; i < num; ++i) {
			char *name = NULL;
			XFetchName(dpy, winlist[i], &name);
			printf("%c %#lx %s\n", winlist[i] == activewin ? '*' : ' ', (unsigned long) winlist[i], name);
			XFree(name);
		}
		XFree(winlist);
	}
	
	XCloseDisplay(dpy);
	
	return 0;
}
arsi ★★★★★
()
Ответ на: комментарий от age

Ваш код ничего не выводит.

да ну?

$ cc -lX11 -o winlist winlist.c
$ ./winlist 
  0x1c00790 plasma-desktop
  0x1c00768 plasma-desktop
  0x1c0077c plasma-desktop
  0x3400064 Rhino - Mozilla Firefox
* 0x360001f lor-winlist : mc
  0x3c00229 Amarok

разве что один баг — не выводит имён окон в кириллице.

arsi ★★★★★
()
Ответ на: комментарий от arsi

Я, кажется, понял. dwm не поддерживает эти атомы.

age
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.