xdotool: Как искать окно по заголовку и классу с разными шаблонами (аналогично AutoHotkey)


10

xdotool позволяет искать окна с помощью подкоманды поиска. Мне нужно найти окно, которое имеет класс '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, чтобы это могло произойти где угодно в заголовке.


да, извините, опечатка, я имел в виду --name и --class. Исправлю сейчас.
t7ko

@DS, можете ли вы сказать, почему xdotool search --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 окнами, и только одно или два находятся на рабочем столе. Я понятия не имею, для чего другие. Кстати, только видимые средства могут отображаться, а не только сразу показываться на текущем рабочем столе.
Джо

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.