bashのマウスポインタの下でXウィンドウIDを見つけるにはどうすればよいですか?


20

bashスクリプトから、マウスポインターの下でXウィンドウのIDを取得する方法はありますか?

(編集)プロセスを非インタラクティブにする必要があります。

回答:


25

xdotoolは、ポインターの位置(xdotool getmouselocation)を公開し、最新バージョン(2.20110530.1以降)は、その位置にあるウィンドウも示します。のいずれもxwininfowmctrlまたは以前のバージョンではxdotool、表示される画面位置によってウィンドウを一致させる方法はありません。

基礎となるXライブラリ呼び出しはXQueryPointerQueryPointerメッセージに対応)です。以下は、この呼び出し(を使用ctypes)の簡単なPythonラッパースクリプトです。エラーチェックはほとんど省略されています。画面0を使用していると仮定します(ディスプレイに複数の画面がある可能性があることを知らない場合は、これを無視してください)。

#! /usr/bin/env python
import sys
from ctypes import *
Xlib = CDLL("libX11.so.6")
display = Xlib.XOpenDisplay(None)
if display == 0: sys.exit(2)
w = Xlib.XRootWindow(display, c_int(0))
(root_id, child_id) = (c_uint32(), c_uint32())
(root_x, root_y, win_x, win_y) = (c_int(), c_int(), c_int(), c_int())
mask = c_uint()
ret = Xlib.XQueryPointer(display, c_uint32(w), byref(root_id), byref(child_id),
                         byref(root_x), byref(root_y),
                         byref(win_x), byref(win_y), byref(mask))
if ret == 0: sys.exit(1)
print child_id.value

使用例:

xwininfo -tree -id $(XQueryPointer)

1
ありがとう、Gilles:これは(ほぼ)私が必要とするものです...これは理想的ですが、デスクトップ自体に対して '0'の値を返すという事実のために..ゼロ以外のウィンドウIDが返されます(デスクトップ用)非同期でxdotool click 1のコメントで述べた方法ブルースEdigerのそれは経由で適切な画像を返すような答え..ゼロ以外のデスクトップIDは有効insomuchでimport -window $nonzeroID screen.png返すようにPythonスクリプトのためのいくつかの簡単な微調整を....あり、そのデスクトップの値を?
Peter.O

@Gilles ... この条件をテスト$(XQueryPointer)0xwininfo -rootこの条件を呼び出すと、この癖が解消されます。ありがとうございます。
Peter.O

私はUNIXマシンの前にいないよので、未テスト@fred:印刷してみてくださいroot_id.value場合child_id.value == 0
ジル 'SO-悪であるのをやめる'

はい、あなたのmodは正常に動作します.. if child_id.value == 0: print root_id.value else: print child_id.value :)
Peter.O

sed /x[0-9]\\++/q\;d <(xwininfo -tree -id $(XQueryPointer))
F.ハウリ

21

このxwininfoコマンドはこの種の出力を提供しますが、情報が必要なウィンドウをクリックする必要があります。

% xwininfo
xwininfo: Please select the window about which you
          would like information by clicking the
          mouse in that window.

xwininfo: Window id: 0xa0000d "flask"

...

そのxwininfo | grep 'Window id:'ため、IDを解析できるものが提供される場合があります。


1
非インタラクティブにする必要があります
...-Peter.O

1
バックグラウンドxwinfo |grep window id:' &で実行することで非インタラクティブにすることができますが、その後に続くことで、マウスをつかむ前にxdotool click 1フォアグラウンドがclick実行されるリスクxdotoolがあります。私は名目上の「スリープn」を使用しないので、この回答は進行中ですが、何かインラインが現れるかどうかを確認するために、少し待っています
...-Peter.O

8

これを試してください、それはxdotoolのみを使用しますが、そのバージョンは少なくとも「2.20110530.1」です

xdotool getmouselocation --shell | grep WINDOW

ウィンドウIDを直接取得するには、これを使用できます:

sedGetValue='s/.*=\(.*\)/\1/'
windowId=`xdotool getmouselocation --shell 2>/dev/null |grep WINDOW |sed "$sedGetValue"`
echo $windowId

