Аз съм от хората, които задействат Caps Lock за превключване на разредката, защото ми е мързеливо да натискам 2 бутона, когато мога да натисна само един. Дори бих желал 2 ненужни бутона: един да използвам за включване на английската разредка, а втория за руската. Но вторият ненужен бутон е за извикване на контекстното меню, което е толкова ненужно, че много производители на лаптопи го премахват. Така че ми се налага да се задоволя с това, което имам.
А още не искам при превключване на прозорците да търся иконките им на панела с инструменти, да улавям имената им при превъртане през Alt+Tab, да превъртам работните настолия и т.н. Искам да натисна комбинация от бутони (в идеалния случай дори един, но вече няма свободни ненужни бутони) и веднага да попадна в прозореца, от който се нуждая. Например така:
- Alt+F: Firefox
- Alt+D: Firefox (Частно Browsing)
- Alt+T: Терминал
- Alt+M: Калькулятор
- Alt+E: IntelliJ Idea
- и т.н.
При натискане, например, на Alt+M искам да виждам калькулятора независимо дали програмата е стартирана в момента. Ако е стартирана, фокусът трябва да бъде предаден на нейния прозорец, а ако не е — да стартира нужната програма и да предаде фокус, когато се зареди.
За случаи, които не покриват предишния сценарий, искам да имам универсални комбинации от бутони, на които лесно да мога да назначавам всякакви от отворените прозорци. Например, имам назначени 10 комбинации от Alt+1 до Alt+0, които не са свързани с никакви програми. Просто мога да натисна Alt+1 и прозорецът, който в момента е във фокус, ще получи фокус при натискане на Alt+1.
Под кота, описвам още няколко функции и отговор на въпроса как може да се направи това. Но веднага ще предупредя, че подобна персонализация "под себе си" може да предизвика сериозна зависимост и дори синдром на абстиненция при необходимост да използвате Windows, Mac OS или дори чужд компютър с Linux.
Наистина, ако се замислим, не използваме толкова много програми в ежедневието. Браузър, терминал, IDE, някой Messenger, файлов мениджър, калькулятор и, вероятно, това е почти всичко. Не са необходими толкова много комбинации от бутони, за да покрият 95% от ежедневните задачи.
За програми, при които са отворени няколко прозореца, един от тях може да бъде назначен за главен. Например, отворени са няколко прозорца на IntelliJ Idea, назначени на Alt+E. В нормални условия, при натискане на Alt+E ще се отваря някакъв прозорец на тази програма, вероятно този, който бе отворен първи. Въпреки това, ако натиснете на Alt+E Когато едно от прозорците на тази програма е активно, това прозорец ще бъде определено за основно и именно на него ще бъде предаден фокусът при следващи натискания на комбинацията.
Основното прозорец може да бъде преназначено. За целта комбинацията първо трябва да бъде нулирана, а след това на него да бъде назначено друго основно прозорец. За нулиране на комбинацията е необходимо да натиснете самата комбинация, а след това специалната комбинация за нулиране, за мен тя е назначена на Alt+Backspace. Това ще изпълни скрипт, който ще отмени назначаването на основното прозорец за предишната комбинация. След това може да назначите ново основно прозорец така, както беше описано в предишния параграф. Нулирането на свързаното прозорец към универсални комбинации става по аналогичен начин.
Въведението се получи дълго, но първо исках да разкажа какво ще правим, а след това да обясня как да го направим.
За тези, които са се уморили от четене
Ако кратко, връзката към скриптовете е в края на статията.
Но все пак веднага да инсталирате и да започнете да използвате няма да стане. Първо трябва да разберете как скриптът намира нужното прозорец. Без това не може да зададете на скрипта къде точно да предаде фокуса. И трябва да се разбере какво да се прави, ако изведнъж не е намерено подходящо прозорец.
И още, няма да се задълбочавам в това как да настроите изпълнението на скриптове при натискане на клавишни комбинации. Например, в KDE това е в System Settings → Shortcuts → Custom Shortcuts. И в други прозоречни мениджъри също трябва да има нещо подобно.
Запознаване с wmctrl
Wmctrl — конзолна утилита за взаимодействие с X Window Manager. Това е ключова програма за скрипта. Нека да разгледаме накратко как може да се използва.
Първо, ще изведем списък на отворените прозорци:
$ 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 Google Translate - Mozilla Firefox
0x04400218 0 Navigator.Firefox N/A Най-добри публикации за деня / Хабр - Mozilla Firefox (Private Browsing)
...Опция -l извежда списък на всички отворени прозорци, а -х добавя към изхода името на класа (skype.Skype, Navigator.Firefox и др.). Ще ни е нужно id на прозорец (колона 1), име на класа (колона 3) и заглавие на прозорец (последната колона).
Можете да опитате да активирате някое прозорец с помощта на опцията -a:
$ wmctrl -a skype.Skype -xАко всичко е минало по план, на екрана трябва да се появи прозорец Skype. Ако вместо опцията -x използвате опцията -i, вместо името на класа, може да се посочи id на прозореца. Проблемът с id е, че той се променя при всяко стартиране на приложението и не можем да го знаем предварително. От друга страна, този атрибут ясно указва на прозореца, което може да бъде важно, когато приложението отваря повече от един прозорец. Повече за това по-късно.
На този етап трябва да запомним, че ще търсим нужния прозорец чрез regex по изхода wmctrl -lx. Но това не означава, че трябва задължително да използваме нещо сложно. Обикновено името на класа или заглавието на прозореца е достатъчно.
В принцип, основната идея вече трябва да е ясна. В настройките за глобални бързи клавиши/шорткъти за вашия оконен мениджър настройваме нужната комбинация за изпълнение на скрипта.
Как да използваме скриптовете
За начало трябва да инсталираме конзолни утилити wmctrl и xdotool:
$ sudo apt-get install wmctrl xdotoolСлед това трябва да изтеглим скриптовете и да ги добавим в $PATH. Обикновено ги слагам в ~/bin:
$ cd ~/bin
$ git clone https://github.com/masyamandev/Showwin-script.git
$ ln -s ./Showwin-script/showwin showwin
$ ln -s ./Showwin-script/showwinDetach showwinDetachАко директорията ~/bin не е съществувала, трябва да я създадете и да се рестартирате (или презаредите сесията), в противен случай ~/bin няма да попадне в $PATH. Ако всичко е направено правилно, скриптовете трябва да са достъпни от конзолата и автозавършването по Tab трябва да работи.
Основният скрипт showwin приема 2 параметъра: първият е regex, по който ще търсим нужния прозорец, а вторият параметър е командата, която трябва да се изпълни, ако нужният прозорец не е намерен.
Може да опитате да изпълните скрипта, например:
$ showwin "Mozilla Firefox$" firefoxАко Firefox е инсталиран, фокусът трябва да бъде предаден на прозореца му. Дори ако Firefox не е стартиран, той трябва да се стартира.
Ако работи, може да опитате да настроите изпълнението на команди на комбинации. В настройките за глобални бързи клавиши/шорткъти добавяме:
- 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
И т.н. Комбинациите на клавиши и софтуера всеки може да настрои както му е удобно.
Ако всичко е направено правилно, по указаните по-горе комбинации ще можем да превключваме между прозорците с просто натискане на клавиш.
Разочаровам любителите на Chrome: обикновеното прозорец инкогнито не може да се различи по изхода. wmctrl Не може, те имат едни и същи имена на класовете и заглавията на прозорците. В предложените regex символите N* и I* са необходими само, за да се различават тези регулярки и да им се назначат различни основни прозорци.
За нулиране на основния прозорец на предишната комбинация (в действителност за regex, който showwin беше извикан последно) трябва да се извика скриптът showwinDetach. Аз съм назначил този скрипт на комбинацията от клавиши Alt+Backspace.
Скриптът showwin има още една функция. Когато се извиква с един параметър (в този случай параметърът е просто идентификатор), той изобщо не проверява regex и смята всички прозорци за подходящи. Това само по себе си изглежда безполезно, но по този начин можем да назначим всякакъв прозорец за основен и бързо да се превключваме именно към този прозорец.
Аз имам настроени следните комбинации:
- Alt+1: showwin «CustomKey1»
- Alt+2: showwin «CustomKey2»
- …
- Alt+0: showwin «CustomKey0»
- Alt+Backspace: showwinDetach
По този начин мога да свържа всякакви прозорци с комбинации Alt+1…Alt+0. Просто натискайки Alt+1 аз свързвам текущия прозорец с тази комбинация. Мога да отменя свързването, натискайки Alt+1, а затем Alt+Backspace. Или да затворя прозореца, така също работи.
Сега ще споделя малко технически подробности. Можете да не ги четете, а просто да опитате да настроите и да видите. Но все пак бих препоръчал да се запознаете с чуждите скриптове преди да ги пуснете на компютъра си :).
Как да различаваме различни прозорци на едно приложение
В принципе, първият пример «wmctrl -a skype.Skype -x» е работещ и може да се използва. Но да погледнем отново примера с Firefox, в който са отворени 2 прозореца:
0x04400003 0 Navigator.Firefox N/A Google Translate - Mozilla Firefox
0x04400218 0 Navigator.Firefox N/A Най-добри публикации за денонощие / Хабр - Mozilla Firefox (Частно сърфиране)Първият прозорец е обикновен режим, а вторият е Частно сърфиране. Тези прозорци желаем да считаме за различни приложения и да превключваме между тях с различни комбинации от клавиши.
Трябва да усложним скрипта, който превключва прозорците. Използвах следното решение: да изведа списък на всички прозорци, да направя grep по regex, да взема първия ред с помощта на head, да извлека първата колона (това ще бъде идентификатор на прозореца) с помощта на cut, да превключа на прозореца по идентификатора.
Тук би трябвало да има шега за регулярни изрази и две проблемы, но по факта не използвам нищо сложно. Регулярките ми трябват, за да мога да посоча края на реда (символ «$») и да различавам «Mozilla Firefox$» от «Mozilla Firefox (Частно сърфиране)$».
Отборът изглежда така:
$ wmctrl -i -a `wmctrl -lx | grep -i "Mozilla Firefox$" | head -1 | cut -d" " -f1`Тук вече може да се досетите за второто свойство на скрипта: ако grep не е извел нищо, това означава, че необходимо приложение не е отворено и трябва да бъде пуснато с командата от втория параметър. А след това периодично да проверявате дали необходимият прозорец не се е отворил, за да му предадете фокуса. Няма да се спирам на това, който иска, може да погледне изходния код.
Когато прозорците на приложението не са различими
И така, научихме как да предаваме фокуса на прозореца на необходимото приложение. Но какво става, ако са отворени повече от едно прозорец на приложението? Към който от тях да предадем фокуса? Скриптът по-горе вероятно ще предаде фокус на първия отворен прозорец. Въпреки това искаме повече гъвкавост. Бихме искали да имаме възможност да запомним конкретния прозорец, от който имаме нужда, и да превключваме именно към него.
Идеята беше следната: Ако искаме да запомним за комбинацията от клавиши определен прозорец, трябва да натиснем тази комбинация, когато нужният прозорец е във фокус. По-късно, при натискане на тази комбинация, фокусът ще бъде предаден именно на този прозорец. Дотогава, докато прозорецът не бъде затворен или не направим нулиране на тази комбинация в скрипта. showwinDetach.
Алгоритъмът на скрипта showwin е горе-долу такъв:
- Проверете дали сме запомнили преди id на прозореца, на който трябва да предадем фокуса.
Ако сме запомнили и този прозорец все още съществува, предаваме фокуса на него и излизаме. - Гледаме кой прозорец в момента е във фокус и ако той отговаря на нашето запитване, запомняме неговия id, за да преминем към него по-късно, и излизаме.
- Преминаваме към някой подходящ прозорец, ако такъв съществува, или отваряме необходимото приложение.
Може да разберете кой прозорец в момента е във фокус с помощта на конзолна утилита xdotool, като преобразувате нейния изход в хексадесетичен формат:
$ printf "0xx" `xdotool getwindowfocus`Нещо да запомняте в bash е най-лесно, като създавате файлове във виртуалната файлова система, която се намира в паметта. В Ubuntu такава е включена по подразбиране в /dev/shm/. За другите дистрибуции не мога да кажа нищо, надявам се, че подобно също съществува. Можете да проверите с командата:
$ mount -l | grep tmpfsСкриптът ще създава празни директории в тази папка, нещо такова: /dev/shm/$USER/showwin/$SEARCH_REGEX/$WINDOW_ID. Допълнително при всяко извикване той ще създава symlink /dev/shm/$USER/showwin/showwin_last на /dev/shm/$USER/showwin/$SEARCH_REGEX. Това ще е необходимо, за да можете при нужда да изтриете id на прозореца за определена комбинация с помощта на скрипта. showwinDetach.
Какво може да се подобри
На първо място, скриптовете трябва да се настройват ръчно. Вероятно, заради нуждата да се вникне и да се свърши много работа на ръка, много от вас дори няма да се опитат да настроят системата. Ако имаше възможност просто да се инсталира пакет и всичко да се настрои по-лесно, вероятно това щеше да придобие известна популярност. А после може би дори щяха да вградят приложението в стандартните дистрибуции.
И, възможно е да бъде направено по-лесно. Ако по id на прозореца може да се разбере id на процеса, който го е създал, а по id на процеса да се разкрие коя команда го е създала, тогава настройката би могла да се автоматизира. Всъщност не съм изследвал дали това, което написах в този абзац, е възможно. Факт е, че аз лично съм доволен от начина, по който работи в момента. Но ако на някого освен мен му изглежда удобно и някой го подобри, то аз с радост ще използвам по-доброто решение.
Другият проблем, както вече писах, е, че в някои случаи прозорците не могат да бъдат разграничени един от друг. Досега съм наблюдавал такова нещо само с incognito в chrome/chromium, но вероятно на други места също има подобно. В крайна сметка винаги съществува вариант с универсални комбинации. Alt+1…Alt+0. Отново, аз използвам Firefox и за мен лично този проблем не е съществен.
Но съществен проблем за мен е, че по работа използвам Mac OS и там не успях да настроя нищо подобно. Утилитата wmctrl изглежда, че успях да инсталирам, но тя не работи добре на Mac OS. Нещо може да се направи с приложението Automator, но то така лага, че е неудобно дори когато работи. Също не успях да настроя комбинации от клавиши, така че да работят във всички програми. Ако случайно някой измисли решение — ще се радвам да го използвам.
Вместо заключение
Получиха се неочаквано много думи за такава, изглеждаща проста функционалност. Исках да изразя идеята и да не пренаситя текста, но засега не съм измислил как да го обясня по-просто. Вероятно във формат на видео би било по-добре, но тук не обичат така.
Разказах малко за това, което се случва зад кулисите на скрипта и как да го настроя. Не навлязох в подробности за самия скрипт, но той е само 50 реда, не е трудно да се разбере.
Надявам се, че някой друг ще изпробва тази идея и, възможно, дори ще я оцени. За себе си мога да кажа, че скриптът беше написан преди около 3 години и ми е МНОГО удобно. Толкова удобно, че предизвиква сериозен дискомфорт при работа с чужди компютри. И с работния ми макбук.
Източник: habr.com
