Bash'da fare işaretçisinin altında X pencere kimliğini nasıl bulabilirim?


20

Bir bash betiğinden, fare işaretçisinin altındaki X penceresinin kimliğini almanın bir yolu var mı?

Etkileşimsiz olmak için bu işleme ihtiyacım var.

Yanıtlar:


25

xdotoolişaretçi konumunu ( xdotool getmouselocation) gösterir ve son sürümler (2.20110530.1'den beri) o pencerede hangi pencerenin olduğunu belirtir . Hiçbiri xwininfo, wmctrlveya eski sürümleri xdotoolgörünür görünür olan bir ekran konumuna göre bir pencere eşleştirmek için bir yol olması.

Temel X kütüphane çağrısı XQueryPointer(bir QueryPointermesaja karşılık gelir ). İşte bu çağrı etrafında basit bir Python sarmalayıcı komut dosyası (kullanarak ctypes). Hata denetimi büyük ölçüde atlandı. Ekran 0'ı kullandığınızı varsayar (ekranların birden fazla ekrana sahip olabileceğini bilmiyorsanız, bunu dikkate almayın).

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

Kullanım örneği:

xwininfo -tree -id $(XQueryPointer)

1
Teşekkürler Gilles: Bu (neredeyse) tam olarak ihtiyacım olan şey ... Bu ideal ama masaüstünün kendisi için '0' değerini döndürdüğü için .. Sıfır olmayan bir pencere kimliği döndürülür (masaüstü için) asenkron tarafından xdotool click 1yorumlaması belirtilen yönteme Bruce Ediger en çok üzerinden uygun görüntüyü döndürür olarak cevap .. sıfır olmayan masaüstü kimliği geçerli ermeyecekse olduğunu import -window $nonzeroID screen.pngdönmek için piton komut dosyası için bazı basit çimdik .... var mı o masaüstüne için değer ?
Peter.O

@Gilles ... Bu durumu test $(XQueryPointer)etmek 0ve çağırmak xwininfo -rootbu
tuhaflığı

@fred Untested çünkü bir unix makinesinin önünde değilim: root_id.valueeğer yazdırmayı deneyin child_id.value == 0.
Gilles 'SO- kötü olmayı bırak

Evet, if child_id.value == 0: print root_id.value else: print child_id.value
modunuz

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

21

xwininfoKomut çıktısı bu tür verir, ama sen hakkında bilgi istediğiniz pencereyi tıklayın zorunda:

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

xwininfo: Window id: 0xa0000d "flask"

...

Bunu yapmak: xwininfo | grep 'Window id:'size kimliğini ayrıştırabileceğiniz bir şey verebilir.


1
Etkileşimli
olmama

1
Arka planda çalıştırarak xwinfo |grep window id:' &ve onu takip ederek etkileşimli olmayan hale getirilebilir xdotool click 1... ancak bu , fareyi clickyakalamadan önce ön planın yürütülmesi riskini taşır xdotool. Nominal bir `` uyku n '' kullanmayacağım, bu yüzden bu cevap yolda olsa da, daha fazla satır içi bir şey olup olmadığını görmek için bir süre bekleyeceğim ...
Peter.O

8

bunu deneyin, sadece xdotool kullanır, ancak sürümü en az "2.20110530.1"

xdotool getmouselocation --shell | grep WINDOW

pencere kimliğini doğrudan almak için bunu kullanabilirsiniz:

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

1
çalıştı, teşekkürler, BTW bu yararlı olabilirxdotool getmouselocation --shell | grep WINDOW | awk -F "=" '{print $2}'
user41209

1

xdotool bunu yapmak için yeterince iyidir.

Çalıştırın xdotool getactivewindowve sonucu göreceksiniz (int) Pencere HERHANGİ bir monitörün üzerinde olabilir. Sadece bir tıklama için bekleyen x11 işaretçisinin bulunduğu yeri okuyun ve uzak bir pencere, bir vncserver veya küp masaüstü ortamının 3. masaüstü olsun. Sadece çalışıyor.

Daha iyi testler için uyku modunu kullanarak oynayabilirsiniz sleep 3; xdotool click 1+2; xdotool getactivewindow.

Gördüğüm kadarıyla getwindowsfocusaynı değeri döndürüyor getactivewindow.

Tıklamaları manuel olarak yaparsanız, bağlam menüsünü görürsünüz, ancak 1 + 2'yi tıklamak, geçerli fare konumunu tıklayıp istediğiniz kimliği almak için her iki tıklamayı da tetikler.

Dene :)


1
Bu (diğer bir deyişle her yerde etkin pencerenin numarası verir pencere olabilir), bağımsız olarak olsun ya da olmasın, aktif pencere fare işaretçisi altında olduğu görülmüştür. Sorunun ifadesine göre: "... fare işaretçisinin altındaki X pencere kimliğini bulun ..." (bu fare nerede olursa olsun ).
Peter.O

1
Düzeltme için teşekkürler, haklısın. Güncellendi . Getmouselocation konseptini activewindow ile karıştırıyordum, ama her neyse, xdotool yeterince havalı.
m3nda

1

Python-xlib'e erişiminiz varsa , Gilles'in cevabına daha kısa ve daha pythonic eşdeğeri:

from Xlib.display import Display

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

print(result.child.id)

0

Peter.O'nun cevabı ile oynadım ve geldim:

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

1
Bu bir fare tıklaması gönderir, böylece fare imlecinin bulunduğu düğmeyi tıklar. Odaklanmak için tıklama kullanırsanız, imlecin bulunduğu pencereyi tesadüfen raporlar, ancak bir tıklama etkinliği göndermek bozucudur.
Gilles 'SO- kötü olmayı bırak'

0

ArchWiki'nin buna iyi bir cevabı var:

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

sedBunu kullanarak , bunu yapmanın muhtemelen en okunabilir yolu olan tek bir satırda yapabilirsiniz:

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

Not dahil edildi xdotoolbenim Debian minimal X11 eksik olduğunu unutmayın xprop(aynı şekilde sedtabii ki).

Çatallamak istemiyorsanız sedveya grepmetin dönüşümünü tamamen yapamıyorsanız, değişikliklerin biraz bashçıkması durumunda belki biraz daha güvenlidir xprop:

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

Her neyse, böyle basit bir görevi arşivlemenin garip bir yolu var.


3
Bu, fare işaretçisinin altındaki pencere yerine etkin pencerenin kimliğini verir.
Peter.O

@ Peter.O Bu doğru pencereyi döndürüyor haklısın. Yanlış cevap için özür dilerim, ancak testlerimle işe yaradı - muhtemelen odaklandığım fareyi kullandığım için.
Tino

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

1
Bu, fare işaretçisinin altındaki pencere yerine etkin pencerenin kimliğini verir.
Peter.O

Oh, burada özensiz odaklanmayı varsayıyordum (odak fareyi takip ediyor).
blueyed

@blueyed Focus etkin pencerelerde ve bu pencereler KLAVYE yanıt veriyor. Fareyi X11 izler / sunucu olarak izler ve bir pencereyi tıklattığınızda, x11 pencere yöneticisi odağını tıklatılan pencerelere ayarlar. Odak gerçekten fareyi takip etmiyor. xdotool getwindowsfocusBir konsoldan koşmayı ve fareyi hareket ettirmeyi kontrol edebilirsiniz . Fare tıklayana veya klavyeyi etkileşene kadar (alt + sekme, vb.) Değer aynı olacaktır
m3nda
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.