Wie finde ich die X-Fenster-ID unter dem Mauszeiger in Bash?

20

Gibt es in einem Bash-Skript eine Möglichkeit, die ID des X-Fensters unter dem Mauszeiger zu ermitteln?

(bearbeiten) Ich muss den Prozess nicht interaktiv sein.

Peter.O
quelle

Antworten:

25

xdotoolmacht die Zeigerposition () sichtbarxdotool getmouselocation , und neuere Versionen (seit 2.20110530.1) geben an, welches Fenster sich ebenfalls an dieser Position befindet . Keines xwininfo, wmctrloder ältere Versionen xdotoolerscheinen , einen Weg zu haben ein Fenster mit einer Bildschirmposition anzupassen , wo es sichtbar.

Der zugrunde liegende Aufruf der X-Bibliothek ist XQueryPointer(entsprechend einer QueryPointerNachricht). Hier ist ein einfaches Python-Wrapper-Skript, das diesen Aufruf umgibt (using ctypes). Fehlerprüfung weitgehend weggelassen. Angenommen, Sie verwenden Bildschirm 0 (wenn Sie nicht wissen, dass Anzeigen mehr als einen Bildschirm haben können, ignorieren Sie dies).

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

Anwendungsbeispiel:

xwininfo -tree -id $(XQueryPointer)
Gilles 'SO - hör auf böse zu sein'
quelle
1
Danke Gilles: Das ist (fast) genau das, was ich brauche ... Es ist ideal, aber dafür, dass es für den Desktop selbst den Wert '0' zurückgibt. Eine Fenster-ID ungleich Null wird zurückgegeben (für den Desktop). durch die asynchrone xdotool click 1Methode im Kommentar zu erwähnt Bruce Ediger der Antwort .. die nicht-Null - Desktop - ID gilt so sehr , wie es das entsprechende Bild über kehrt import -window $nonzeroID screen.png.... gibt es ein paar einfache zwicken für den python - Skript zurück , dass Wert für den Desktop ?
Peter.O
@ Gilles ... Testen $(XQueryPointer)für 0und Aufrufen xwininfo -rootfür diese Bedingung behebt diese Eigenart .. Danke ..
Peter.O
@fred Ungetestet, weil ich nicht vor einer Unix-Maschine stehe: Versuche zu drucken, root_id.valuewenn child_id.value == 0.
Gilles 'SO- hör auf böse zu sein'
Ja, dein Mod funktioniert gut .. 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

Der xwininfoBefehl gibt diese Art von Ausgabe aus, aber Sie müssen auf das Fenster klicken, zu dem Sie Informationen wünschen:

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

xwininfo: Window id: 0xa0000d "flask"

...

Wenn Sie dies tun xwininfo | grep 'Window id:', erhalten Sie möglicherweise etwas, aus dem Sie die ID analysieren können.

Bruce Ediger
quelle
1
Ich muss es nicht interaktiv sein ...
Peter.O
1
Es kann so eingestellt werden, dass es nicht interaktiv ist, indem es im Hintergrund ausgeführt xwinfo |grep window id:' &wird und anschließend xdotool click 1..., aber dies birgt die Gefahr, dass der Vordergrund clickausgeführt wird, bevor xdotooldie Maus greift. Ich würde raten, kein nominales `sleep n 'zu verwenden. Obwohl diese Antwort auf dem richtigen Weg ist, werde ich eine Weile warten, um zu sehen, ob etwas mehr Inline auftaucht ...
Peter.O
8

Versuchen Sie dies, es verwendet nur xdotool, aber seine Version ist mindestens "2.20110530.1"

xdotool getmouselocation --shell | grep WINDOW

Um die Fenster-ID direkt zu erhalten, können Sie Folgendes verwenden:

sedGetValue='s/.*=\(.*\)/\1/'
windowId=`xdotool getmouselocation --shell 2>/dev/null |grep WINDOW |sed "$sedGetValue"`
echo $windowId
Wassermann Power
quelle
1
funktioniert, danke, BTW das kann nützlich seinxdotool getmouselocation --shell | grep WINDOW | awk -F "=" '{print $2}'
user41209
1

xdotool ist dafür gut genug.

