如何在bash中的鼠标指针下找到X窗口ID?


20

从bash脚本中,是否可以通过某种方式在鼠标指针下获取X窗口的ID?

(编辑)我需要过程是非交互式的。

Answers:


25

xdotool公开指针位置(xdotool getmouselocation),最新版本(自2.20110530.1起)也指示哪个窗口位于该位置。没有的xwininfowmctrl或旧版本的xdotool出现有办法通过一个屏幕位置,它是可见的匹配窗口。

底层的X库调用是XQueryPointer(对应于一条QueryPointer消息)。这是围绕此调用的一个简单的Python包装器脚本(使用ctypes)。错误检查在很大程度上被省略了。假设您正在使用屏幕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
吉尔斯:谢谢(几乎)正是我所需要的...这是理想的选择,但事实上它为桌面本身返回了“ 0”值。.(对于桌面)返回了一个非零的窗口ID。通过布鲁斯·埃迪格(Bruce Ediger)的答案xdotool click 1的注释中提到的异步方法。非零桌面ID有效,因为它通过... 返回了适当的图像。是否有一些简单的调整,Python脚本可以为桌面返回值?import -window $nonzeroID screen.png
Peter.O 2011年

@Gilles ...测试$(XQueryPointer)0,并呼吁xwininfo -root这个条件解决了这个怪癖..谢谢..
Peter.O

@fred未经测试,因为我不在Unix机器前:root_id.value如果尝试打印,请尝试child_id.value == 0
吉尔斯(Gilles)'所以

是的,您的mod工作正常.. if child_id.value == 0: print root_id.value else: print child_id.value :)
Peter.O 2011年

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

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 2011年

1
可以通过在后台运行它xwinfo |grep window id:' &,然后在xdotool click 1... 后面使其成为非交互方式,但这冒着clickxdotool抓住鼠标之前执行前台的风险。我不会使用名义上的`sleep n,所以尽管这个答案是正确的,但我会等一会儿再看看是否有更多内联的出现……
Peter.O 2011年

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)窗口可以在ANY监视器上。只需读取x11指针在哪里等待单击即可:),无论它是远程窗口,vncserver还是多维数据集桌面环境的第3个桌面。正常工作。

您可以使用睡眠播放它以进行更好的测试sleep 3; xdotool click 1+2; xdotool getactivewindow

我发现getwindowsfocus返回的值与相同getactivewindow

如果您手动进行单击,将看到上下文菜单,但单击1 + 2会在单击当前鼠标位置并获得所需ID时触发两次单击。

试试吧 :)


1
这将提供活动窗口的ID(无论该窗口位于何处),无论该活动窗口是否在鼠标指针下方。按照问题的措辞:“ ...在鼠标指针下找到X窗口ID ...”(无论鼠标在哪里)。
Peter.O 2015年

1
谢谢您的纠正,对了。已更新。我将getmouselocation的概念与activewindow混合使用,但是无论如何,xdotool还是很酷的。
m3nda 2015年

1

如果您可以访问python-xlib,那么这是一个与Gilles的答案更短,更多的pythonic等效项:

from Xlib.display import Display

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

print(result.child.id)


0

ArchWiki对此有一个很好的答案:

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

使用sed您可以在一行中完成此操作,这可能是最易读的方式:

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

请注意,xdotool在我的Debian minimal X11中,缺少了它xpropsed当然也是如此)。

如果您不想分叉,sedgrep不能完全在中进行文本转换,那么在bash输出xprop更改时可能会更安全一些:

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

无论如何,它仍然是归档这种简单任务的一种奇怪方法。


3
这给出了活动窗口的ID,而不是鼠标指针下方的窗口。
Peter.O 2014年

@ Peter.O您是对的,这确实会返回活动窗口。很抱歉输入错误,但是在我的测试中仍然有效-可能是因为我一直关注鼠标。
蒂诺(Tino)

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

1
这给出了活动窗口的ID,而不是鼠标指针下方的窗口。
Peter.O 2014年

哦,我在这里假设草率的焦点(焦点跟随鼠标)。
2014年

@blueyed焦点位于活动窗口中,并且该窗口确实响应键盘。作为鼠标的服务器,X11将跟踪/跟踪鼠标,并且当您单击窗口时,x11会将窗口管理器焦点设置为单击的窗口。焦点并不是真的跟随鼠标。您可以检查xdotool getwindowsfocus从控制台运行和鼠标移动。在单击鼠标或交互键盘(alt + tab等)之前,值将保持不变
m3nda
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.