Jestem osobą, która ustawia przełączanie układu na Caps Lock, ponieważ leniwie naciskam dwa klawisze, gdy mogę naciskać jeden. Chciałbym nawet mieć dwa zbędne klawisze: jeden do włączania angielskiego układu, a drugi do rosyjskiego. Ale ten drugi zbędny klawisz to otwieranie menu kontekstowego, które jest tak zbędne, że wielu producentów laptopów się go pozbywa. Dlatego muszę zadowolić się tym, co mam.
I jeszcze nie chcę szukać ikon okien na pasku zadań podczas ich przełączania, łapać wzrokiem nazw przeglądając przez Alt+Tab, przeglądać biurka itp. Chcę nacisnąć kombinację klawiszy (w idealnym przypadku jedną, ale nie ma już wolnych zbędnych klawiszy) i od razu przejść do potrzebnego okna. Na przykład tak:
- Alt+F: Firefox
- Alt+D: Firefox (Przeglądanie prywatne)
- Alt+T: Terminal
- Alt+M: Kalkulator
- Alt+E: IntelliJ Idea
- i tak dalej.
Przy czym, po naciśnięciu, na przykład, na Alt+M chcę widzieć kalkulator niezależnie od tego, czy ta aplikacja jest aktualnie uruchomiona. Jeśli jest uruchomiona, okno powinno otrzymać fokus, a jeśli nie — uruchomić potrzebny program i przekazać fokus, gdy się załaduje.
Na przypadki, które nie są objęte poprzednim scenariuszem, chcę mieć uniwersalne kombinacje klawiszy, do których łatwo można przypisać dowolne z otwartych okien. Na przykład mam przypisane 10 kombinacji od Alt+1 do Alt+0, które nie są przypisane do żadnych programów. Mogę po prostu nacisnąć Alt+1 i okno, które jest teraz w fokusie, otrzyma fokus po naciśnięciu Alt+1.
Pod spodem opis jeszcze kilku funkcji i odpowiedź na pytanie, jak to zrobić. Ale od razu ostrzegam, że taka personalizacja „pod siebie” może wywołać silne uzależnienie, a nawet syndrom odstawienia podczas korzystania z Windows, Mac OS lub nawet obcego komputera z Linuxem.
W rzeczywistości, jeśli się nad tym zastanowić, nie używamy zbyt wielu programów na co dzień. Przeglądarka, terminal, IDE, jakiś komunikator, menedżer plików, kalkulator i to chyba wszystko. Nie potrzebuję zbyt wielu kombinacji klawiszy, aby pokryć 95% codziennych zadań.
Dla programów, w których jest otwartych kilka okien, jedno z nich można ustawić jako główne. Na przykład, gdy otwarte są kilka okien IntelliJ Idea, przypisanych do Alt+E. W normalnych warunkach, naciskając Alt+E , otworzy się jakieś okno tego programu, najprawdopodobniej to, które było otwarte jako pierwsze. Jednak, jeśli naciśniesz Alt+E Gdy jedno z okien programu jest już w fokuse, to właśnie to okno zostanie oznaczone jako główne i to do niego będzie przypisywany fokus przy kolejnych naciśnięciach kombinacji.
Główne okno można zmienić. W tym celu najpierw należy resetować kombinację, a następnie przypisać inne okno jako główne. Aby zresetować kombinację, trzeba wcisnąć tę samą kombinację, a następnie specjalną kombinację resetującą, którą mam przypisaną na Alt+Backspace. To wywoła skrypt, który anuluję oznaczenie głównego okna dla poprzedniej kombinacji. Następnie można przypisać nowe główne okno, tak jak opisano to w poprzednim akapicie. Reset przypisanego okna do uniwersalnych kombinacji odbywa się analogicznie.
Wprowadzenie wyszło długie, ale chciałem najpierw opowiedzieć, co będziemy robić, a potem wyjaśnić, jak to robić.
Dla tych, którzy mają dość czytania
Mówiąc krótko, link do skryptów znajduje się na końcu artykułu.
Ale i tak od razu nie uda się ich zainstalować i używać. Najpierw trzeba zrozumieć, jak skrypt znajduje odpowiednie okno. Bez tego nie uda się wskazać skryptowi, gdzie dokładnie należy przekazać fokus. I trzeba zrozumieć, co zrobić, jeśli nagle nie ma odpowiedniego okna.
Nie będę też zwracał uwagi na to, jak konfigurować wykonanie skryptów przy naciśnięciu kombinacji klawiszy. Na przykład, w KDE znajduje się to w Ustawieniach systemu → Skróty → Niestandardowe skróty. W innych menedżerach okien również powinno być podobnie.
Poznawanie wmctrl
Wmctrl to narzędzie konsolowe do interakcji z X Window Manager. To kluczowy program dla skryptu. Przejrzyjmy szybko, jak można go używać.
Na początek wyświetlmy listę otwartych okien:
$ wmctrl -lx
0x01e0000e -1 plasmashell.plasmashell N/A Desktop — Plasma
0x01e0001e -1 plasmashell.plasmashell N/A Plasma
0x03a00001 0 skype.Skype N/A Skype
0x04400003 0 Navigator.Firefox N/A Tłumacz Google - Mozilla Firefox
0x04400218 0 Navigator.Firefox N/A Najlepsze publikacje za dobę / Habr - Mozilla Firefox (Przeglądanie prywatne)
...Opcja -l wyświetla listę wszystkich otwartych okien, a -x dodaje do wyjścia nazwę klasy (skype.Skype, Navigator.Firefox itd.). Będzie nam tutaj potrzebny identyfikator okna (kolumna 1), nazwa klasy (kolumna 3) oraz tytuł okna (ostatnia kolumna).
Można spróbować aktywować jakieś okno za pomocą opcji -a:
$ wmctrl -a skype.Skype -xJeśli wszystko poszło zgodnie z planem, na ekranie powinno pojawić się okno Skype. Jeśli zamiast opcji -x użyjesz opcji -i, zamiast nazwy klasy można użyć id okna. Problem z id polega na tym, że zmienia się ono przy każdym uruchomieniu aplikacji i nie możemy go znać z wyprzedzeniem. Z drugiej strony, ten atrybut jednoznacznie wskazuje na okno, co może być ważne, gdy aplikacja otwiera więcej niż jedno okno. O tym troszkę później.
Na tym etapie musimy zapamiętać, że będziemy szukać odpowiedniego okna za pomocą regex w wyjściu wmctrl -lx. Ale to nie znaczy, że musimy używać czegoś skomplikowanego. Zazwyczaj wystarczy nazwa klasy lub tytuł okna.
W zasadzie główna idea już powinna być jasna. W ustawieniach globalnych skrótów klawiszowych dla twojego menedżera okien konfigurujemy odpowiednią kombinację do wykonania skryptu.
Jak korzystać ze skryptów
Na początku musisz zainstalować narzędzia konsolowe wmctrl i xdotool:
$ sudo apt-get install wmctrl xdotoolNastępnie należy pobrać skrypty i dodać je do $PATH. Zwykle umieszczam je w ~/bin:
$ cd ~/bin
$ git clone https://github.com/masyamandev/Showwin-script.git
$ ln -s ./Showwin-script/showwin showwin
$ ln -s ./Showwin-script/showwinDetach showwinDetachJeśli katalog ~/bin nie istniał, należy go utworzyć i zrestartować (lub się przelogować), w przeciwnym razie ~/bin nie będzie dostępny w $PATH. Jeśli wszystko zostało zrobione poprawnie, skrypty powinny być dostępne z konsoli i powinna działać autouzupełnianie po Tab.
Główny skrypt showwin przyjmuje 2 parametry: pierwszy to regex, na podstawie którego będziemy szukać odpowiedniego okna, a drugi parametr to polecenie, które należy wykonać, jeśli odpowiednie okno nie zostało znalezione.
Można spróbować wykonać skrypt, na przykład:
$ showwin "Mozilla Firefox$" firefoxJeśli Firefox jest zainstalowany, jego okno powinno uzyskać fokus. Nawet jeśli Firefox nie był uruchomiony, powinien się uruchomić.
Jeśli się udało, można spróbować skonfigurować wykonanie poleceń na kombinacjach klawiszy. W ustawieniach globalnych skrótów klawiszowych dodajemy:
- Alt+F: showwin «Mozilla Firefox$» firefox
- Alt+D: showwin «Mozilla Firefox (Private Browsing)$» «firefox -private-window»
- Alt+C: showwin «chromium-browser.Chromium-browser N*» chromium-browser
- Alt+X: showwin «chromium-browser.Chromium-browser I*» «chromium-browser -incognito»
- Alt+S: showwin «skype.Skype» skypeforlinux
- Alt+E: showwin «jetbrains-idea» idea.sh
I tak dalej. Każdy może skonfigurować kombinacje klawiszy i oprogramowanie według własnych upodobań.
Jeśli wszystko zostało zrobione poprawnie, przy podanych kombinacjach klawiszy będziemy mogli przełączać się między oknami prostym naciśnięciem klawiszy.
Rozczaruję miłośników Chrome'a: zwykłe okno nie da się odróżnić od incognito na podstawie wyjścia. wmctrl Nie można, mają te same nazwy klas i nagłówki okien. W zaproponowanych wyrażeniach regex znaki N* i I* są potrzebne tylko po to, aby te regularne wyrażenia się różniły, co pozwala na przypisanie różnych okien jako głównych.
Aby zresetować główne okno poprzedniej kombinacji (w rzeczywistości dla regex, który showwin był wywoływany ostatni raz), należy wywołać skrypt showwinDetach. Mam ten skrypt przypisany do kombinacji klawiszy Alt+Backspace.
Skrypt showwin ma jeszcze jedną funkcję. Kiedy jest wywoływany z jednym parametrem (w tym przypadku parametrem jest po prostu identyfikator), to w ogóle nie sprawdza regex, a wszystkie okna uważa za odpowiednie. W sobie nie wydaje się to przydatne, jednak w ten sposób możemy przypisać każde okno jako główne i szybko przełączać się do tego okna.
Mam skonfigurowane takie kombinacje:
- Alt+1: showwin „CustomKey1”
- Alt+2: showwin „CustomKey2”
- …
- Alt+0: showwin „CustomKey0”
- Alt+Backspace: showwinDetach
W ten sposób mogę przypisać dowolne okna do kombinacji Alt+1…Alt+0. Po prostu naciskając Alt+1 przypisuję bieżące okno do tej kombinacji. Można anulować przypisanie naciskając Alt+1, a potem Alt+Backspace. Lub zamknąć okno, to też działa.
Teraz opowiem trochę o technicznych szczegółach. Można ich nie czytać, a po prostu spróbować skonfigurować i zobaczyć. Ale mimo wszystko polecałbym zrozumienie cudzych skryptów przed uruchomieniem ich na swoim komputerze :).
Jak rozróżniać różne okna jednej aplikacji
W zasadzie, pierwszy przykład „wmctrl -a skype.Skype -x” był działający i można go używać. Ale przyjrzyjmy się jeszcze raz przykładzie z Firefox, w którym otwarte są 2 okna:
0x04400003 0 Navigator.Firefox N/A Google Translate - Mozilla Firefox
0x04400218 0 Navigator.Firefox N/A Najlepsze publikacje za dzień / Habr - Mozilla Firefox (Prywatne przeglądanie)Pierwsze okno — zwykły tryb, a drugie — Prywatne przeglądanie. Te okna chciałbym traktować jako różne aplikacje i przełączać się w nie za pomocą różnych kombinacji klawiszy.
Trzeba skomplikować skrypt przełączający okna. Użyłem takiego rozwiązania: wyświetlić listę wszystkich okien, zrobić grep na regex, wziąć pierwszy wiersz za pomocą head, wydobyć pierwszą kolumnę (to będzie id okna) za pomocą cut, przełączyć na okno po id.
Tutaj powinien być żart o wyrażeniach regularnych i dwóch problemach, ale w rzeczywistości nie używam niczego skomplikowanego. Wyrażenia regularne są mi potrzebne po to, aby można było określić koniec linii (znak „$”) i rozróżnić „Mozilla Firefox$” od „Mozilla Firefox (Prywatne przeglądanie)$”.
Zespół wygląda mniej więcej tak:
$ wmctrl -i -a `wmctrl -lx | grep -i "Mozilla Firefox$" | head -1 | cut -d" " -f1`Już można się domyślić o drugiej charakterystyce skryptu: jeśli grep nic nie zwrócił, oznacza to, że potrzebna aplikacja nie jest otwarta i należy ją uruchomić, wykonując polecenie z drugiego parametru. A potem okresowo sprawdzać, czy potrzebne okno się nie otworzyło, aby przekazać mu fokus. Nie będę na tym skupiać uwagi, kto potrzebuje, ten spojrzy w źródła.
Gdy okna aplikacji są nieodróżnialne
Nauczyliśmy się przekazywać fokus do okna potrzebnej aplikacji. Ale co, jeśli otwartych jest więcej niż jedno okno danej aplikacji? Do którego z nich przekazać fokus? Powyższy skrypt prawdopodobnie przekaże fokus do pierwszego otwartego okna. Chcielibyśmy jednak większej elastyczności. Chcemy mieć możliwość zapamiętania, które dokładnie okno potrzebujemy, i przełączania się do tego okna.
Pomysł był taki: Jeśli chcemy zapamiętać dla kombinacji klawiszy jakieś konkretne okno, musimy nacisnąć tę kombinację wtedy, gdy to okno jest w fokusie. W kolejnych naciśnięciach tej kombinacji fokus będzie przekazywany właśnie temu oknu, dopóki okno się nie zamknie lub nie zresetujemy tej kombinacji skryptu. showwinDetach.
Algorytm skryptu showwin wygląda mniej więcej tak:
- Sprawdź, czy wcześniej zapamiętaliśmy id okna, któremu należy przekazać fokus.
Jeśli zapamiętaliśmy i takie okno nadal istnieje, przekazujemy mu fokus i wychodzimy. - Patrzymy, które okno jest aktualnie w fokusie, a jeśli spełnia nasze oczekiwania, zapamiętujemy jego id do przyszłego przełączania się do niego i wychodzimy.
- Przechodzimy do jakiegokolwiek odpowiedniego okna, jeśli istnieje, lub otwieramy potrzebną aplikację.
Możemy uzyskać informacje o tym, które okno jest aktualnie w fokusie, za pomocą narzędzia konsolowego xdotool, przekształcając jego wyjście na format szesnastkowy:
$ printf "0xx" `xdotool getwindowfocus`Cokolwiek zapamiętywać w bashu najłatwiej tworząc pliki w wirtualnym systemie plików znajdującym się w pamięci. W Ubuntu taki system jest podłączony domyślnie w /dev/shm/. O innych dystrybucjach nic nie mogę powiedzieć, mam nadzieję, że takie rozwiązanie również tam istnieje. Można to sprawdzić poleceniem:
$ mount -l | grep tmpfsSkrypt będzie tworzyć puste katalogi w tej folderze, takie jak: /dev/shm/$USER/showwin/$SEARCH_REGEX/$WINDOW_ID. Dodatkowo przy każdym wywołaniu będzie tworzyć symlink /dev/shm/$USER/showwin/showwin_last na /dev/shm/$USER/showwin/$SEARCH_REGEX. Będzie to potrzebne, aby w razie potrzeby usunąć id okna dla określonej kombinacji za pomocą skryptu. showwinDetach.
Co można poprawić
Po pierwsze, skrypty muszą być konfigurowane ręcznie. Z pewnością, z powodu potrzeby zaangażowania się i wykonania wielu czynności samodzielnie, wielu z was nawet nie spróbuje skonfigurować systemu. Gdyby była możliwość po prostu zainstalowania pakietu i łatwej konfiguracji wszystkiego, to być może zyskałby pewną popularność. A wtedy z pewnością znalazłoby się w standardowych dystrybucjach aplikacja.
I być może można to zrobić prościej. Jeśli po identyfikatorze okna można byłoby poznać identyfikator procesu, który je stworzył, a po identyfikatorze procesu dowiedzieć się, która komenda go stworzyła, można by było zautomatyzować konfigurację. W rzeczywistości nie zgłębiałem tej kwestii, czy to, co napisałem w tym akapicie, jest możliwe. Chodzi o to, że osobiście zadowala mnie to, jak to działa teraz. Ale jeśli ktoś poza mną uzna ten sposób za wygodny i uda mu się go poprawić, chętnie skorzystam z lepszego rozwiązania.
Innym problemem, jak już pisałem, jest to, że w niektórych przypadkach okna nie mogą być od siebie odróżniane. Na razie zaobserwowałem to tylko w trybie incognito w Chrome/Chromium, ale być może gdzie indziej też takie coś występuje. W ostateczności zawsze są uniwersalne kombinacje klawiszy. Alt+1…Alt+0Znowu, korzystam z Firefoksa i dla mnie ta kwestia nie jest istotna.
Natomiast poważnym problemem dla mnie jest to, że w pracy używam Mac OS i nie udało mi się tam skonfigurować nic podobnego. Narzędzie wmctrl wydaje się, że mogłem zainstalować, ale nie działa ono dobrze na Mac OS. Coś można zrobić z aplikacją Automator, ale tak strasznie się zacina, że korzystanie z niej jest niewygodne nawet, gdy działa. Nie udało mi się także skonfigurować kombinacji klawiszy, aby działały we wszystkich programach. Jeśli ktoś wymyśli rozwiązanie – z chęcią z niego skorzystam.
Zamiast zakończenia
Niespodziewanie wyszło mi sporo słów na temat tak zdawałoby się prostej funkcjonalności. Chciałem przekazać pomysł i nie przeciążać tekstu, ale na razie nie wymyśliłem, jak łatwiej to opowiedzieć. Może w formacie wideo byłoby lepiej, ale tutaj tego nie lubią.
Trochę opowiedziałem o tym, co kryje się w skrypcie i jak go skonfigurować. Nie wdawałem się w szczegóły samego skryptu, ale ma on zaledwie 50 linii, więc łatwo się w nim odnaleźć.
Mam nadzieję, że ktoś jeszcze przetestuje ten pomysł i być może go doceni. Mogę powiedzieć, że skrypt został napisany około 3 lata temu i jest dla mnie BARDZO wygodny. Tak wygodny, że odczuwam poważny dyskomfort podczas pracy na obcych komputerach. I z moim służbowym MacBookiem.
Źródło: habr.com