Führen xdotool getactivewindowSie aus und Sie werden das Ergebnis sehen (int) Das Fenster kann sich über JEDEM Monitor befinden. Lesen Sie einfach, wo sich der x11-Zeiger befindet, der auf einen Klick wartet :), und egal, ob es sich um ein Remote-Fenster, einen vncserver oder den dritten Desktop der Cube-Desktop-Umgebung handelt. Funktioniert einfach.

Sie können es zum besseren Testen mit Sleep spielen sleep 3; xdotool click 1+2; xdotool getactivewindow.

Ich habe gesehen, dass getwindowsfocusderselbe Wert als zurückgibt getactivewindow.

Wenn Sie die Klicks manuell ausführen, wird das Kontextmenü angezeigt. Wenn Sie jedoch auf 1 + 2 klicken, werden beide Klicks gleichzeitig ausgelöst, indem Sie auf die aktuelle Mausposition klicken und die gewünschte ID abrufen.

Versuch es :)

m3nda
quelle
1
Dies gibt die ID des aktiven Fensters an (wo immer sich dieses Fenster befindet), unabhängig davon, ob sich dieses aktive Fenster unter dem Mauszeiger befindet oder nicht. Nach dem Wortlaut der Frage: "... finde die X-Fenster-ID unter dem Mauszeiger ..." (wo auch immer sich diese Maus befindet).
Peter.O
1
Vielen Dank für die Korrektur, du hast Recht. Aktualisiert . Ich habe das Konzept von getmouselocation mit activewindow gemischt, aber trotzdem ist xdotool cool genug.
m3nda
1

Wenn Sie Zugriff auf python-xlib haben , finden Sie hier eine kürzere und pythonischere Entsprechung zu Gilles 'Antwort:

from Xlib.display import Display

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

print(result.child.id)
Noé Martínez
quelle
0

Ich spielte mit der Antwort von Peter.O herum und fand:

xdotool click 1|xwininfo|grep 'Window id:'
Ikem Krueger
quelle
1
Das sendet einen Mausklick, also würde es zB auf eine Schaltfläche klicken, auf der sich der Mauszeiger befindet. Es würde im Übrigen das Fenster melden, in dem sich der Cursor befindet, wenn Sie zum Fokussieren klicken, aber das Senden eines Klickereignisses stört.
Gilles 'SO- hör auf böse zu sein'
0

ArchWiki hat eine gute Antwort darauf:

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

Mit sedkönnen Sie dies in einer einzigen Zeile tun. Dies ist wahrscheinlich die am besten lesbare Methode:

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

Beachten Sie, dass xdotoolin meinem Debian-Minimal-X11 etwas fehlte, während xpropes enthalten war (ebenfalls sednatürlich).

Wenn Sie nicht verzweigen möchten oder die Textumwandlung sednicht grepvollständig durchführen können bash, ist dies möglicherweise etwas sicherer, falls sich die Ausgabe xpropetwas ändert:

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

Trotzdem ist es immer noch eine seltsame Art, eine so einfache Aufgabe zu archivieren.

Tino
quelle
3
Dies gibt die ID des aktiven Fensters anstelle des Fensters unter dem Mauszeiger an.
Peter.O
@ Peter.O Sie haben Recht, dies gibt das aktive Fenster zurück. Tut mir leid für die falsche Antwort, aber bei meinen Tests hat es funktioniert - wahrscheinlich, weil ich Focus-follows-Mouse an hatte.
Tino
0
xprop -root 2>/dev/null | sed -n '/^_NET_ACTIVE_WINDOW/ s/.* // p'
bläulich
quelle
1
Dies gibt die ID des aktiven Fensters anstelle des Fensters unter dem Mauszeiger an.
Peter.O
Oh, ich habe hier einen schlampigen Fokus angenommen (Fokus folgt der Maus).
blueyed
@blueyed Der Fokus liegt auf den aktiven Fenstern, und dieses Fenster reagiert auf KEYBOARD. Auf die Maus folgt X11 als Server, und wenn Sie auf ein Fenster klicken, setzt x11 den Fokus des Fenstermanagers auf angeklickte Fenster. Fokus folgt der Maus nicht wirklich. Sie können die Ausführung xdotool getwindowsfocusvon einer Konsole aus und das Bewegen der Maus überprüfen . Der Wert
bleibt