如何准确找到窗户尺寸和位置(包括装饰)?

如何准确找到窗户尺寸和位置(包括装饰)?

我一直在尝试计算出在小脚本中使用的窗口的大小。我目前的技术是用来wmctrl -lG找出尺寸。然而,问题是这样的:

它给出的 x 和 y 数字适用于窗口装饰的左上角,而高度和宽度仅适用于内容区域。这意味着,如果窗口装饰添加 20px 的高度和 2px 的宽度,wmctrl 将报告窗口为 640x480,即使它在屏幕上占用 660x482。这是一个问题,因为我的脚本的下一步是使用该区域告诉 ffmpeg 记录屏幕。我想避免在当前设置中对窗口装饰的大小进行硬编码。

适合的方法是获取窗口装饰的大小,以便我可以使用它们来确定 640x480 内容区域的位置,或者直接获取内容区域的位置,而不是窗口装饰的位置。

答案1

以下脚本将为您提供左上角的屏幕坐标和窗口的大小(没有任何装饰)。 。 。 。 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"
#

答案2

获取当前窗口大小和位置的更简单方法:

xdotool getwindowfocus getwindowgeometry

并获取选定的窗口大小和位置:

xdotool selectwindow getwindowgeometry

答案3

可以扩展接受的答案以获得整个窗口:

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

虽然很简单,但事实证明它不适用于 Ubuntu 14.04 中的 Unity,因为相对信息全为 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。

答案4

使用 xdotool:

  • 首先你需要获取窗口ID:

sleep 3s && xdotool getactivewindow,你有 3 秒时间打开窗户

  • 然后你需要使用:
    1. 要获取输出中的信息,请使用以下命令: xdotool getwindowgeometry $WINDOW_ID
    2. 或者如果您想要 shell 参数,请使用以下命令:xdotool getwindowgeometry -shell $WINDOW_ID

相关内容