Как мне точно определить размеры и положение окна, включая украшения?

37

Я пытался выяснить размер окна для использования в небольшом скрипте. Моя текущая техника использует, wmctrl -lGчтобы узнать размеры. Однако проблема заключается в следующем:

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

То, что подойдет, это либо метод получения размера оконных декораций, чтобы я мог использовать их для определения положения области содержимого 640x480, либо способ непосредственного получения положения области контента, а не расположения оконных декораций. ,

Мача
источник
1
Я перепутал высоту и ширину на рисунках для диаграммы.
Мача
Мертвая ссылка на изображение.
Сиро Сантилли 新疆 改造 中心 法轮功 六四 事件
закрытый вопрос, но также и другие вопросы: superuser.com/questions/164047/…
Сиро Сантилли 13 改造 中心 法轮功 六四 事件

Ответы:

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"
#
Peter.O
источник
Кажется, это работает, потому что xdotool getactivewindowвозвращает идентификатор окна фрейма оконного менеджера (который включает в себя оформление), а не окно клиента, содержащееся в нем.
Адам Спирс
2
Нет, это возвращает геометрию без декораций, что явно не то, что задан вопрос. Если вы не хотите, чтобы украшения были включены, есть более простые способы сделать это, напримерxdotool getactivewindow getwindowgeometry
slinkp
1
Это не очень хорошо для меня (т.е. украшения не включены). Этот ответ лучше.
Ян Вархол
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`добавить top, чтобы избежать зависания при вызове xwininfo. Это приятно знать, потому что я рассматриваю возможность перехода на Unity, где я не могу запустить wmiface без segfaulting.
slinkp
@slinkp, спасибо за указание на отсутствующее awопределение. Я сейчас отредактирую ответ, чтобы добавить эту строку.
Колин Кинан
Вторая часть этого прекрасно работает! Единственное изменение, которое я должен был сделать в Gnome 3, - не добавлять высоту заголовка h. Кажется, заголовок уже включен в высоту, которая возвращается xwininfo.
Джонни Асмар
7

Намного более простой способ получить размер и положение окна:

xdotool getwindowfocus getwindowgeometry
radara
источник
3

Принятый ответ явно не включает оформление окна. Для тех, кто все еще ищет, как получить геометрию, включая все декорации, в соответствии с заголовком этого вопроса, вы можете использовать wmiface как в этом другом вопросе https://superuser.com/questions/164047/how-to-get-accurate-window -информация-размеры-и-т-в-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

slinkp
источник
Извините - я сожалею об этом, потому что принятый ответ включает в себя оформление окна согласно моему комментарию.
Адам Шпирс
Я бы хотел, чтобы это было правдой, но, к сожалению, этот комментарий неверен. Они согласны с идентификатором активного окна: $ 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
LyndaOlexandr
источник
0

Объединяя ответы на этой странице, я использовал это:

$ sleep 3 && xdotool getwindowfocus getwindowgeometry

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

Запустите однострочник и затем в течение 3 секунд нажмите на окно, для которого вы хотите положение и геометрию.

WinEunuuchs2Unix
источник