¿Cómo encuentro con precisión las dimensiones y la posición de la ventana, incluidas las decoraciones?


37

He estado tratando de calcular el tamaño de una ventana para usar en un script pequeño. Mi técnica actual está usando wmctrl -lGpara averiguar las dimensiones. Sin embargo, el problema es este:

Las figuras x e y que da son para la parte superior izquierda de las decoraciones de la ventana, mientras que la altura y el ancho son solo para el área de contenido. Esto significa que si las decoraciones de la ventana agregan 20 px de altura y 2 px de ancho, wmctrl informará que una ventana es 640x480, incluso si ocupa 660x482 en la pantalla. Esto es un problema porque el siguiente paso de mi script sería usar esa área para decirle a ffmpeg que grabe la pantalla. Me gustaría evitar la codificación en el tamaño de las decoraciones de las ventanas de mi configuración actual.

Lo que conviene es un método para obtener el tamaño de las decoraciones de la ventana para que pueda usarlas para determinar la posición del área de contenido 640x480, o una forma de obtener la posición del área de contenido directamente, no la de las decoraciones de la ventana .


1
Mezclé altura y anchura en las figuras del diagrama.
Macha


Respuestas:


36

La siguiente secuencia de comandos le dará los códigos de pantalla de la esquina superior izquierda y el tamaño de la ventana (sin ninguna decoración). . . . xwininfo -id $(xdotool getactivewindow)contiene suficiente información para ti.


#!/bin/bash
# Get the coordinates of the active window's
#    top-left corner, and the window's size.
#    This excludes the window decoration.
  unset x y w h
  eval $(xwininfo -id $(xdotool getactivewindow) |
    sed -n -e "s/^ \+Absolute upper-left X: \+\([0-9]\+\).*/x=\1/p" \
           -e "s/^ \+Absolute upper-left Y: \+\([0-9]\+\).*/y=\1/p" \
           -e "s/^ \+Width: \+\([0-9]\+\).*/w=\1/p" \
           -e "s/^ \+Height: \+\([0-9]\+\).*/h=\1/p" )
  echo -n "$x $y $w $h"
#

Esto parece funcionar porque xdotool getactivewindowdevuelve la identificación de la ventana del marco del administrador de ventanas (que incluye la decoración) en lugar de la ventana del cliente contenida en su interior.
Adam Spires

2
No, esto devuelve la geometría sin las decoraciones, que explícitamente no es lo que hizo la pregunta. Si no desea decoraciones incluidas, hay formas más fáciles de hacerlo, por ejemploxdotool getactivewindow getwindowgeometry
slinkp

1
Esto no funciona bien para mí (es decir, las decoraciones no están incluidas). Esta respuesta es mejor.
Jan Warchoł

7

La respuesta aceptada se puede extender para obtener toda la ventana:

entire=false
x=0
y=0
w=0
h=0
b=0  # b for border
t=0  # t for title (or top)

# ... find out what user wants then 

eval $(xwininfo -id $(xdotool getactivewindow) |
  sed -n -e "s/^ \+Absolute upper-left X: \+\([0-9]\+\).*/x=\1/p" \
         -e "s/^ \+Absolute upper-left Y: \+\([0-9]\+\).*/y=\1/p" \
         -e "s/^ \+Width: \+\([0-9]\+\).*/w=\1/p" \
         -e "s/^ \+Height: \+\([0-9]\+\).*/h=\1/p" \
         -e "s/^ \+Relative upper-left X: \+\([0-9]\+\).*/b=\1/p" \
         -e "s/^ \+Relative upper-left Y: \+\([0-9]\+\).*/t=\1/p" )
if [ "$entire" = true ]
then                     # if user wanted entire window, adjust x,y,w and h
    let x=$x-$b
    let y=$y-$t
    let w=$w+2*$b
    let h=$h+$t+$b
fi
echo "$w"x"$h" $x,$y

Aunque es fácil, resulta que no funciona en Unity en Ubuntu 14.04 porque la información relativa es toda 0. Pregunté Obtener las dimensiones de la ventana completa (incluidas las decoraciones) en Unity y obtuve una buena respuesta. Así es como usé esa respuesta:

aw=$(xdotool getactivewindow)
eval $(xwininfo -id "$aw" |
      sed -n -e "s/^ \+Absolute upper-left X: \+\([0-9]\+\).*/x=\1/p" \
             -e "s/^ \+Absolute upper-left Y: \+\([0-9]\+\).*/y=\1/p" \
             -e "s/^ \+Width: \+\([0-9]\+\).*/w=\1/p" \
             -e "s/^ \+Height: \+\([0-9]\+\).*/h=\1/p" )
