Làm cách nào để tìm ID cửa sổ X dưới con trỏ chuột trong bash?


20

Từ một tập lệnh bash, có cách nào để lấy ID của cửa sổ X dưới con trỏ chuột không?

(chỉnh sửa) Tôi cần quá trình không tương tác.

Câu trả lời:


25

xdotoolhiển thị vị trí con trỏ ( xdotool getmouselocation) và các phiên bản gần đây (kể từ 2.20110530.1) cho biết cửa sổ nào cũng ở vị trí đó . Không ai trong số xwininfo, wmctrlhoặc phiên bản cũ của xdotoolxuất hiện để có một cách để phù hợp với một cửa sổ bằng một vị trí màn hình mà nó nhìn thấy được.

Cuộc gọi thư viện X bên dưới là XQueryPointer(tương ứng với một QueryPointertin nhắn). Đây là một tập lệnh bao bọc Python đơn giản xung quanh cuộc gọi này (sử dụng ctypes). Lỗi kiểm tra phần lớn bị bỏ qua. Giả sử bạn đang sử dụng màn hình 0 (nếu bạn không biết rằng màn hình có thể có nhiều hơn một màn hình, hãy bỏ qua điều này).

#! /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

Ví dụ sử dụng:

xwininfo -tree -id $(XQueryPointer)

1
Cảm ơn Gilles: Đây là (gần như) chính xác những gì tôi cần ... Thật lý tưởng nhưng thực tế là nó trả về giá trị '0' cho chính máy tính để bàn .. Trả về ID cửa sổ khác không (cho máy tính để bàn) bằng xdotool click 1phương pháp không đồng bộ được đề cập trong nhận xét cho câu trả lời của Bruce Ediger .. ID máy tính để bàn khác không là hợp lệ vì nó trả về hình ảnh phù hợp thông qua import -window $nonzeroID screen.png.... Có một số điều chỉnh đơn giản để tập lệnh python trả về giá trị đó cho máy tính để bàn ?
Peter.O

@Gilles ... kiểm tra $(XQueryPointer)cho 0, và gọi xwininfo -rootcho tình trạng này giải quyết những đứa này .. Cảm ơn ..
Peter.O

@fred Chưa được kiểm tra vì tôi không ở trước máy unix: hãy thử in root_id.valuenếu child_id.value == 0.
Gilles 'SO- ngừng trở nên xấu xa'

Vâng, mod của bạn hoạt động tốt .. 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. Hauri 14/2/2015

21

Các xwininfolệnh cho loại đầu ra, nhưng bạn phải nhấp chuột vào cửa sổ bạn muốn thông tin về:

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

xwininfo: Window id: 0xa0000d "flask"

...

Vì vậy, làm: xwininfo | grep 'Window id:'có thể cung cấp cho bạn một cái gì đó bạn có thể phân tích ID ra.


1
Tôi cần nó để không tương tác ...
Peter.O

1
Nó có thể được thực hiện để không tương tác bằng cách chạy nó trong nền xwinfo |grep window id:' &và theo dõi nó bằng xdotool click 1... nhưng điều đó có nguy cơ tiền cảnhclick thực hiện trước khi xdotoolbắt chuột. Tôi muốn Rathen không sử dụng một danh nghĩa 'giấc ngủ n, vì vậy mặc dù câu trả lời này đang đi đúng hướng, tôi sẽ đợi một wihile để xem nếu một cái gì đó hơn inline lần lượt lên ...
Peter.O

8

Hãy thử điều này, nó chỉ sử dụng xdotool, nhưng phiên bản của nó ít nhất là "2.20110530.1"

xdotool getmouselocation --shell | grep WINDOW

để lấy id cửa sổ trực tiếp, bạn có thể sử dụng:

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

1
đã làm việc, cảm ơn, BTW điều này có thể hữu íchxdotool getmouselocation --shell | grep WINDOW | awk -F "=" '{print $2}'
user41209

1

xdotool là đủ tốt để làm như vậy.

Chạy xdotool getactivewindowvà bạn sẽ thấy kết quả (int) Cửa sổ có thể qua bất kỳ màn hình nào. Chỉ cần đọc vị trí của con trỏ x11 đang chờ nhấp chuột :) và không có vấn đề gì nếu đó là cửa sổ từ xa, vncserver hoặc máy tính để bàn thứ 3 của môi trường máy tính để bàn. Chỉ cần làm việc.

