2009-07-07 15 views
6

Estoy tratando de obtener la ventana X en una determinada ubicación en la pantalla. Cuando le pedí a las personas una función para hacer esto, me dijeron que simplemente llamarías a XQueryTree recursivamente.¿Qué pasa con mi código X11?

Este es el fragmento de código que, de alguna manera, creo que está mal. Cuando lo depuro, parece funcionar perfectamente. El único problema es que la salida que da parece un poco extraña. Cuando hago XQueryTree en la ventana raíz, obtengo cientos de niños, cuando solo tengo cinco o menos abiertos. Además, parece pensar que hay una ventana de nivel superior en algún lugar donde simplemente no hay una, y la devuelve como resultado. No importa cómo mueva mis ventanas reales, XQueryTree parece indicar que hay otra ventana en la parte superior de mis ventanas (que no cubre toda la pantalla). Cuando miro dónde dice que está la ventana, está en algún lugar arbitrario apuntar en mi escritorio

Si esto es de alguna ayuda: La pantalla es de XOpenDisplay (NULL), y la ventana raíz que originalmente le paso es XDefaultRootWindow (pantalla). Estoy ejecutando GNOME bajo Debian con metacity.

point getwindowatloc(Display * display, Window root, jint x, jint y) { 
     Window returnedroot; 
     Window returnedparent; 
     Window * children; 
     unsigned int numchildren; 
     XQueryTree(display,root,&returnedroot,&returnedparent,&children, &numchildren); 
     XWindowAttributes w; 
     int i; 
     for(i=numchildren-1; i>=0; i--) { 
      XGetWindowAttributes(display,children[i],&w); 
      if(x>=w.x && x<=w.x+w.width && y>=w.y && y <= w.y+w.height) { 
       point result={w.x,w.y}; 
       XFree(children); 
       return result; 
      } else { 
       point result=getwindowatloc(display,children[i],x-w.x,y-w.y); 
       if(result.x!=INT_MAX) { 
        result.x+=w.x; 
        result.y+=w.y; 
        XFree(children); 
        return result; 
       } 
      } 
     } 
     if(children) { 
      XFree(children); 
     } 
     return notfound; 
    } 

¡Gracias!

EDITAR: Para cualquiera que esté buscando información similar: terminé buscando en la fuente de xwininfo. La función clave es Find_Client en dsimple.c, que de alguna manera ignora a los administradores de ventanas para obtener la ventana que realmente está buscando. Si desea examinar las subventanas, este es un código que agregué a Select_Window en dsimple.c, que buscará recursivamente dentro de las subventanas, utilizando XTranslateCoordinates.

Window child; 
do { 
    XTranslateCoordinates(dpy,target_temp,target_win,x,y,&x,&y,&child); 
    target_temp=target_win; 
    target_win=child; 
} while(target_win); 
return target_temp; 
+1

¡No puedo creer que alguien realmente esté haciendo una pregunta de xlib aquí! He usado xlib pero no lo suficiente para ayudar a solucionar tu problema :( – hhafez

+0

Sería mejor que publicaras tu solución como respuesta, en lugar de publicar una pregunta. –

Respuesta

3

Su código se ve a la derecha (no he probado), y los resultados que usted describe no parece extraña en absoluto. Metacity (y otros administradores de ventanas X) crearán muchas ventanas alrededor y cerca de las ventanas propiedad de la aplicación para mostrar el título de la ventana, los bordes y otras decoraciones.

Intenta ejecutar tu prueba con un gestor de ventanas más simple como TVM (o incluso ninguno). TVM debería crear muchas menos ventanas que los actuales administradores de ventanas. Esto debería hacer las cosas más fáciles de entender.

Por lo general, sin embargo, es una mala idea luchar contra el administrador de ventanas. ¿No puedes resolver tu problema de una manera más elevada sin tener que usar xlib directamente?

+0

La idea era que quería escribir algo que funcionara como hombre plataformas como sea posible. Pensé que si lo escribía para xlib, sería portátil para muchos sistemas, en lugar de solo trabajar para el administrador de ventanas que uso. Intentaré usarlo con un gestor de ventanas diferente. –

3

Creo que lo que quiere hacer es consultar la propiedad _NET_CLIENT_LIST de la ventana raíz. Esto generará una lista de identificadores de ventana para todas las ventanas de cliente, excluyendo todas las ventanas "virtual" creadas por el administrador de ventanas. La mayoría de los administradores de ventanas aparentemente admiten _NET_CLIENT_LIST, pero también puede consultar si se admite o no alguna característica dada.

+0

Gracias, pero Encontré algo más que funciona. Estoy usando una herramienta de xwininfo para hacer el trabajo. Podría hacer exactamente lo que estás sugiriendo, no estoy seguro. Gracias por la ayuda. –

+0

Genial, me alegra oír que encontraste una solución. :) – rob