if [ "$entire" = true ]
then
    extents=$(xprop _NET_FRAME_EXTENTS -id "$aw" | grep "NET_FRAME_EXTENTS" | cut -d '=' -f 2 | tr -d ' ')
    bl=$(echo $extents | cut -d ',' -f 1) # width of left border
    br=$(echo $extents | cut -d ',' -f 2) # width of right border
    t=$(echo $extents | cut -d ',' -f 3)  # height of title bar
    bb=$(echo $extents | cut -d ',' -f 4) # height of bottom border

    let x=$x-$bl
    let y=$y-$t
    let w=$w+$bl+$br
    let h=$h+$t+$bb
fi

Este segundo método funciona tanto en Unity como en Xfce, y también debería funcionar en Gnome.


El enfoque superior es incorrecto incluso fuera de Unity en Ubuntu porque supone que los bordes izquierdo, derecho e inferior tienen el mismo ancho, y no hay garantía de esto. El segundo enfoque se ve mejor.
Adam Spires

Acabo de comprobar el segundo enfoque: solo era necesario aw=`xdotool getactivewindow`agregar la parte superior para evitar colgar en la llamada xwininfo. Es bueno saberlo porque estoy considerando cambiar a Unity, donde no puedo hacer que wmiface se ejecute sin segfaullar.
slinkp

@slinkp, gracias por señalar la awdefinición que falta . Editaré la respuesta ahora para agregar esa línea.
Colin Keenan

La segunda parte de esto funciona muy bien! El único cambio que tuve que hacer en Gnome 3 fue no agregar la altura de la barra de título h. Parece que la barra de título ya está incluida en la altura desde la que regresa xwininfo.
Jonny Asmar

7

Una forma mucho más simple de obtener el tamaño y la posición de la ventana:

xdotool getwindowfocus getwindowgeometry

3

La respuesta aceptada explícitamente no incluye la decoración de ventanas. Para aquellos que todavía buscan cómo obtener la geometría, incluidas todas las decoraciones, según el título de esta pregunta, pueden usar wmiface según esta otra pregunta https://superuser.com/questions/164047/how-to-get-accurate-window -información-dimensiones-etc-en-linux-x . Ejemplo:

wmiface frameGeometry `wmiface activeWindow`

Esto devuelve la geometría y la posición relativa a la parte superior izquierda de la siguiente manera:

650x437+0+1003

wmiface no parece venir con todas las distribuciones de Linux (no encontré un paquete que lo proporcionara en Mint o Ubuntu) pero pude instalarlo desde los paquetes aquí: http://kde-apps.org/content/show .php? content = 40425

Y viene sin documentos ni siquiera --help , pero el archivo README está aquí:

https://gitorious.org/wmiface/wmiface/source/ea941eeb2076124734f6a3d3079326c826b462d7:README


Lo sentimos - Me arrepiento de mi upvote para esto porque la respuesta aceptada no incluye decoración de ventanas como por mi comentario sobre el mismo.
Adam Spires

Desearía que fuera cierto, pero desafortunadamente ese comentario está mal. Están de acuerdo con el id de la ventana activa: $ wmiface activeWindow 6291772 $ xdotool getactivewindow 6291772 Pero no están de acuerdo con la geometría, y puedo confirmar con, por ejemplo. Screenruler que wmiface incluye la decoración de la ventana y xdotool no. Pruébalo por ti mismo. $ wmiface frameGeometry wmiface activeWindow570x434 + 870 + 31 $ xdotool getwindowgeometry xdotool getactivewindowWindow 6291772 Posición: 878,77 (pantalla: 0) Geometría: 562x407
slinkp

lo siento, espero que puedas descifrar lo que quise decir allí ... deseo que stackoverflow permita muestras de código de bloque en los comentarios.
slinkp

3

Usando xdotool:

  • Primero necesitas obtener la identificación de la ventana:

sleep 3s && xdotool getactivewindow, tienes 3 segundos para abrir tu ventana

  • Entonces necesitas usar:
    1. para obtener información en la salida, use esto: xdotool getwindowgeometry $WINDOW_ID
    2. o si quieres un parámetro de shell usa esto: xdotool getwindowgeometry -shell $WINDOW_ID

0

Combinando respuestas en esta página, usé esto:

$ sleep 3 && xdotool getwindowfocus getwindowgeometry

Window 88080400
  Position: 4565,2345 (screen: 0)
  Geometry: 1186x885

Ejecute el one-liner y luego, dentro de 3 segundos, haga clic en la ventana para la que desea la posición y la geometría.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.