xdotool: Cara mencari jendela berdasarkan judul dan kelas dengan pola yang berbeda (mirip dengan AutoHotkey)

10

xdotool memungkinkan Anda mencari windows menggunakan sub-perintah pencariannya. Saya perlu mencari jendela, yang memiliki kelas 'gvim' dan judul yang mengandung kata 'TODO'. Bagaimana saya melakukan ini?

Apa yang saya coba:

  • Anda dapat melakukannya xdotool search --name --class, tetapi hanya menerima satu pola untuk nama dan judul.
  • xdotool mendukung perintah chaining, tetapi saya tidak dapat menemukan cara untuk menghubungkan dua panggilan pencarian - yang kedua hanya mengabaikan yang pertama.
t7ko
sumber
xdotoolMenyebalkan ... ini adalah operasi yang sederhana dan tidak ada cara untuk melakukannya dengan elegan.
Yan King Yin

Jawaban:

13

Bantuan xdotool saya memberi tahu saya bahwa kedua sakelar Anda sama (xdotool versi 3.20150503.1),

--name          check regexp_pattern agains the window name
--title         DEPRECATED. Same as --name.

dan karena itu tidak melakukan apa pun. Xdotool saya melakukan hal yang sama seperti milik Anda dengan mengganti tumpukan jendela, jadi saya melakukannya dengan skrip shell. Script shell melakukan apa yang Anda inginkan disampaikan di bawah ini:

pids=$(xdotool search --class "gvim")
for pid in $pids; do
    name=$(xdotool getwindowname $pid)
    if [[ $name == *"TODO"* ]]; then
        #Do what you want, $pid is your sought for PID,
        #matching both class gvim and TODO in title
    fi
done

Tanda bintang dalam pernyataan if ada untuk melakukan pencocokan substring TODO, sehingga hal itu dapat terjadi di mana pun dalam judul.

DS
sumber
ya, maaf, salah cetak, maksud saya --name dan --class. Akan diperbaiki sekarang.
t7ko
@DS, bisakah Anda memberi tahu mengapa pencarian xdotool --kelas "gedit" sekarang hanya akan berfungsi untuk gedit, tetapi berfungsi untuk jendela lain? Kisah yang sama dengan utilitas xprop.
Gonki
6

Saya dapat mengidentifikasi solusi pendek dan unix-way:

comm -12 \
  <(xdotool search --name  'title-pattern'  | sort) \
  <(xdotool search --class 'class-pattern'  | sort)
t7ko
sumber
3

Berikut adalah solusi lain yang mengikuti cara UNIX!

Pada pandangan pertama, itu tidak seindah milikmu, @ t7ko:

xdotool search --onlyvisible --class 'gvim' getwindowpid %@ | xargs -I{} xdotool search --all --pid {} --name 'TODO' getwindowgeometry | sed -r -n 's/.*Position: ([-0-9,+x]+) .*/\1/p'

Tapi bersabarlah! Ada beberapa keindahan tersembunyi di dalamnya.

Singkatnya, itu

  1. memiliki struktur linier , bukan struktur pohon, seperti satu bukan dua dimensi
  2. menggunakan sintaksis shell yang lebih terkenal .
  3. benar-benar menjawab pertanyaan Anda: Ini menempatkan jendela.

(Apakah poin-poin ini merupakan keuntungan tergantung pada konteks - mari kita abaikan aspek ini * .)

Saya akan menunjukkan kode yang sama dalam tata letak yang lebih terstruktur di bawah ini, untuk membuatnya lebih mudah untuk memahami langkah demi langkah.
Tetapi perhatikan indentasi adalah untuk menjelaskan perintah - itu tidak menunjukkan bersarang atau lebih, semua masih merupakan pipa UNIX linier.

Perintah yang sama, cukup bagi setelah pipa ( |):

xdotool search --onlyvisible --class 'gvim' getwindowpid %@ |
    xargs -I{} xdotool search --all --pid {} --name 'TODO' getwindowgeometry |
    sed -r -n 's/.*Position: ([-0-9,+x]+) .*/\1/p'

