Як точно визначити розміри та положення вікон, включаючи прикраси?


37

Я намагався з’ясувати розмір вікна для використання в невеликому сценарії. Моя сучасна техніка використовує wmctrl -lGдля з'ясування розмірів. Однак проблема полягає в наступному:

Цифри x та y, представлені у верхньому лівому куті, прикрашають вікно, тоді як висота та ширина - лише область вмісту. Це означає, що якщо прикраси вікон додають 20 пікселів висоти та 2 пікселів ширини, wmctrl повідомить про вікно 640x480, навіть якщо воно займає 660x482 на екрані. Це проблема, оскільки наступним кроком мого сценарію було б використовувати цю область, щоб сказати ffmpeg для запису екрана. Я хотів би уникнути жорсткого кодування розміру віконних прикрас із моєї поточної установки.

Що б підходило, це або метод отримання розміру віконних прикрас, тому я можу використовувати їх для з'ясування положення області вмісту 640x480, або спосіб отримати безпосередньо напрямок області вмісту, а не розміщення прикрас вікна. .


1
Я змішав висоту та ширину у малюнках для діаграми.
Macha

Посилання на мертве зображення.
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

близьке запитання, але також задає інші речі: superuser.com/questions/164047/…
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Відповіді:


36

Наведений нижче сценарій надасть вам упорядкування верхнього лівого екрана та розмір вікна (без будь-яких прикрас). . . . xwininfo -id $(xdotool getactivewindow)містить достатньо інформації для вас.


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

Це, здається, працює, тому що xdotool getactivewindowповертає ідентифікатор вікна кадру диспетчера вікон (що включає прикрасу), а не вікно клієнта, що міститься всередині нього.
Адам Шпієр

2
Ні, це повертає геометрію без прикрас, що явно не те, що задається питанням. Якщо ви не хочете, щоб прикраси були включені, є простіші способи зробити це, наприкладxdotool getactivewindow getwindowgeometry
slinkp

1
Це не добре працює для мене (тобто прикраси не включаються). Ця відповідь краща.
Jan Warchoł

7

Прийняту відповідь можна розширити, щоб отримати все вікно:

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

Хоча це легко, але виявляється, що це не працює над Unity в Ubuntu 14.04, оскільки відносна інформація - це 0. Я попросив Отримати повний розмір вікна (включаючи прикраси) в Unity, і я отримав хорошу відповідь. Ось як я використав цю відповідь:

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

Цей другий метод працює і в Unity, і в Xfce, і він повинен працювати і в Gnome.


Верхній підхід є помилковим навіть поза Unity на Ubuntu, оскільки він передбачає, що ліва, права та нижня межі мають однакову ширину, і на це немає гарантії. Другий підхід виглядає краще.
Адам Шпієр

Я щойно перевірив другий підхід - його потрібно було лише aw=`xdotool getactivewindow`доповнити, щоб уникнути зависання на дзвінок xwininfo. Це чудово знати, тому що я розглядаю можливість переходу на Unity, де я не можу запустити wmiface без запуску.
slinkp

@slinkp, дякую, що вказали на відсутність awвизначення. Я зараз відредагую відповідь, щоб додати цей рядок.
Колін Кінан

Друга частина цього чудово працює! Єдина зміна, яку мені довелося внести в Gnome 3, полягала в тому, щоб не додавати висоту заголовка до h. Здається, заголовок уже включений у висоту, з якої повертається xwininfo.
Джоні Асмар

7

Набагато простіший спосіб отримати розмір і положення вікна:

xdotool getwindowfocus getwindowgeometry

3

Прийнята відповідь явно не включає прикрасу вікна. Для тих, хто ще шукає, як отримати геометрію, включаючи всі прикраси, відповідно до назви цього питання, ви можете використовувати wmiface відповідно до цього іншого питання https://superuser.com/questions/164047/how-to-get-accurate-window -інформація-розміри-etc-in-linux-x . Приклад:

wmiface frameGeometry `wmiface activeWindow`

Це повертає геометрію та положення відносно лівого верхнього краю так:

650x437+0+1003

wmiface, здається, не входить у всі дистрибутиви Linux (я не знайшов пакет, що надає його на Mint або Ubuntu), але мені вдалося встановити його з пакунків тут: http://kde-apps.org/content/show .php? вміст = 40425

І він не має жодних документів, навіть не --help, але README є тут:

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


До жаль - я шкодую upvote за це , тому що загальноприйнятий відповідь дійсно включає оформлення вікон , як на мій коментар на ньому.
Адам Шпіерс

Я б хотів, щоб це було правдою, але, на жаль, цей коментар невірний. Вони погоджуються щодо активного ідентифікатора вікна: $ wmiface activeWindow 6291772 $ xdotool getactivewindow 6291772 Але вони не згодні з геометрією, і я можу підтвердити, наприклад. screenruler, що включає в себе wmiface прикраса вікна, а xdotool не робить. Спробуйте самі. $ wmiface frameGeometry wmiface activeWindow570x434 + 870 + 31 $ xdotool getwindowgeometry xdotool getactivewindowWindow 6291772 Позиція: 878,77 (екран: 0) Геометрія: 562x407
slinkp

Вибачте, сподіваюсь, ви можете розгадати, що я мав на увазі там ... бажаю, щоб stackoverflow дозволив блокувати зразки коду в коментарях.
slinkp

3

Використання xdotool:

  • Спочатку потрібно отримати ідентифікатор вікна:

sleep 3s && xdotool getactivewindow, у вас є 3 секунди, щоб відкрити вікно

  • Тоді вам потрібно використовувати:
    1. щоб отримати інформацію у висновку, скористайтеся цією: xdotool getwindowgeometry $WINDOW_ID
    2. або якщо ви хочете параметр оболонки, скористайтеся цим: xdotool getwindowgeometry -shell $WINDOW_ID

0

Поєднуючи відповіді на цій сторінці, я використав це:

$ sleep 3 && xdotool getwindowfocus getwindowgeometry

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

Запустіть однолінійку, а потім протягом 3 секунд клацніть на вікні, для якого потрібно розташування та геометрію.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.