ฉันจะค้นหา ID หน้าต่าง X ภายใต้ตัวชี้เมาส์ในทุบตีได้อย่างไร


20

จากสคริปต์ทุบตีมีวิธีการรับ ID ของหน้าต่าง X ภายใต้ตัวชี้เมาส์?

(แก้ไข) ฉันต้องการให้กระบวนการเป็นแบบไม่โต้ตอบ

คำตอบ:


25

xdotoolหมายความว่าสถานที่ชี้ ( xdotool getmouselocation) และรุ่นล่าสุด (ตั้งแต่ 2.20110530.1) ระบุว่าหน้าต่างที่ตำแหน่งนั้นได้เป็นอย่างดี ไม่มีของxwininfo, wmctrlหรือรุ่นเก่าของxdotoolปรากฏว่ามีวิธีที่จะตรงกับหน้าต่างโดยตำแหน่งหน้าจอที่มันมองเห็นได้

การเรียกไลบรารี่ X พื้นฐานคือXQueryPointer(สอดคล้องกับQueryPointerข้อความ) ต่อไปนี้เป็นสคริปต์ห่อหุ้มงูหลามแบบง่าย ๆ สำหรับการโทร (โดยใช้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
ขอบคุณ Gilles: นี่คือ (เกือบ) สิ่งที่ฉันต้องการ ... มันเหมาะ แต่สำหรับความจริงที่ว่ามันส่งกลับค่า '0' สำหรับเดสก์ท็อปตัวเอง .. ID หน้าต่างที่ไม่ใช่ศูนย์จะถูกส่งกลับ (สำหรับเดสก์ท็อป) โดยไม่ตรงกันxdotool click 1วิธีที่กล่าวถึงในความคิดเห็นเพื่อบรูซเอดิเกอร์ของคำตอบ .. ไม่ใช่ศูนย์ ID สก์ท็อปเป็นถึงขนาดที่ถูกต้องเป็นมันจะกลับภาพที่เหมาะสมผ่านimport -window $nonzeroID screen.png.... มีบางบิดง่ายสำหรับหลามสคริปต์ที่จะกลับมาที่คุ้มค่าสำหรับเดสก์ทอป ?
Peter.O

@Gilles ... การทดสอบ$(XQueryPointer)สำหรับ0, และเรียกxwininfo -rootสภาพนี้แก้ไขมุมแหลมนี้ .. ขอบคุณ ..
Peter.O

@fred ยังไม่ทดลองเพราะฉันไม่ได้อยู่ในด้านหน้าของเครื่องยูนิกซ์: ลองพิมพ์ถ้า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

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

1
มันสามารถทำให้เป็นแบบไม่โต้ตอบได้โดยการเรียกใช้ในพื้นหลังxwinfo |grep window id:' &และตามด้วยxdotool click 1... แต่นั่นจะเสี่ยงต่อการทำงานเบื้องหน้าclickก่อนที่จะxdotoolจับเมาส์ ฉัน Rathen ได้ใช้น้อยนอนหลับ `n ดังนั้นแม้ว่าคำตอบนี้อยู่บนแทร็ค, ฉันจะรอ wihile เพื่อดูว่าสิ่งที่มากขึ้นแบบอินไลน์จะเปิดขึ้น ...
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
ทำงานขอบคุณ BTW สิ่งนี้อาจเป็นประโยชน์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คุณสามารถเล่นได้โดยใช้การนอนหลับที่ดีขึ้นสำหรับการทดสอบ

ฉันได้เห็นว่าผลตอบแทนคุ้มค่าเดียวกันกว่าgetwindowsfocusgetactivewindow

หากคุณคลิกด้วยตนเองคุณจะเห็นเมนูตามบริบท แต่คลิก 1 + 2 ยิงทั้งสองคลิกในเวลาคลิกที่ตำแหน่งเมาส์ปัจจุบันและรับรหัสที่ต้องการ

ลองมัน :)


