xdotool: як шукати вікно за назвою та класом з різними візерунками (схоже на AutoHotkey)


10

xdotool дозволяє шукати Windows за допомогою підкоманди пошуку. Мені потрібно знайти вікно, яке має клас 'gvim' та заголовок, що містить слово 'TODO'. Як це зробити?

Що я спробував:

  • Можна зробити xdotool search --name --class, але він би прийняв лише один зразок і для імені, і для заголовка.
  • xdotool підтримує ланцюжок команд, але я не зміг знайти спосіб ланцюжка двох пошукових викликів - другий просто перекриває перший.

xdotoolсмокче ... це така проста операція, і немає способу зробити це елегантно.
Ян Кінг Інь

Відповіді:


13

Моя довідка xdotool повідомляє мені, що ваші два перемикачі однакові (xdotool версія 3.20150503.1),

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

і як таке нічого не робить. Мій xdotool робить те саме, що і ваш, замінюючи стек вікон, тому я це зробив зі скриптом оболонки. Сценарій оболонки, що робить те, що ви хочете, подається нижче:

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

Зірочки в операторі if є для того, щоб виконати збіг підрядкових рядків TODO, так що це може відбуватися де завгодно в заголовку.


так, вибачте, помилка, я мав на увазі - ім'я та - клас. Виправимо зараз.
t7ko

@DS чи можете ви сказати, чому пошук xdotool --class "gedit" зараз працюватиме лише для gedit, але працює для будь-якого іншого вікна? Та сама історія з утилітою xprop.
Гонкі

6

Мені вдалося визначити коротке та універсальне рішення:

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

3

Ось ще одне рішення, яке дотримується способу UNIX!

На перший погляд, він не такий гарний, як ваш, @ 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'

Але нехай зі мною! У ньому є якась прихована краса.

Словом, це

  1. має лінійну структуру , а не структуру дерева, як одну замість двох вимірів
  2. використовує більш відомий синтаксис оболонки .
  3. насправді відповідає на ваше запитання: воно знаходить вікно.

(Переваги цих моментів залежить від контексту - давайте просто ігноруємо цей аспект * .)

Я покажу той самий код у більш структурованому макеті нижче, щоб полегшити його розуміння крок за кроком.
Але зауважте, що відступ полягає в тому, щоб пояснити команду - вона не вказує на гніздування чи так, все одно це лінійний трубопровід UNIX.

Ця ж команда, щойно розділиться після труб ( |):

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'

Повна команда, як показано вище, дає розташування пікселів у gvimвікні, повертаючи координати пікселів відносно верхнього лівого кута поточного (можливо, віртуального) екрана, як x,y, наприклад 42,433, або, можливо, -5375,-3809коли він знаходиться на першому з чотирьох віртуальних екранів , а поточний десь внизу праворуч.

Поки що я скорочую команду, щоб знайти лише ідентифікатор вікна X11 - можливо, це все, що насправді було потрібно OP, не впевнений:

Скорочений конвеєр команд, окрема команда оболонки на кожному рядку:

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

Тепер він починає читати:

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

xdotoolКоманда searchвикористовується для пошуку вікна з « клас » gvim, в результаті чого деякі «внутрішні» вікна. Результат вказаний як PID's (ідентифікатори процесу).
Для кожного PID, xargsпрацює інше xdotool search, перевіряючи «ім'я» для нашого прикладу шаблону TODO- після перевірки для PID.

(На всяк випадок: рядки, що закінчуються на \- називаються рядки продовження, - насправді повинні закінчуватися \пробілом та без пробілу перед новим рядком.)

Тепер поверніться до початкової команди:

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'

У решті частини перераховані деякі деталі про вікно, включаючи положення. В sedкомандних матчах і повертає тільки x,yзначення позиції.

Наприклад, запуск команди вгорі на моєму 16-му віртуальному екрані (з 4 на 4), з "TODO" gvimна екрані 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

*) Відмова: Я віддаю перевагу коду @ t7ko. Багато!


Користуватися --onlyvisibleприємно. Допомогли мені з подібним питанням. Thunderbird може починатися з 14 вікон, а на робочому столі лише одне-два. Я поняття не маю, для чого інші. Можуть відображатися лише видимі засоби BTW - не просто одразу ж показані на поточному робочому столі.
Джо

1

Коротка та елегантна відповідь (яка використовує wmctrl):

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

Отриманий ідентифікатор вікна в шістнадцятковій формі, тому вам потрібно перетворити його в десятковий (використовуваний xdotool):

printf "%d\n" $result

Тоді ви можете робити все, що завгодно xdotool.


1
wmctrlінструкція говорить, що -lне друкує клас вікна, а лише заголовок; тому фрагмент вашого коду не вирішує мою проблему "пошук за заголовком І класом".
t7ko

1
wmctrl -lxнадає клас.
david.perez
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.