2009-07-07 7 views
6

J'essaye d'obtenir la fenêtre X à un certain endroit à l'écran. Quand j'ai demandé aux gens de faire une fonction, ils ont dit que vous appeliez simplement XQueryTree récursivement.Quel est le problème avec mon code X11?

Ceci est l'extrait de code que je pense est en quelque sorte faux. Quand je le débogue, ça semble fonctionner parfaitement. Le seul problème est que la sortie qu'elle donne semble un peu étrange. Quand je fais XQueryTree sur la fenêtre racine, je reçois des centaines d'enfants, quand j'ai seulement cinq ou plus ouvert. En outre, il semble penser qu'il existe une fenêtre de haut niveau quelque part où il n'y en a tout simplement pas, et la renvoie en conséquence. Peu importe comment je bouge mes fenêtres réelles, XQueryTree semble indiquer qu'il y a une autre fenêtre sur le dessus de mes fenêtres (ne couvrant pas tout l'écran.) Quand je regarde où il est dit que la fenêtre est, il est arbitraire pointer sur mon bureau.

Si cela vous aide: L'affichage provient de XOpenDisplay (NULL), et la fenêtre racine que je lui ai initialement transmise est XDefaultRootWindow (affichage). Je cours gnome sous debian avec la métacity.

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

Merci!

EDIT: Pour tous ceux qui recherchent des informations similaires: j'ai fini par regarder dans la source de xwininfo. La fonction clé est Find_Client dans dsimple.c, qui en quelque sorte ignore les gestionnaires de fenêtres pour obtenir la fenêtre que vous recherchez réellement. Si vous voulez regarder dans les sous-fenêtres, c'est du code que j'ai ajouté à Select_Window dans dsimple.c qui va regarder récursivement dans les sous-fenêtres, en utilisant 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

Je n'arrive pas à croire que quelqu'un pose une question xlib ici! J'ai utilisé xlib mais pas assez pour aider à déboguer votre problème :( – hhafez

+0

Il vaudrait mieux que vous posté votre solution comme réponse, au lieu d'éditer l'article de la question –

Répondre

3

Votre code semble droit (je ne l'ai pas testé), et les résultats que vous décrivez ne semble pas étrange du tout. Metacity (et d'autres gestionnaires de fenêtres X) va créer beaucoup de fenêtres autour et à proximité des fenêtres appartenant à l'application pour montrer le titre de la fenêtre, les bordures et autres décorations. Essayez d'exécuter votre test avec un gestionnaire de fenêtres plus simple comme TVM (ou même pas du tout). TVM devrait créer beaucoup moins de fenêtres que les gestionnaires de fenêtres actuels. Cela devrait rendre les choses plus faciles à comprendre.

Habituellement, cependant, c'est une mauvaise idée de lutter contre le gestionnaire de fenêtres. Ne pouvez-vous pas résoudre votre problème de manière plus approfondie sans avoir à utiliser xlib directement?

+0

L'idée était que je voulais écrire quelque chose qui fonctionnerait comme homme Je me suis dit que si je l'écrivais pour xlib, ce serait portable sur de nombreux systèmes, plutôt que de travailler uniquement pour le gestionnaire de fenêtres que j'utilise, je vais essayer de l'utiliser avec un autre gestionnaire de fenêtres .. –

3

Je pense que ce que vous voulez faire est d'interroger la propriété _NET_CLIENT_LIST de la fenêtre racine. Cela produira une liste d'identifiants de fenêtres pour toutes les fenêtres client, à l'exclusion de toutes les fenêtres «virtual» créées par le gestionnaire de fenêtres. La plupart des gestionnaires de fenêtres prennent apparemment en charge _NET_CLIENT_LIST, mais vous pouvez également demander si une fonctionnalité donnée est prise en charge ou non.

+0

J'ai trouvé quelque chose d'autre qui marche.J'utilise une fuction de xwininfo pour faire le travail.Il pourrait faire exactement ce que vous suggérez, je ne suis pas sûr.Merci pour l'aide –

+0

Cool, heureux d'entendre que vous avez trouvé une solution de contournement. :) – rob

Questions connexes