1
สิ่งนี้จะให้ ID ของหน้าต่างที่ใช้งานอยู่ (ไม่ว่าหน้าต่างนั้นจะอยู่ที่ใด) ไม่ว่าหน้าต่างที่ใช้งานนั้นจะอยู่ภายใต้ตัวชี้เมาส์หรือไม่ก็ตาม ตามถ้อยคำของคำถาม: "... ค้นหา ID หน้าต่าง X ภายใต้ตัวชี้เมาส์ ... " (ไม่ว่าเมาส์นั้นจะอยู่ที่ใด)
Peter.O

1
ขอบคุณสำหรับการแก้ไขคุณถูกต้อง อัปเดตแล้ว ฉันกำลังผสมแนวความคิดของการย้ายตำแหน่งกับ activewindow แต่อย่างไรก็ตาม xdotool นั้นเท่ห์พอ
m3nda

1

หากคุณสามารถเข้าถึงpython-xlibได้นี่คือคำตอบที่สั้นกว่าและเป็น pythonic ที่เทียบเท่ากับคำตอบของ Gilles:

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
ที่ส่งการคลิกเมาส์ดังนั้นมันจะเช่นคลิกปุ่มที่เคอร์เซอร์เมาส์อยู่ มันจะรายงานหน้าต่างที่เคอร์เซอร์อยู่โดยบังเอิญถ้าคุณใช้การคลิกเพื่อโฟกัส แต่การส่งเหตุการณ์การคลิกนั้นก่อกวน
Gilles 'หยุดความชั่วร้าย' ใน

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 น้อยที่สุดของฉัน X11 ขณะที่xpropรวมอยู่ด้วย (เช่นเดียวกันsed)

หากคุณไม่ต้องการแยกsedและgrepคุณสามารถทำการแปลงข้อความทั้งหมดbashซึ่งอาจปลอดภัยกว่าเล็กน้อยในกรณีที่ผลลัพธ์ของxpropการเปลี่ยนแปลงเล็กน้อย:

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

อย่างไรก็ตามมันยังคงเป็นวิธีที่แปลกในการเก็บถาวรงานง่าย ๆ


3
สิ่งนี้จะให้ ID ของหน้าต่างที่ใช้งานแทนหน้าต่างภายใต้ตัวชี้เมาส์
Peter.O

@ Peter.O คุณถูกต้องนี่จะส่งคืนหน้าต่างที่ใช้งานอยู่ ขออภัยสำหรับคำตอบที่ผิด แต่ด้วยการทดสอบของฉันมันทำงานได้ - อาจเป็นเพราะฉันมีโฟกัส - ดังนี้ - เมาส์
Tino

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

1
สิ่งนี้จะให้ ID ของหน้าต่างที่ใช้งานแทนหน้าต่างภายใต้ตัวชี้เมาส์
Peter.O

โอ้ฉันกำลังสมมติว่าโฟกัสเลอะเทอะ (โฟกัสตามเมาส์) ที่นี่
blueyed

@blueyed Focus อยู่บนหน้าต่างที่ใช้งานอยู่และหน้าต่างนี้ตอบสนองต่อ KEYBOARD เมาส์ถูกติดตาม / ติดตามโดย X11 เนื่องจากเป็นเซิร์ฟเวอร์จากนั้นและเมื่อคุณคลิกหน้าต่าง x11 จะกำหนดโฟกัสตัวจัดการหน้าต่างให้เป็นหน้าต่างที่ถูกคลิก โฟกัสไม่ได้ติดตามเมาส์จริงๆ คุณสามารถตรวจสอบการทำงานxdotool getwindowsfocusจากคอนโซลและเลื่อนเมาส์ไปรอบ ๆ ค่าจะเหมือนเดิมจนกว่าคุณจะคลิกเมาส์หรือแป้นพิมพ์แบบโต้ตอบ (alt + tab, ฯลฯ )
m3nda
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.