装飾を含めてウィンドウの寸法と位置を正確に見つけるにはどうすればよいですか?


37

小さなスクリプトで使用するウィンドウのサイズを把握しようとしています。私の現在のテクニックはwmctrl -lG、寸法を見つけるために使用しています。ただし、問題は次のとおりです。

表示されるxとyの数字はウィンドウ装飾の左上にあり、高さと幅はコンテンツ領域のみに使用されます。これは、ウィンドウ装飾が高さ20ピクセルと幅2ピクセルを追加すると、画面上で660 x 482を占有する場合でも、wmctrlは640 x 480としてウィンドウを報告することを意味します。これは問題です。私のスクリプトの次のステップは、その領域を使用してffmpegに画面を記録するよう指示することです。現在の設定からウィンドウ装飾のサイズのハードコーディングを回避したいと思います。

適しているのは、ウィンドウ装飾のサイズを取得して640x480コンテンツ領域の位置を把握する方法、またはウィンドウ装飾ではなくコンテンツ領域の位置を直接取得する方法のいずれかです。 。


1
図の図で高さと幅を混同しました。
マチャ

デッドイメージリンク。
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は、内部に含まれるクライアントウィンドウではなく、ウィンドウマネージャフレーム(装飾を含む)のウィンドウIDを返すため、機能しているように見えます。
アダムスパイアーズ

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

簡単ですが、相対情報がすべて0であるため、Ubuntu 14.04のUnityで動作しないことが判明しました。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

この2番目の方法はUnityとXfceの両方で機能し、Gnomeでも機能するはずです。


UbuntuのUnityの外側であっても、左、右、下の境界線がすべて同じ幅であると想定されるため、上のアプローチは間違っています。これは保証されません。2番目のアプローチはより良く見えます。
アダム・スパイアーズ

2番目のアプローチをチェックしaw=`xdotool getactivewindow`ました。xwininfo呼び出しがハングしないようにするために、トップを追加するだけで済みました。これは、セグメンテーション違反なしでwmifaceを実行できないUnityに切り替えることを検討しているため、知っておくと便利です。
slinkp

@slinkp、欠落しているaw定義を指摘してくれてありがとう。その答えを編集して、その行を追加します。
コリンキーナン

これの第2部はうまくいきます!Gnome 3で行った変更は、タイトルバーの高さをに追加しないことだけでしたh。タイトルバーはから戻ってくる高さにすでに含まれているようxwininfoです。
ジョニーアス

7

ウィンドウのサイズと位置を取得するはるかに簡単な方法:

xdotool getwindowfocus getwindowgeometry

3

受け入れられた回答には、ウィンドウ装飾は明示的に含まれていません。この質問のタイトルに従って、すべての装飾を含むジオメトリ取得する方法をまだ探している人のために、この他の質問https://superuser.com/questions/164047/how-to-get-accurate-windowに従ってwmifaceを使用できます-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が、READMEは次のとおりです。

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


申し訳ありませんが、受け入れられた回答に、コメントに対するウィンドウ装飾含まれているため、これに対する賛成票を後悔してます。
アダムスパイアーズ

それが本当だったらいいのですが、残念ながらそのコメントは間違っています。彼らはアクティブなウィンドウIDについて同意します:$ wmiface activeWindow 6291772 $ xdotool getactivewindow 6291772しかし、彼らはジオメトリについて同意しません。wmifaceにはウィンドウ装飾が含まれ、xdotoolには含まれないscreenruler。自分で試してみてください。$ wmiface frameGeometry wmiface activeWindow570x434 + 870 + 31 $ xdotool getwindowgeometry xdotool getactivewindowWindow 6291772位置:878,77(画面:0)ジオメトリ:562x407
slinkp

申し訳ありませんが、あなたが私が意味することを解決できることを願っています... stackoverflowがブロックコードサンプルをコメントで許可することを願っています
slinkp

3

xdotoolの使用:

  • まず、ウィンドウIDを取得する必要があります。

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秒以内に、位置とジオメトリが必要なウィンドウをクリックします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.