1
おかげで、ところでこれは有用であるかもしれない、働いていたxdotool getmouselocation --shell | grep WINDOW | awk -F "=" '{print $2}'
user41209

1

xdotoolはそうするのに十分です。

実行するxdotool getactivewindowと結果が表示されます(int)ウィンドウはどのモニターでもかまいません。クリックを待つx11ポインターの場所を読むだけで:)、それがリモートウィンドウ、vncserver、またはキューブデスクトップ環境の3番目のデスクトップであるかどうかは関係ありません。ただ動作します。

より良いテストのために、スリープを使用して再生できますsleep 3; xdotool click 1+2; xdotool getactivewindow

私はそれgetwindowsfocusと同じ値を返すことがわかりましたgetactivewindow

手動でクリックすると、コンテキストメニューが表示されますが、1 + 2をクリックすると、現在のマウス位置をクリックして目的のIDを取得すると同時に両方のクリックが発生します。

それを試してみてください :)


1
これにより、アクティブウィンドウがマウスポインターの下にあるかどうかに関係なく、アクティブウィンドウのID(そのウィンドウがどこにあってもよい)が得られます。質問の文言によると:「...マウスポインターの下でXウィンドウIDを見つけてください...」(マウスがどこにあっても)。
Peter.O

1
訂正ありがとうございます。を更新しました。getmouselocationの概念とactivewindowを組み合わせていましたが、とにかく、xdotoolは十分クールです。
m3nda

1

python-xlibにアクセスできる場合、Gillesの答えと同等の、より短くてよりPython的なものがあります。

from Xlib.display import Display

display = Display()
window = display.screen().root
result = window.query_pointer()

print(result.child.id)

0

私はPeter.Oからの答えをいじって、思いついた:

xdotool click 1|xwininfo|grep 'Window id:'

1
これはマウスクリックを送信するため、たとえばマウスカーソルがあるボタンをクリックします。クリックを使用してフォーカスを合わせると、カーソルが置かれているウィンドウが偶然報告されますが、クリックイベントの送信は中断されます。
ジル 'SO-悪であるのをやめる'

0

ArchWikiにはこれに対する良い答えがあります:

activeWinLine=$(xprop -root | grep "_NET_ACTIVE_WINDOW(WINDOW)")
activeWinId=${activeWinLine:40}

を使用sedすると、これを1行で実行できます。これはおそらく最も読みやすい方法です。

activeWin="$(xprop -root | sed -n 's/^_NET_ACTIVE_WINDOW(WINDOW): window id # //p')"

xdotool私のDebian最小限X11の中で行方不明になりましたxprop(同様に含まれていたsedもちろん)。

分岐したくない場合sedgrep、テキスト変換を完全に行うことができないbash場合は、出力がxprop少し変更された場合にもう少し安全です。

activeWin="$(xprop -root)"
activeWin="${activeWin#*_NET_ACTIVE_WINDOW(WINDOW):}'
activeWin="${activeWin%%?_NET_*}'
activeWin="${activeWin##* }'

とにかく、このような単純なタスクをアーカイブする奇妙な方法です。


3
これにより、マウスポインターの下のウィンドウではなく、アクティブウィンドウのIDが得られます。
Peter.O

@ Peter.Oそうです、これはアクティブなウィンドウを返します。間違った答えで申し訳ありませんが、私のテストではうまくいきました-おそらくフォーカスフォローマウスを持っていたためです。
ティノ

0
xprop -root 2>/dev/null | sed -n '/^_NET_ACTIVE_WINDOW/ s/.* // p'

1
これにより、マウスポインターの下のウィンドウではなく、アクティブウィンドウのIDが得られます。
Peter.O 14年

ああ、私はここでずさんなフォーカス(フォーカスはマウスに従う)を想定していました。
14年

@blueyedフォーカスはアクティブなウィンドウにあり、このウィンドウはキーボードに応答します。マウスはサーバーであるためX11が追跡/追跡し、ウィンドウをクリックすると、x11はウィンドウマネージャーのフォーカスをクリックされたウィンドウに設定します。フォーカスは本当にマウスに追従しません。xdotool getwindowsfocusコンソールからの実行とマウスの動きを確認できます。マウスをクリックするかキーボードを操作するまで(alt + tabなど)値は同じになります
m3nda
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.