Come posso trovare con precisione le dimensioni e la posizione della finestra, comprese le decorazioni?


37

Ho cercato di capire le dimensioni di una finestra da utilizzare in un piccolo script. La mia tecnica attuale sta usando wmctrl -lGper scoprire le dimensioni. Tuttavia, il problema è questo:

Le figure xey che fornisce sono per la parte superiore sinistra delle decorazioni della finestra, mentre l'altezza e la larghezza sono solo per l'area del contenuto. Ciò significa che se le decorazioni delle finestre aggiungono 20 pixel di altezza e 2 pixel di larghezza, wmctrl segnalerà una finestra come 640x480, anche se occupa 660x482 sullo schermo. Questo è un problema perché il prossimo passo del mio script sarebbe usare quell'area per dire a ffmpeg di registrare lo schermo. Vorrei evitare l'hardcoding nella dimensione delle decorazioni delle finestre dalla mia configurazione attuale.

Quello che si adatterebbe è un metodo per ottenere la dimensione delle decorazioni delle finestre in modo che io possa usarle per capire la posizione dell'area del contenuto 640x480, o un modo per ottenere direttamente la posizione dell'area del contenuto, non quella delle decorazioni della finestra .


1
Ho mescolato altezza e larghezza nelle figure per il diagramma.
Macha,


Risposte:


36

Il seguente script ti fornirà le coordinate dello schermo in alto a sinistra e le dimensioni della finestra (senza alcuna decorazione). . . . xwininfo -id $(xdotool getactivewindow)contiene abbastanza informazioni per te.


#!/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"
#

Questo sembra funzionare perché xdotool getactivewindowrestituisce l'id della finestra del frame del gestore finestre (che include la decorazione) anziché la finestra del client contenuta al suo interno.
Adam Spires,

2
No, questo restituisce la geometria senza le decorazioni, che non è esplicitamente la domanda posta. Se non vuoi includere decorazioni, ci sono modi più semplici per farlo, ad esempioxdotool getactivewindow getwindowgeometry
slinkp

1
Questo non funziona bene per me (cioè le decorazioni non sono incluse). Questa risposta è migliore
Jan Warchoł,

7

La risposta accettata può essere estesa per ottenere l'intera finestra:

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

Anche se facile, si scopre che non funziona su Unity in Ubuntu 14.04 perché le informazioni relative sono tutte 0. Ho chiesto Ottieni le dimensioni della finestra intera (comprese le decorazioni) in Unity e ho ottenuto una buona risposta. Ecco come ho usato quella risposta:

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

Questo secondo metodo funziona sia in Unity che in Xfce e dovrebbe funzionare anche in Gnome.


L'approccio top è sbagliato anche al di fuori di Unity su Ubuntu perché presuppone che i bordi sinistro, destro e inferiore abbiano tutti la stessa larghezza e non è garantito. Il secondo approccio sembra migliore.
Adam Spires,

Ho appena controllato il secondo approccio: è stato necessario solo aw=`xdotool getactivewindow`aggiungere il top per evitare di rimanere agganciati alla chiamata xwininfo. È bello sapere perché sto pensando di passare a Unity, dove non riesco a far funzionare wmiface senza segfaulting.
sbattere le ciglia il

@slinkp, grazie per aver sottolineato la awdefinizione mancante . Modificherò ora la risposta per aggiungere quella riga.
Colin Keenan,

La seconda parte di questo funziona alla grande! L'unica modifica che ho dovuto apportare in Gnome 3 è stata quella di non aggiungere l'altezza della barra del titolo h. Sembra che la barra del titolo sia già inclusa nell'altezza da cui ritorna xwininfo.
Jonny Asmar,

7

Modo molto più semplice per ottenere dimensioni e posizione della finestra:

xdotool getwindowfocus getwindowgeometry

3

La risposta accettata esplicitamente non include la decorazione della finestra. Per coloro che sono ancora alla ricerca di come ottenere la geometria, comprese tutte le decorazioni, come da titolo di questa domanda, è possibile utilizzare wmiface come per questa altra domanda https://superuser.com/questions/164047/how-to-get-accurate-window -information-dimensioni-etc-in-linux-x . Esempio:

wmiface frameGeometry `wmiface activeWindow`

Ciò restituisce la geometria e la posizione relative in alto a sinistra in questo modo:

650x437+0+1003

wmiface non sembra venire con tutte le distribuzioni di Linux (non ho trovato un pacchetto che lo fornisce su Mint o Ubuntu) ma sono stato in grado di installarlo dai pacchetti qui: http://kde-apps.org/content/show .php? content = 40425

E viene fornito senza documenti né nemmeno --help, ma il README è qui:

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


Sorry - Mi dispiace mia upvote per questo, perché la risposta accettata non comprende decorazione della finestra come per il mio commento su di esso.
Adam Spires,

Vorrei che fosse vero, ma sfortunatamente quel commento è sbagliato. Sono d'accordo sull'ID della finestra attiva: $ wmiface activeWindow 6291772 $ xdotool getactivewindow 6291772 Ma non sono d'accordo sulla geometria e posso confermare con es. lo screenruler che wmiface include la decorazione della finestra e xdotool no. Provalo tu stesso. $ wmiface frameGeometry wmiface activeWindow570x434 + 870 + 31 $ xdotool getwindowgeometry xdotool getactivewindowWindow 6291772 Posizione: 878,77 (schermo: 0) Geometria: 562x407
slinkp

scusate, spero che possiate capire cosa intendevo lì ... vorrei che stackoverflow consentisse esempi di codice a blocchi nei commenti.
ciondola il

3

Utilizzando xdotool:

  • Per prima cosa devi ottenere l'ID della finestra:

sleep 3s && xdotool getactivewindow, hai 3 secondi per aprire la finestra

  • Quindi è necessario utilizzare:
    1. per ottenere informazioni in output usa questo: xdotool getwindowgeometry $WINDOW_ID
    2. o se vuoi il parametro shell usa questo: xdotool getwindowgeometry -shell $WINDOW_ID

0

Combinando le risposte in questa pagina ho usato questo:

$ sleep 3 && xdotool getwindowfocus getwindowgeometry

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

Esegui il one-liner e quindi entro 3 secondi fai clic sulla finestra per la quale desideri la posizione e la geometria.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.