Bagaimana cara menemukan dimensi dan posisi jendela secara akurat termasuk dekorasi?


37

Saya sudah mencoba mencari tahu ukuran jendela untuk digunakan dalam skrip kecil. Teknik saya saat ini digunakan wmctrl -lGuntuk mengetahui dimensi. Namun, masalahnya adalah ini:

Angka x dan y yang diberikannya adalah untuk bagian kiri atas dekorasi jendela, sedangkan tinggi dan lebar hanya untuk area konten. Ini berarti bahwa jika dekorasi jendela menambahkan 20px tinggi dan lebar 2px, wmctrl akan melaporkan jendela sebagai 640x480, bahkan jika itu membutuhkan 660x482 di layar. Ini masalah karena langkah script saya selanjutnya adalah menggunakan area itu untuk memberitahu ffmpeg untuk merekam layar. Saya ingin menghindari hardcoding dalam ukuran dekorasi jendela dari pengaturan saya saat ini.

Apa yang cocok adalah metode untuk mendapatkan ukuran dekorasi jendela sehingga saya dapat menggunakannya untuk mengetahui posisi area konten 640x480, atau cara untuk mendapatkan posisi area konten secara langsung, bukan pada cara dekorasi jendela. .


1
Saya mencampur angka tinggi dan lebar dalam gambar untuk diagram.
Macha


Jawaban:


36

Skrip berikut akan memberi Anda co-ords layar kiri atas dan ukuran jendela (tanpa hiasan apa pun). . . . xwininfo -id $(xdotool getactivewindow)berisi informasi yang cukup untuk Anda.


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

Ini tampaknya berfungsi karena xdotool getactivewindowmengembalikan id jendela dari bingkai manajer jendela (yang mencakup dekorasi) daripada jendela klien yang terkandung di dalamnya.
Adam Spires

2
Tidak, ini mengembalikan geometri tanpa dekorasi, yang jelas bukan pertanyaannya. Jika Anda tidak ingin dekorasi disertakan, ada cara yang lebih mudah untuk melakukannya, misalnyaxdotool getactivewindow getwindowgeometry
slinkp

1
Ini tidak berfungsi dengan baik untuk saya (mis. Dekorasi tidak termasuk). Ini jawabannya lebih baik.
Jan Warchoł

7

Jawaban yang diterima dapat diperpanjang untuk mendapatkan seluruh jendela:

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

Meskipun mudah, ternyata tidak bekerja pada Unity di Ubuntu 14.04 karena info Relatif adalah semua 0. Saya bertanya Dapatkan dimensi jendela penuh (termasuk dekorasi) di Unity dan mendapat jawaban yang baik. Inilah cara saya menggunakan jawaban itu:

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

Metode kedua ini berfungsi baik di Unity dan Xfce, dan harus bekerja di Gnome juga.


Pendekatan teratas salah bahkan di luar Unity di Ubuntu karena mengasumsikan batas kiri, kanan, dan bawah semuanya sama, dan tidak ada jaminan untuk ini. Pendekatan kedua terlihat lebih baik.
Adam Spires

Saya baru saja memeriksa pendekatan kedua - hanya perlu aw=`xdotool getactivewindow`ditambahkan di bagian atas untuk menghindari panggilan xwininfo. Ini bagus untuk diketahui karena saya mempertimbangkan untuk beralih ke Unity, di mana saya tidak bisa menjalankan wmiface tanpa segfaulting.
slinkp

@slinkp, terima kasih telah menunjukkan awdefinisi yang hilang . Saya akan mengedit jawaban sekarang untuk menambahkan baris itu.
Colin Keenan

Bagian kedua ini sangat bagus! Hanya perubahan yang harus saya buat di Gnome 3 adalah tidak menambahkan tinggi batang judul h. Tampaknya batang judul sudah termasuk dalam ketinggian yang berasal dari xwininfo.
Jonny Asmar

7

Cara yang lebih sederhana untuk mendapatkan ukuran dan posisi jendela:

xdotool getwindowfocus getwindowgeometry

3

Jawaban yang diterima secara eksplisit tidak termasuk dekorasi jendela. Bagi mereka yang masih mencari cara mendapatkan geometri termasuk semua dekorasi, sesuai dengan judul pertanyaan ini, Anda dapat menggunakan wmiface sesuai pertanyaan lain ini https://superuser.com/questions/164047/how-to-get-accurate-window -information-dimension-etc-in-linux-x . Contoh:

wmiface frameGeometry `wmiface activeWindow`

Ini mengembalikan geometri dan posisi relatif ke kiri atas seperti:

650x437+0+1003

wmiface tampaknya tidak datang dengan semua distro linux (saya tidak menemukan paket menyediakannya di Mint atau Ubuntu) tetapi saya dapat menginstalnya dari paket di sini: http://kde-apps.org/content/show .php? content = 40425

Dan ia datang tanpa dokumen atau bahkan --help, tetapi README ada di sini:

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


Maaf - Saya menyesalkan upvote saya untuk ini karena jawaban yang diterima tidak termasuk dekorasi jendela sesuai komentar saya di atasnya.
Adam Spires

Saya berharap itu benar, tetapi sayangnya komentar itu salah. Mereka setuju tentang id jendela aktif: $ wmiface activeWindow 6291772 $ xdotool getactivewindow 6291772 Tapi mereka tidak setuju tentang geometri, dan saya dapat mengonfirmasi dengan misalnya. screenruler yang wmiface termasuk dekorasi jendela dan xdotool tidak. Cobalah sendiri. $ wmiface frameGeometry wmiface activeWindow570x434 + 870 + 31 $ xdotool getwindowgeometry xdotool getactivewindowWindow 6291772 Posisi: 878,77 (layar: 0) Geometri: 562x407
slinkp

maaf, harap Anda bisa mencari tahu apa yang saya maksudkan di sana ... berharap stackoverflow mengizinkan sampel kode blok dalam komentar.
slinkp

3

Menggunakan xdotool:

  • Pertama, Anda perlu mendapatkan id jendela:

sleep 3s && xdotool getactivewindow, Anda memiliki 3 detik untuk membuka jendela Anda

  • Maka Anda perlu menggunakan:
    1. untuk mendapatkan info dalam output gunakan ini: xdotool getwindowgeometry $WINDOW_ID
    2. atau jika Anda ingin parameter shell gunakan ini: xdotool getwindowgeometry -shell $WINDOW_ID

0

Menggabungkan jawaban pada halaman ini saya menggunakan ini:

$ sleep 3 && xdotool getwindowfocus getwindowgeometry

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

Jalankan one-liner dan kemudian dalam 3 detik klik pada jendela yang Anda inginkan untuk posisi dan geometri.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.