Comment trouver les dimensions et la position de la fenêtre avec précision, y compris les décorations?

37

J'ai essayé de déterminer la taille d'une fenêtre à utiliser dans un petit script. Ma technique actuelle utilise wmctrl -lGpour trouver les dimensions. Cependant, le problème est le suivant:

Les chiffres x et y donnés correspondent au coin supérieur gauche de la décoration de la fenêtre, tandis que la hauteur et la largeur concernent uniquement la zone de contenu. Cela signifie que si les décorations de fenêtre ajoutent 20 pixels de hauteur et 2 pixels de largeur, wmctrl signalera une fenêtre comme étant de 640 x 480, même si elle prend 660 x 482 à l'écran. C'est un problème car l'étape suivante de mon script serait d'utiliser cette zone pour indiquer à ffmpeg d'enregistrer l'écran. Je voudrais éviter de coder en dur la taille des décorations de fenêtre de ma configuration actuelle.

Ce qui conviendrait est une méthode pour obtenir la taille des décorations de fenêtre afin que je puisse les utiliser pour déterminer la position de la zone de contenu 640x480, ou un moyen d'obtenir directement la position de la zone de contenu, et non celle des décorations de fenêtre. .

Macha
la source
1
J'ai mélangé hauteur et largeur dans les figures du diagramme.
Macha
Lien d'image morte.
Ciro Santilli a annoncé
question proche mais demande aussi d' autres choses: superuser.com/questions/164047/...
Ciro Santilli新疆改造中心法轮功六四事件

Réponses:

36

Le script suivant vous donnera les coordonnées de l'écran en haut à gauche et la taille de la fenêtre (sans aucune décoration). . . . xwininfo -id $(xdotool getactivewindow)contient assez d'informations pour vous.


#!/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"
#
Peter.O
la source
Cela semble fonctionner car xdotool getactivewindowrenvoie l'identifiant de fenêtre du cadre du gestionnaire de fenêtres (qui comprend la décoration) plutôt que la fenêtre cliente qu'il contient.
Adam Spires
2
Non, cela renvoie la géométrie sans les décorations, ce qui n’est pas ce que la question a demandé. Si vous ne voulez pas que les décorations soient incluses, il existe des moyens plus simples de le faire, par exemplexdotool getactivewindow getwindowgeometry
slinkp le
1
Cela ne fonctionne pas bien pour moi (les décorations ne sont pas incluses). Cette réponse est meilleure.
Jan Warchoł
7

La réponse acceptée peut être étendue pour obtenir la fenêtre entière:

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

Bien que cela soit facile, il s’avère que cela ne fonctionne pas avec Unity dans Ubuntu 14.04 car les informations relatives sont à 0. J’ai demandé Obtenir toutes les dimensions de la fenêtre (y compris les décorations) dans Unity et obtenir une bonne réponse. Voici comment j'ai utilisé cette réponse:

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

Cette seconde méthode fonctionne à la fois dans Unity et Xfce et devrait également fonctionner dans Gnome.

Colin Keenan
la source
L'approche du haut est fausse, même en dehors de Unity sur Ubuntu, car elle suppose que les bordures gauche, droite et inférieure ont toutes la même largeur, et il n'y a aucune garantie de cela. La deuxième approche est meilleure.
Adam Spires
Je viens juste de vérifier la deuxième approche - il ne manquait aw=`xdotool getactivewindow`plus que le haut pour éviter de raccrocher à l'appel xwininfo. C’est bon à savoir car j’envisage de passer à Unity, où je ne parviens pas à faire fonctionner wmiface sans segfault.
Slinkp
@slinkp, merci d'avoir signalé la awdéfinition manquante . Je vais modifier la réponse maintenant pour ajouter cette ligne.
Colin Keenan
La deuxième partie de cela fonctionne très bien! Le seul changement que je devais faire dans Gnome 3 était de ne pas ajouter la hauteur de la barre de titre à h. Semble que la barre de titre est déjà incluse dans la hauteur qui revient xwininfo.
Jonny Asmar
7

Un moyen beaucoup plus simple d’obtenir la taille et la position de la fenêtre:

xdotool getwindowfocus getwindowgeometry
radara
la source
3

La réponse acceptée n'inclut pas explicitement la décoration de fenêtre. Pour ceux qui recherchent toujours comment obtenir la géométrie, y compris toutes les décorations, vous pouvez utiliser wmiface selon le titre de cette question, selon cette autre question https://superuser.com/questions/164047/how-to-get-accurate-window -information-dimensions-etc-in-linux-x . Exemple:

wmiface frameGeometry `wmiface activeWindow`

Ceci retourne la géométrie et la position par rapport au haut à gauche comme ceci:

650x437+0+1003

wmiface ne semble pas venir avec toutes les distributions linux (je n'ai pas trouvé de paquet le fournissant sur Mint ou Ubuntu) mais j'ai pu l'installer à partir des paquets ici: http://kde-apps.org/content/show .php? content = 40425

Et cela n’a pas de documentation ni même --help, mais le fichier README est ici:

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

slinkp
la source
Désolé - Je regrette mon upvote pour cela parce que la réponse acceptée ne comprend la décoration de fenêtre par mon commentaire à ce sujet .
Adam Spires
Je souhaite que cela soit vrai, mais malheureusement, ce commentaire est faux. Ils sont d’accord sur l’identifiant de la fenêtre active: $ wmiface activeWindow 6291772 $ xdotool getactivewindow 6291772 Mais ils ne sont pas d’accord sur la géométrie, et je peux confirmer avec, par exemple. screenruler que wmiface inclut la décoration de la fenêtre et xdotool non. Essayez par vous-même. $ wmiface frameGeometry wmiface activeWindow570x434 + 870 + 31 $ xdotool xdotool getactivewindowFenêtre getwindowgeometry 6291772 Position: 878,77 (écran: 0) Géométrie: 562x407
Slinkp
désolé, j'espère que vous pourrez déchiffrer ce que je voulais dire par là ... souhait de stackoverflow autoriserait les échantillons de code de bloc dans les commentaires.
Slinkp
3

Utiliser xdotool:

  • Vous devez d'abord obtenir l'identifiant de la fenêtre:

sleep 3s && xdotool getactivewindow, vous avez 3 secondes pour ouvrir votre fenêtre

  • Ensuite, vous devez utiliser:
    1. pour obtenir des informations en sortie, utilisez ceci: xdotool getwindowgeometry $WINDOW_ID
    2. ou si vous voulez un paramètre shell, utilisez ceci: xdotool getwindowgeometry -shell $WINDOW_ID
LyndaOlexandr
la source
0

En combinant les réponses sur cette page, j'ai utilisé ceci:

$ sleep 3 && xdotool getwindowfocus getwindowgeometry

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

Exécutez one-liner puis, dans les 3 secondes qui suivent, cliquez sur la fenêtre pour laquelle vous souhaitez connaître la position et la géométrie.

WinEunuuchs2Unix
la source