ログイン
編集不可のページディスカッション情報添付ファイル
clear/wm_devel/2012-10-26

MMA

ウィンドウを列挙する

WMのデバッグ用に、存在するウィンドウを列挙しつつ属性を確認できるとうれしいので簡単なツールを書いた。

   1 #include <stdio.h>
   2 #include <string.h>
   3 #include <locale.h>
   4 #include <X11/Xlib.h>
   5 #include <X11/Xutil.h>
   6 #include <X11/Xatom.h>
   7 
   8 Display *dpy;
   9 Window root;
  10 
  11 Atom net_wm_name;
  12 
  13 #define BUFSIZE 256
  14 char buf[BUFSIZE];
  15 
  16 #define MIN(a, b) ((a) < (b) ? (a) : (b))
  17 
  18 #define OPT_GEOM 1
  19 #define OPT_CLASS 2
  20 #define OPT_OVERRIDE_REDIRECT 4
  21 #define OPT_TRANSIENT_FOR 8
  22 #define OPT_MAP_STATE 16
  23 
  24 unsigned int opt = OPT_GEOM | OPT_CLASS |  OPT_OVERRIDE_REDIRECT | OPT_TRANSIENT_FOR | OPT_MAP_STATE;
  25 
  26 void get_window_title(Window w, char *title, int size)
  27 {
  28     XTextProperty prop;
  29 
  30     /* try to get _NET_WM_NAME */
  31     XGetTextProperty(dpy, w, &prop, net_wm_name);
  32     if (prop.nitems == 0) {
  33         /* fall back to WM_NAME */
  34         XGetWMName(dpy, w, &prop);
  35     }
  36 
  37     title[0] = '\0';
  38     if (prop.nitems > 0 && prop.value) {
  39         if (prop.encoding == XA_STRING) {
  40             strncpy(title, (char *)prop.value, MIN(BUFSIZE - 1, size - 1));
  41         } else {
  42             char **l = NULL;
  43             int count;
  44             XmbTextPropertyToTextList(dpy, &prop, &l, &count);
  45             if (count > 0 && *l)
  46                 strncpy(title, *l, MIN(BUFSIZE - 1, size - 1));
  47             XFreeStringList(l);
  48         }
  49         title[size - 1] = '\0';
  50     }
  51 }
  52 
  53 #define indent(l) for (i = 0; i < (l); ++i) putchar('\t')
  54 void traverse(Window w, unsigned int level, unsigned int max_level)
  55 {
  56     Window r, parent, *children;
  57     unsigned int nchildren, i;
  58     XWindowAttributes wa;
  59 
  60     if (max_level != 0 && level > max_level)
  61         return;
  62 
  63     get_window_title(w, buf, BUFSIZE);
  64     if (buf[0] == '\0')
  65         strcpy(buf, "<no title>");
  66     XGetWindowAttributes(dpy, w, &wa);
  67 
  68     if (level > 0)
  69         putchar('\n');
  70     indent(level);
  71     printf("0x%06x \"%s\"\n", w, buf);
  72     if (opt & OPT_GEOM) {
  73         indent(level + 1);
  74         printf("geometry: %dx%d+%d+%d\n", wa.width, wa.height, wa.x, wa.y);
  75     }
  76     if (opt & OPT_CLASS) {
  77         indent(level + 1);
  78         printf("class: %s\n", wa.class == InputOutput ? "InputOutput" : "InputOnly");
  79     }
  80     if (opt & OPT_OVERRIDE_REDIRECT) {
  81         if (wa.override_redirect) {
  82             indent(level + 1);
  83             puts("override_redirect");
  84         }
  85     }
  86     if (opt & OPT_TRANSIENT_FOR) {
  87         Window trans;
  88         XGetTransientForHint(dpy, w, &trans);
  89         if (trans != 0) {
  90             indent(level + 1);
  91             printf("WM_TRANSIENT_FOR: 0x%06x\n", trans);
  92         }
  93     }
  94     if (opt & OPT_MAP_STATE) {
  95         indent(level + 1);
  96         printf("state: ");
  97         switch (wa.map_state) {
  98         case IsUnmapped: puts("Unmapped"); break;
  99         case IsUnviewable: puts("Unviewable"); break;
 100         case IsViewable: puts("Viewable"); break;
 101         }
 102     }
 103 
 104     XQueryTree(dpy, w, &r, &parent, &children, &nchildren);
 105     if (nchildren > 0) {
 106         for (i = 0; i < nchildren; ++i)
 107             traverse(children[i], level + 1, max_level);
 108         XFree(children);
 109     }
 110 }
 111 
 112 int main(int argc, char **argv)
 113 {
 114     if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
 115         fputs("warning: no locale support\n", stderr);
 116 
 117     dpy = XOpenDisplay(argc > 1 ? argv[1] : NULL);
 118     if (!dpy) {
 119         fputs("failed to open display\n", stderr);
 120         return 1;
 121     }
 122     net_wm_name = XInternAtom(dpy, "_NET_WM_NAME", False);
 123     root = RootWindow(dpy, DefaultScreen(dpy));
 124     traverse(root, 0, 0);
 125     XCloseDisplay(dpy);
 126     return 0;
 127 }
xenum.c

clear/wm_devel/2012-10-26 (最終更新日時 2012-10-27 12:43:19 更新者 clear)