Tengo el PID para el proceso (y el nombre), quiero llevarlo al frente en Linux (ubuntu). En mac simplemente haría SetFrontProcess(pid)
, en Windows enumeraría las ventanas, elegiría la que yo quería, y llamaría al SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
pero no sabía qué hacer en Linux. He analizado un poco a X Lib, pero la mayoría o todas esas funciones parecen funcionar en ventanas dentro de tu proceso.¿Cómo traigo una ventana de procesos al primer plano en X Windows? (C++)
Editar: Usando la respuesta de bdk añadí estos ayudantes a mi código para obtener la ventana
bool searchHelper(Display* display, Window w, Atom& atomPID, unsigned long pid, Window& result)
{
bool ret = false;
Atom atomType;
int format;
unsigned long nItems;
unsigned long bytesAfter;
unsigned char* propPID = 0;
if (Success == XGetWindowProperty(display,w,atomPID,0,1,False,XA_CARDINAL,&atomType,&format,&nItems,&bytesAfter,&propPID))
{
if (propPID != 0)
{
if (pid == *((unsigned long *)propPID))
{
result = w;
ret = true;
}
XFree(propPID);
}
}
if (ret)
return ret; //we found we can stop
//check the children of the window
Window wRoot;
Window wParent;
Window *wChild=NULL;
unsigned nChildren=0;
if (XQueryTree(display, w, &wRoot, &wParent, &wChild, &nChildren) != 0)
{
for (unsigned i=0; i<nChildren; ++i)
{
ret = searchHelper(display, wChild[i], atomPID, pid, result);
if (ret)
break;
}
}
return ret;
}
bool getWindowFromPid(unsigned long pid, Display* display, Window& result)
{
Window window = XDefaultRootWindow(display);
Atom atomPID = XInternAtom(display, "_NET_WM_PID", true);
if (atomPID == None)
{
qDebug("XInternAtom failure");
return false;
}
return searchHelper(display, window, atomPID, pid, result);
}
Ahora me sale la ventana con éxito, pero cuando lo haga la siguiente
if (getWindowFromPid(pid,display,window))
{
qDebug("Found window ID:%d", window);
int result = XRaiseWindow(display,window);
qDebug("XRaiseWindow returned:%d", result);
}
XRaiseWindow devuelve 1 (BadRequest). La documentación de XRaiseWindow no menciona el código de retorno de BadRequest como posible resultado. No estoy seguro de lo que está mal. ¿No se me permite llamar a Windows en un proceso diferente? ¿Esta prevención de acero de enfoque me está obstaculizando? ¿Alguna idea?
Editar editar:
Así que mirar lo que xwininfo.c hace cuando se le llama con -frame he cambiado de código como sigue basado en la sugerencia de BDK.
if (getWindowFromPid(pid,display,window))
{
qDebug("Found window ID:%d", window);
//Need the windowmanger frame (or parent) id not window id
Window root, parent;
Window *childlist;
unsigned int ujunk;
int status = XQueryTree(display, window, &root, &parent, &childlist, &ujunk);
if (status && parent && parent != root)
{
qDebug("Found frame window ID:%d",parent);
window = parent;
}
XSetWindowAttributes xswa;
xswa.override_redirect=True;
int result = XChangeWindowAttributes (display,window,CWOverrideRedirect,&xswa);
qDebug("XChangeWindowAttributes returned:%d", result);
result = XRaiseWindow(display,window);
qDebug("XRaiseWindow returned:%d", result);
}
else
qDebug("unable to find the window for the pid");
En este punto hago encontrar el ID del marco de la ventana, pero me da un código de retorno de "1" de ambos XChangeWindowAttributes y XRaiseWindow. ¿Acaso no puedo modificar la ventana de otro proceso?
Obtendrá mejores resultados preguntando "¿Cómo traigo una ventana de procesos al primer plano en X Windows?" –
@Vulcan gracias, he editado el título de la pregunta. (Tenga en cuenta la tilde original: "¿Cómo puedo traer un proceso al frente en Linux (C++)?") – Lorenz03Tx
Si desea obtener una versión técnica, el título sigue estando mal; no existe tal cosa como "X Windows". Es "El sistema X Window" (pero "Ventana" no debe estar pluralizado). –