xdotool: Jak wyszukać okno według tytułu i klasy z różnymi wzorami (podobnie jak AutoHotkey)


10

xdotool umożliwia wyszukiwanie okien za pomocą podkomendy wyszukiwania. Muszę znaleźć okno, które ma klasę „gvim” i tytuł zawierający słowo „TODO”. Jak mam to zrobic?

Co próbowałem:

  • Możesz to zrobić xdotool search --name --class, ale zaakceptowałby tylko jeden wzorzec dla imienia i tytułu.
  • xdotool obsługuje łańcuch poleceń, ale nie mogłem znaleźć sposobu na połączenie dwóch wywołań wyszukiwania - drugie po prostu zastępuje pierwsze.

xdotooldo bani ... to taka prosta operacja i nie ma sposobu, aby zrobić to elegancko.
Yan King Yin

Odpowiedzi:


13

Moja pomoc xdotool informuje mnie, że twoje dwa przełączniki są takie same (xdotool wersja 3.20150503.1),

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

i jako taki nic nie robi. Mój xdotool robi to samo co twój, zastępując stos okien, więc zrobiłem to za pomocą skryptu powłoki. Skrypt powłoki wykonujący to, co chcesz, znajduje się poniżej:

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

Gwiazdki w instrukcji if są tam, aby wykonać dopasowanie podłańcuchowe TODO, aby mogło wystąpić w dowolnym miejscu w tytule.


tak, przepraszam, pomyłka, miałem na myśli - name i - class. Naprawię teraz.
t7ko

@DS, czy możesz powiedzieć, dlaczego xdotool search - klasa „gedit” działa teraz tylko dla gedit, ale działa dla każdego innego okna? Ta sama historia z narzędziem xprop.
Gonki

6

Byłem w stanie zidentyfikować krótkie i unikalne rozwiązanie:

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

3

Oto kolejne rozwiązanie zgodne ze sposobem UNIX!

Na pierwszy rzut oka nie jest tak piękny jak twój, @ 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'

Ale znoś mnie! Jest w tym trochę ukrytego piękna.

Krótko mówiąc, to

  1. ma strukturę liniową zamiast struktury drzewa, jak jeden zamiast dwóch wymiarów
  2. używa bardziej znanej składni powłoki .
  3. faktycznie odpowiada na twoje pytanie: lokalizuje okno.

(To, czy te punkty są zaletami, zależy od kontekstu - zignorujmy ten aspekt * ).

Pokażę ten sam kod w bardziej uporządkowanym układzie poniżej, aby ułatwić zrozumienie krok po kroku.
Zauważ jednak, że wcięcie ma na celu wyjaśnienie polecenia - nie oznacza to zagnieżdżenia, wszystko jest nadal liniowym potokiem UNIX.

To samo polecenie, po prostu podzielone za potokami ( |):

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'

Pełne polecenie, jak pokazano powyżej, podaje lokalizację gvimokna w pikselach, zwracając współrzędne pikseli względem lewego górnego rogu bieżącego (ewentualnie wirtualnego) ekranu x,y, tak jak 42,433, a może, -5375,-3809gdy jest on na pierwszym z czterech na czterech wirtualnych ekranach , a obecny jest gdzieś po prawej stronie.

Na razie skrócę polecenie, aby znaleźć tylko identyfikator okna X11 - może to wszystko, czego faktycznie potrzebował OP, nie jestem pewien:

Skrócony potok poleceń, osobne polecenie powłoki w każdym wierszu:

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

Teraz zaczyna być czytelny:

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

xdotoolKomenda searchsłuży do znalezienia okna z „ klasągvim, pozostawiając pewne „wewnętrzne” okna. Wynik jest wymieniony jako PID„s” (identyfikatory procesu).
Dla każdego PID, xargsuruchamia kolejny xdotool search, sprawdzając „name” dla naszego przykładowego wzorca TODO- po sprawdzeniu dla PID.

(Na wszelki wypadek: linie kończące się na \- tak zwane linie kontynuacji - muszą faktycznie kończyć \się znakiem spacji przed znakiem nowej linii i bez białych znaków).

Teraz wróć do pierwotnego polecenia:

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'

W pozostałej części wymieniono niektóre szczegóły dotyczące okna, w tym pozycję. Te sedmecze dowodzenia i powroty tylko x,ywartość pozycji.

Na przykład uruchomienie polecenia u góry na moim 16. wirtualnym ekranie (4 na 4), z „DO ZROBIENIA” gvimna ekranie 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

*) Zastrzeżenie: Wolę kod @ t7ko. Dużo!


Korzystanie --onlyvisiblejest przyjemne. Pomógł mi z podobnym problemem. Thunderbird można uruchomić z 14 oknami i tylko jedno lub dwa są na pulpicie. Nie mam pojęcia do czego służą inne. BTW mogą być wyświetlane tylko widoczne środki - nie tylko natychmiast widoczne na bieżącym pulpicie.
Joe

1

Krótka i elegancka odpowiedź (która wykorzystuje wmctrl):

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

Wynikowy identyfikator okna jest w formacie szesnastkowym, więc musisz przekonwertować go na dziesiętny (używany przez xdotool):

printf "%d\n" $result

Wtedy możesz zrobić cokolwiek xdotool.


1
wmctrlinstrukcja mówi, że -lnie drukuje klasy okna, tylko tytuł; więc fragment kodu nie rozwiązuje mojego problemu „szukaj według tytułu ORAZ klasy”.
t7ko

1
wmctrl -lxzapewnia klasę.
david.perez
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.