¿Cómo saber qué ventana tiene el foco y cómo cambiarlo?
-
06-07-2019 - |
Pregunta
Me gustaría saber cómo puedo preguntarle a X11 qué ventanas tiene el foco. Y si por alguna razón mi propia aplicación (que puede ser visible o no) obtuvo el foco, quiero permitir que las ventanas anteriores vuelvan a enfocarse.
Por ejemplo, mi aplicación se está ejecutando con muchos otros (por ejemplo, firefox, gvim, nautilus, ...)
Suponga que al principio Firefox tiene el foco y que el usuario hizo clic en mi aplicación que ahora tiene el foco. Quiero que mi aplicación vuelva a centrarse en Firefox.
¿Alguien sabe cómo lograr esto? Las recomendaciones de libros serían muy buenas.
Muchas gracias.
Solución
Use este XQueryTree para encontrar la ventana actualmente activa o superior.
Aquí hay una función, cuando se le muestra una pantalla, encontrará la ventana actual en foco:
static Window
GetCurrWindow(d)
Display *d;
{
Window foo;
Window win;
int bar;
do{
(void) XQueryPointer(d, DefaultRootWindow(d), &foo, &win,
&bar, &bar, &bar, &bar, &bar);
} while(win <= 0);
#ifdef VROOT
{
int n;
Window *wins;
XWindowAttributes xwa;
(void) fputs("=xwa=", stdout);
/* do{ */
XQueryTree(d, win, &foo, &foo, &wins, &n);
/* } while(wins <= 0); */
bar=0;
while(--n >= 0) {
XGetWindowAttributes(d, wins[n], &xwa);
if( (xwa.width * xwa.height) > bar) {
win = wins[n];
bar = xwa.width * xwa.height;
}
n--;
}
XFree(wins);
}
#endif
return(win);
}
http://tronche.com/gui/x/xlib/ window-information / XQueryTree.html
Encontré la fuente:
http://examples.oreilly.com/networksa/tools/xsnoop.c
Buena suerte
Otros consejos
Eche un vistazo al valor _NET_ACTIVE_WINDOW
de la ventana raíz que establece la mayoría de los administradores de ventanas modernos:
xprop -root _NET_ACTIVE_WINDOW
Este valor, por supuesto, puede obtenerse usando llamadas a la biblioteca Xlib.
Probablemente desee la llamada XGetInputFocus
.
Window focused;
int revert_to;
XGetInputFocus(dpy, &focused, &revert_to);
En este fragmento, centrado
será la ventana con el foco de entrada actual, obteniendo eventos del teclado y pulsaciones del botón del mouse.
Esto funcionará incluso si el administrador de ventanas no establece la propiedad _NET_ACTIVE_WINDOW
en la ventana raíz, según lo especificado por EWMH. Algunos administradores de ventanas, como dwm y my 9wm, no configuran esto.
Recomiendo una aplicación llamada XDoTool. Admite muchas consultas, controles e incluso ganchos.
> xdotool getwindowfocus # 29360135
> xdotool getwindowfocus getwindowpid # 12988
> xdotool getwindowfocus getwindowname # tilda
> xdotool getwindowfocus behave '%@' blur getmouselocation
# or focus, mouse-enter, etc.
x:514 y:317 screen:0 window:56623121
x:271 y:26 screen:0 window:56623121
...
Los comandos como behave
aceptan una devolución de llamada, que puede incorporarse como getmouselocation
o externa como exec notify-send 'ventana enfocada'
, exec zsh myscript.zsh
, etc., como quiera usarlo.
Editar: puede enfocar usando xdotool windowfocus [opciones] [ventana]
, como en xdotool search --class firefox windowfocus
. En mi caso, esto causa errores porque Firefox aparece como un par de docenas de 'ventanas', pero todas tienen el mismo PID; funciona con la identificación correcta. Esperemos que sea un comienzo.
Editar 2: la 'ID de ventana' es la representación decimal del puntero de la ventana, p. de xprop :
> xprop -root _NET_ACTIVE_WINDOW
_NET_ACTIVE_WINDOW(WINDOW): window id # 0x1c00007, 0x0
> xdotool getwindowfocus
29360135
> printf '%d\n' '0x1c00007'
29360135