Bạn có thể chơi nó bằng cách sử dụng giấc ngủ để kiểm tra tốt hơn sleep 3; xdotool click 1+2; xdotool getactivewindow .

Tôi đã thấy rằng getwindowsfocus trả về cùng một giá trị hơn getactivewindow.

Nếu bạn thực hiện các nhấp chuột theo cách thủ công, bạn sẽ thấy menu theo ngữ cảnh, nhưng nhấp 1 + 2 sẽ kích hoạt cả hai lần nhấp khi nhấp vào vị trí chuột hiện tại và nhận id mong muốn.

Thử nó :)


1
Điều này cung cấp ID của cửa sổ hoạt động (bất cứ nơi nào cửa sổ đó có thể), bất kể cửa sổ hoạt động đó có ở dưới con trỏ chuột hay không. Theo từ ngữ của câu hỏi: "... tìm ID cửa sổ X dưới con trỏ chuột ..." (bất cứ nơi nào con chuột đó có thể).
Peter.O

1
Cảm ơn bạn đã sửa chữa, bạn đã đúng. Cập nhật . Tôi đã trộn lẫn khái niệm getmouselocation với activewindow, nhưng dù sao, xdotool vẫn đủ tuyệt vời.
m3nda

1

Nếu bạn có quyền truy cập vào python-xlib , thì đây là một pythonic ngắn hơn và nhiều hơn tương đương với câu trả lời của Gilles:

from Xlib.display import Display

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

print(result.child.id)

0

Tôi đùa giỡn với câu trả lời từ Peter.O và nghĩ ra:

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

1
Điều đó sẽ gửi một nhấp chuột, do đó, ví dụ như nhấp vào nút có con trỏ chuột. Nó sẽ báo cáo ngẫu nhiên cửa sổ nơi con trỏ đang ở nếu bạn sử dụng nhấp để tập trung, nhưng việc gửi một sự kiện nhấp chuột là gián đoạn.
Gilles 'SO- ngừng trở nên xấu xa'

0

ArchWiki có một câu trả lời tốt cho điều này:

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

Sử dụng sedbạn có thể làm điều này trong một dòng duy nhất, đó có lẽ là cách dễ đọc nhất để làm điều đó:

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

Lưu ý rằng xdotoolđã bị thiếu trong Debian tối thiểu X11 của tôi trong khi xpropđược đưa vào ( seddĩ nhiên tương tự ).

Nếu bạn không muốn rẽ nhánh sedcũng không grepthể thực hiện chuyển đổi văn bản hoàn toàn bash, điều này có thể an toàn hơn một chút trong trường hợp đầu ra xpropthay đổi một chút:

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

Dù sao, đó vẫn là một cách kỳ lạ để lưu trữ một nhiệm vụ đơn giản như vậy.


3
Điều này cung cấp ID của cửa sổ hoạt động thay vì cửa sổ dưới con trỏ chuột.
Peter.O

@ Peter.O Bạn đúng điều này không trả về cửa sổ hoạt động. Xin lỗi vì câu trả lời sai, tuy nhiên với các bài kiểm tra của tôi, nó đã hoạt động - có lẽ vì tôi đã tập trung theo dõi chuột.
Tino

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

1
Điều này cung cấp ID của cửa sổ hoạt động thay vì cửa sổ dưới con trỏ chuột.
Peter.O

Ồ, tôi đã giả sử tập trung cẩu thả (tập trung theo chuột) ở đây.
xanh lam

@blueyed Tập trung vào các cửa sổ đang hoạt động và cửa sổ này phản hồi với KEYBOARD. Chuột được theo dõi / theo dõi bởi X11 khi nó là máy chủ của nó và khi bạn nhấp vào một cửa sổ, x11 sẽ đặt tiêu điểm của trình quản lý cửa sổ thành các cửa sổ được nhấp. Tập trung không theo dõi chuột thực sự. Bạn có thể kiểm tra chạy xdotool getwindowsfocustừ bàn điều khiển và di chuyển chuột xung quanh. Giá trị sẽ giống nhau cho đến khi bạn nhấp chuột hoặc bàn phím tương tác (tab alt +, v.v.)
m3nda
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.