Perintah penuh, seperti yang ditunjukkan di atas, memberikan lokasi piksel gvimjendela, mengembalikan koordinat piksel relatif ke sudut kiri atas layar saat ini (mungkin virtual) sebagai x,y, seperti 42,433, atau mungkin -5375,-3809ketika itu pada yang pertama dari empat oleh empat layar virtual , dan yang sekarang ada di suatu tempat di sisi kanan.

Untuk saat ini, saya akan mempersingkat perintah untuk hanya menemukan jendela ID X11 - mungkin hanya itu yang sebenarnya dibutuhkan oleh OP, tidak yakin:

Pipa perintah yang dipersingkat, perintah shell yang terpisah di setiap baris:

xdotool search --onlyvisible --class 'gvim' getwindowpid %@ |
    xargs -I{} xdotool search --all --pid {} --name 'TODO'

Sekarang, itu mulai dapat dibaca:

xdotool \
    search --onlyvisible --class 'gvim' \
    getwindowpid %@ |
xargs -I{} \
    xdotool search --all --pid {} --name 'TODO' 

The xdotoolPerintah searchini digunakan untuk menemukan jendela dengan " kelas " gvim, meninggalkan beberapa "internal" jendela. Hasilnya terdaftar sebagai PID(pengidentifikasi proses).
Untuk masing-masing PID, xargsjalankan yang lain xdotool search, periksa "nama" untuk pola contoh kita TODO- setelah memeriksa PID.

(Untuk berjaga-jaga: Baris yang berakhiran \- disebut garis kelanjutan - harus benar-benar berakhir dengan \dan tidak ada spasi sebelum baris baru.)

Sekarang kembali ke perintah aslinya:

xdotool \
    search --onlyvisible --class 'gvim' \
    getwindowpid %@ |
xargs -I{} \
    xdotool \
        search --all --pid {} --name 'TODO' \
        getwindowgeometry |
sed -r -n 's/.*Position: ([-0-9,+x]+) .*/\1/p'

Bagian yang tersisa mencantumkan beberapa detail tentang jendela, termasuk posisinya. The sedpertandingan perintah dan kembali hanya x,ynilai posisi.

Sebagai contoh, menjalankan perintah di atas pada layar virtual ke-16 saya (dari 4 oleh 4), dengan "TODO" gvimdi layar 1:

$ xdotool search --onlyvisible --class 'gvim' getwindowpid %@ | xargs -I{} xdotool search --all --pid {} --name 'TODO' getwindowgeometry | sed -r -n 's/.*Position: ([-0-9,+x]+) .*/\1/p'
-7653,-4732

*) Penafian: Saya lebih suka kode @ t7ko. Banyak!

Volker Siegel
sumber
Menggunakan --onlyvisibleitu bagus. Membantu saya dengan masalah serupa. Thunderbird dapat dimulai dengan 14 jendela dan hanya satu atau dua yang ada di desktop. Saya tidak tahu untuk apa yang lainnya. BTW hanya sarana yang terlihat yang dapat ditampilkan - tidak hanya segera ditampilkan di desktop saat ini.
Joe
1

Jawaban singkat dan elegan (yang menggunakan wmctrl):

result=$(wmctrl -l | grep 'TODO - gvim' | grep -Eo '0x[0-9a-f]+')

ID jendela yang dihasilkan dalam hex, jadi Anda perlu mengubahnya menjadi desimal (digunakan oleh xdotool):

printf "%d\n" $result

Maka Anda dapat melakukan apa pun dengan xdotool.

Raja Yan Yin
sumber
1
wmctrlmanual mengatakan bahwa -ltidak mencetak kelas jendela, hanya judul; jadi cuplikan kode Anda tidak menyelesaikan masalah saya "cari berdasarkan judul DAN kelas".
t7ko
1
wmctrl -lxmemang menyediakan kelas.
david.perez