Como encontro as dimensões e a posição da janela com precisão, incluindo decorações?

37

Eu tenho tentado descobrir o tamanho de uma janela para uso em um pequeno script. Minha técnica atual está usando wmctrl -lGpara descobrir as dimensões. No entanto, o problema é este:

As figuras x e y são para o canto superior esquerdo da decoração da janela, enquanto a altura e largura são apenas para a área de conteúdo. Isso significa que, se as decorações da janela adicionarem 20px de altura e 2px de largura, o wmctrl reportará uma janela como 640x480, mesmo que ocupe 660x482 na tela. Isso é um problema porque o próximo passo do meu script seria usar essa área para informar ao ffmpeg para gravar a tela. Gostaria de evitar a codificação no tamanho da decoração da janela da minha configuração atual.

O que seria adequado é um método para obter o tamanho das decorações da janela, para que eu possa usá-las para descobrir a posição da área de conteúdo de 640x480 ou uma maneira de obter a posição da área de conteúdo diretamente, não a das decorações da janela .

Macha
fonte
11
Misturei altura e largura nas figuras do diagrama.
Macha
Link de imagem morta.
Ciro Santilli publicou 13/08/14
pergunta próxima, mas também faz outras coisas: superuser.com/questions/164047/…
Ciro Santilli escreveu:

Respostas:

36

O script a seguir fornecerá as coordenadas da tela superior esquerda e o tamanho da janela (sem nenhuma decoração). . . . xwininfo -id $(xdotool getactivewindow)contém informações suficientes para você.


#!/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
fonte
Isso parece funcionar porque xdotool getactivewindowretorna o ID da janela do quadro do gerenciador de janelas (que inclui decoração) em vez da janela do cliente contida nele.
Adam Spiers
2
Não, isso retorna a geometria sem as decorações, o que não é explicitamente o que a pergunta foi feita. Se você não deseja que as decorações sejam incluídas, há maneiras mais fáceis de fazer isso, por exemploxdotool getactivewindow getwindowgeometry
slinkp 27/01
11
Isso não funciona bem para mim (ou seja, as decorações não estão incluídas). Essa resposta é melhor.
Jan Warchoł 18/01/19
7

A resposta aceita pode ser estendida para obter a janela inteira:

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

Embora fácil, não funciona no Unity no Ubuntu 14.04, porque as informações relativas são todas 0. Perguntei: Obtenha as dimensões da janela completa (incluindo as decorações) no Unity e obtenha uma boa resposta. Aqui está como eu usei essa resposta:

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 no Unity e no Xfce, e também deve funcionar no Gnome.

Colin Keenan
fonte
A abordagem superior está errada, mesmo fora do Unity no Ubuntu, porque assume que as bordas esquerda, direita e inferior têm a mesma largura e não há garantia disso. A segunda abordagem parece melhor.
Adam Spiers
Acabei de verificar a segunda abordagem - ela só precisava ser aw=`xdotool getactivewindow`adicionada para evitar interrupção na chamada xwininfo. Isso é ótimo de saber, porque estou pensando em mudar para o Unity, onde não consigo executar o wmiface sem segfaulting.
slinkp
@ linklink, obrigado por apontar a awdefinição ausente . Vou editar a resposta agora para adicionar essa linha.
Colin Keenan
Segunda parte disso funciona muito bem! A única alteração que tive que fazer no Gnome 3 foi não adicionar a altura da barra de título h. Parece que a barra de título já está incluída na altura de retorno xwininfo.
9139 Jonny Asmar
7

Maneira muito mais simples de obter o tamanho e a posição da janela:

xdotool getwindowfocus getwindowgeometry
radara
fonte
3

A resposta aceita explicitamente não inclui decoração de janela. Para aqueles que ainda procuram obter a geometria, incluindo todas as decorações, de acordo com o título desta pergunta, você pode usar o wmiface conforme esta outra pergunta https://superuser.com/questions/164047/how-to-get-accurate-window -informações-dimensões-etc-no-linux-x . Exemplo:

wmiface frameGeometry `wmiface activeWindow`

Isso retorna a geometria e a posição em relação à parte superior esquerda da seguinte forma:

650x437+0+1003

O wmiface parece não vir com todas as distribuições linux (não encontrei nenhum pacote que o fornecesse no Mint ou Ubuntu), mas consegui instalá-lo a partir dos pacotes aqui: http://kde-apps.org/content/show .php? content = 40425

E ele vem sem documentos nem mesmo --help, mas o README está aqui:

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

slinkp
fonte
Desculpe - Lamento o meu upvote para isso, porque a resposta aceita que incluem decoração da janela como por meu comentário sobre ele.
Adam Spiers
Eu gostaria que isso fosse verdade, mas infelizmente esse comentário está errado. Eles concordam com o ID da janela ativa: $ wmiface activeWindow 6291772 $ xdotool getactivewindow 6291772 Mas eles não concordam com a geometria e posso confirmar com, por exemplo. screenruler que o wmiface inclui a decoração da janela e o xdotool não. Experimente você mesmo. $ wmiface frameGeometry wmiface activeWindow570x434 + 870 + 31 $ xdotool getwindowgeometry xdotool getactivewindowJanela 6291772 Posição: 878,77 (tela: 0) Geometria: 562x407
slinkp
desculpe, espero que você possa entender o que eu quis dizer lá ... gostaria que o stackoverflow permitisse exemplos de código de bloco nos comentários.
slinkp
3

Usando o xdotool:

  • Primeiro você precisa obter o ID da janela:

sleep 3s && xdotool getactivewindow, você tem 3 segundos para abrir sua janela

  • Então você precisa usar:
    1. para obter informações na saída, use isto: xdotool getwindowgeometry $WINDOW_ID
    2. ou se você quiser o parâmetro shell, use este: xdotool getwindowgeometry -shell $WINDOW_ID
LyndaOlexandr
fonte
0

Combinando respostas nesta página, usei isto:

$ sleep 3 && xdotool getwindowfocus getwindowgeometry

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

Execute a linha única e, em 3 segundos, clique na janela para a qual deseja a posição e a geometria.

WinEunuuchs2Unix
fonte