Sous Linux, mon application C++ utilise fork() et execv() pour lancer plusieurs instances d'OpenOffice afin de visualiser des diaporamas Powerpoint. Cette partie fonctionne.
Ensuite, je veux pouvoir déplacer les fenêtres OpenOffice à des endroits spécifiques de l'écran. Je peux le faire avec la fonction XMoveResizeWindow() mais je dois trouver la fenêtre pour chaque instance.
J'ai l'ID du processus de chaque instance, comment puis-je trouver la fenêtre X11 à partir de cela ?
UPDATE - Grâce à la suggestion d'Andy, j'ai réussi à le faire. Je poste le code ici pour le partager avec la communauté Stack Overflow.
Malheureusement, Open Office ne semble pas définir la propriété _NET_WM_PID. Cela ne résout donc pas mon problème, mais répond à ma question.
// Attempt to identify a window by name or attribute.
// by Adam Pierce <adam@doctort.org>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <iostream>
#include <list>
using namespace std;
class WindowsMatchingPid
{
public:
WindowsMatchingPid(Display *display, Window wRoot, unsigned long pid)
: _display(display)
, _pid(pid)
{
// Get the PID property atom.
_atomPID = XInternAtom(display, "_NET_WM_PID", True);
if(_atomPID == None)
{
cout << "No such atom" << endl;
return;
}
search(wRoot);
}
const list<Window> &result() const { return _result; }
private:
unsigned long _pid;
Atom _atomPID;
Display *_display;
list<Window> _result;
void search(Window w)
{
// Get the PID for the current Window.
Atom type;
int format;
unsigned long nItems;
unsigned long bytesAfter;
unsigned char *propPID = 0;
if(Success == XGetWindowProperty(_display, w, _atomPID, 0, 1, False, XA_CARDINAL,
&type, &format, &nItems, &bytesAfter, &propPID))
{
if(propPID != 0)
{
// If the PID matches, add this window to the result set.
if(_pid == *((unsigned long *)propPID))
_result.push_back(w);
XFree(propPID);
}
}
// Recurse into child windows.
Window wRoot;
Window wParent;
Window *wChild;
unsigned nChildren;
if(0 != XQueryTree(_display, w, &wRoot, &wParent, &wChild, &nChildren))
{
for(unsigned i = 0; i < nChildren; i++)
search(wChild[i]);
}
}
};
int main(int argc, char **argv)
{
if(argc < 2)
return 1;
int pid = atoi(argv[1]);
cout << "Searching for windows associated with PID " << pid << endl;
// Start with the root window.
Display *display = XOpenDisplay(0);
WindowsMatchingPid match(display, XDefaultRootWindow(display), pid);
// Print the result.
const list<Window> &result = match.result();
for(list<Window>::const_iterator it = result.begin(); it != result.end(); it++)
cout << "Window #" << (unsigned long)(*it) << endl;
return 0;
}
1 votes
Je pense qu'il manque ceci
#include <stdlib.h>
pour leatoi
utilisée dansmain
.4 votes
Cinq ans de retard, mais je pense qu'il vous manque un XFree lorsque vous appelez XQueryTree.