Як знайти ідентифікатор вікна X під вказівником миші в bash?


20

З скрипту bash, чи є спосіб отримати ідентифікатор вікна X під вказівником миші?

(редагувати) Мені потрібно, щоб процес був не інтерактивним.

Відповіді:


25

xdotoolвідкриває розташування вказівника ( xdotool getmouselocation), а останні версії (починаючи з 2.20110530.1) вказують, яке вікно також знаходиться в цьому місці . Жоден з xwininfo, wmctrlабо більш ранні версії 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" для самого робочого столу. Повертається ненульовий ідентифікатор вікна (для робочого столу) асинхронним xdotool click 1методом, згаданим у коментарі до відповіді Брюса Едігера . Ненульовий ідентифікатор робочого столу дійсний, оскільки він повертає відповідне зображення через import -window $nonzeroID screen.png.... Чи є кілька простих налаштувань для сценарію python, щоб повернути це значення для робочого столу ?
Пітер.O

@Gilles ... Тестування $(XQueryPointer)на 0, і виклик xwininfo -rootдля цього умови усуває цієї примхи .. Спасибо ..
Peter.O

@fred Неперевірено, тому що я не перед машиною Unix: спробуйте надрукувати, root_id.valueякщо child_id.value == 0.
Жил "ТАК - перестань бути злим"

Так, ваш мод працює чудово .. 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))
Ф. Хаурі

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:'може дати вам щось, з чого можна розібрати ідентифікатор.


1
Мені потрібно, щоб це було не інтерактивним ...
Peter.O

1
Запустивши його у фоновому режимі xwinfo |grep window id:' &та дотримуючись його, його можна зробити неінтерактивним xdotool click 1... але це ризикує clickвиконати передній план перед xdotoolсхопленням миші. Я б Rathen не використовувати номінальну `сон п, так що, хоча ця відповідь на трасі, я буду чекати wihile , щоб побачити , якщо що - то більш рядний повертає вгору ...
Peter.O

8

спробуйте це, він використовує лише xdotool, але його версія принаймні "2.20110530.1"

xdotool getmouselocation --shell | grep WINDOW

щоб отримати ідентифікатор вікна безпосередньо, ви можете скористатися цим:

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}'
користувач41209

1

xdotool досить хороший для цього.

Біжи xdotool getactivewindow і ви побачите результат (int) У вікні може бути будь-який монітор. Просто прочитайте, де знаходиться вказівник x11, який очікує натискання :), і незалежно від того, чи це віддалене вікно, vncserver або 3-й робочий стіл середовища куба. Просто працює.

Ви можете грати в режим сну для кращого тестування sleep 3; xdotool click 1+2; xdotool getactivewindow .

Я бачу, що getwindowsfocusповертає те саме значення, що іgetactivewindow .

Якщо ви робите клацання вручну, ви побачите контекстне меню, але натисніть кнопку 1 + 2, натиснувши на обидва кліки, натисніть на поточне місце миші та отримаєте потрібний ідентифікатор.

Спробуй це :)


1
Це дає ідентифікатор активного вікна (всюди , де це вікно може бути), незалежно від того , що активне вікно під курсором миші. У відповідності з формулюванням питання: «... знайти X вікна ID під покажчиком миші ...» (там , де що миша може бути).
Пітер.О

1
Дякую за виправлення, ви праві. Оновлено . Я змішував поняття getmouselocation з activewindow, але все одно, xdotool досить класний.
м3нда

1

Якщо у вас є доступ до python-xlib , ось коротший і більш пітонічний еквівалент відповіді Жиля:

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
Це посилає клацання миші, тому воно, наприклад, натисне кнопку, де знаходиться курсор миші. Це випадково повідомить про вікно, в якому знаходиться курсор, якщо ви використовуєте натискання для фокусування, але надсилання події клацання є руйнівним.
Жиль "ТАК - перестань бути злим"

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
Це дає ідентифікатор активного вікна замість вікна під вказівником миші.
Пітер.O

@ Peter.O Ви праві, це повертає активне вікно. Вибачте за неправильну відповідь, проте з моїми тестами це спрацювало - ймовірно, тому, що я мав фокус-слідкувати мишкою.
Тіно

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

1
Це дає ідентифікатор активного вікна замість вікна під вказівником миші.
Пітер.O

О, я тут припускав неохайний фокус (фокус слід за мишкою).
синюха

@blueyed Фокус знаходиться на активних вікнах, і ці вікна реагують на KEYBOARD. Миша супроводжується / відслідковується X11 як її сервер, і коли ви клацаєте вікно, x11 встановлює фокус-менеджер вікон на натиснуті вікна. Фокус насправді не слідкуйте за мишкою. Ви можете перевірити біг xdotool getwindowsfocusз консолі та переміщення миші. Значення буде таким самим, поки ви не натиснете клавішу миші або взаємодієте з клавіатурою (alt + вкладка тощо)
m3nda
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.