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


37

我一直在尝试找出在小脚本中使用的窗口的大小。我当前的技术wmctrl -lG用于找出尺寸。但是,问题是这样的:

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

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


1
我将图中的高度和宽度混合在一起。
Macha


Answers:


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返回的是窗口管理器框架(包括装饰)的窗口ID,而不是其中包含的客户窗口。
亚当·斯皮尔斯

2
不,这将返回没有装饰的几何图形,这显然不是问题要问的内容。如果您不希望包含装饰物,那么可以使用更简单的方法,例如xdotool getactivewindow getwindowgeometry
slinkp

1
这对我来说效果不佳(即不包括装饰品)。这个答案更好。
JanWarchoł17年

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

尽管很容易,但由于相对信息全为0,因此在Ubuntu 14.04中无法在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中也应适用。


即使在Ubuntu上的Unity外部,顶部方法也是错误的,因为它假定左边界,右边界和底边界都具有相同的宽度,并且对此不能保证。第二种方法看起来更好。
亚当·斯皮尔斯

我刚刚检查了第二种方法-它只需要aw=`xdotool getactivewindow`加起来就可以避免挂在xwininfo调用上。知道这一点很高兴,因为我正在考虑切换到Unity,在没有Unity的情况下我无法让wmiface运行。
slinkp '16

@slinkp,感谢您指出缺少的aw定义。我现在将编辑答案以添加该行。
科林·基南2016年

第二部分效果很好!我必须在Gnome 3中进行的唯一更改是不将标题栏高度添加到h。似乎标题栏已经包含在从返回的高度中xwininfo
强尼·阿斯玛

6

获取窗口大小和位置的简单得多的方法:

xdotool getwindowfocus getwindowgeometry

3

明确接受的答案不包括窗户装饰。对于那些仍在寻找如何获取包括所有装饰的几何体的人,可以按照此问题的标题使用wmiface,也可以按照此其他问题的操作使用https://superuser.com/questions/164047/how-to-get-accurate-window -information-dimensions-etc-in-linux-x中。例:

wmiface frameGeometry `wmiface activeWindow`

这将返回相对于左上角的几何形状和位置,如下所示:

650x437+0+1003

wmiface似乎并不是所有的Linux发行版都随附(我没有找到在Mint或Ubuntu上提供它的软件包),但是我能够从以下软件包中安装它:http : //kde-apps.org/content/show .php?content = 40425

它没有文档,甚至都没有--help,但是自述文件在这里:

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


抱歉-我对此表示遗憾,因为根据我的评论,接受的答案的确包含窗户装饰。
亚当·斯皮尔斯

我希望这是真的,但不幸的是,这一评论是错误的。他们同意活动窗口ID:$ wmiface activeWindow 6291772 $ xdotool getactivewindow 6297772但是他们不同意几何形状,我可以例如进行确认。wmiface包含窗口装饰,而xdotool不包含。自己尝试一下。$ wmiface frameGeometry wmiface activeWindow570x434 + 870 + 31 $ xdotool getwindowgeometry xdotool getactivewindow窗口6291772位置:878,77(屏幕:0)几何:562x407
slinkp

抱歉,希望您能弄明白我的意思...希望stackoverflow允许注释中的代码块示例。
slinkp '16

3

使用xdotool:

  • 首先,您需要获取窗口ID:

sleep 3s && xdotool getactivewindow,您有3秒的时间可以打开窗口

  • 然后,您需要使用:
    1. 要获得输出信息,请使用以下命令: xdotool getwindowgeometry $WINDOW_ID
    2. 或者,如果您希望shell参数使用此命令: xdotool getwindowgeometry -shell $WINDOW_ID

0

结合此页面上的答案,我使用了:

$ sleep 3 && xdotool getwindowfocus getwindowgeometry

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

运行单线,然后在3秒钟内单击要使用其位置和几何形状的窗口。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.