Альтэрнатыўнае кіраванне вокнамі ў Linux

Я з тых, хто ставіць на Caps Lock пераключэнне раскладкі таму, што лянота націскаць 2 клавішы, калі можна націскаць адну. Я б нават хацеў 2 непатрэбныя клавішы: адну б я выкарыстоўваў для ўключэння ангельскай раскладкі, а другую для рускай. Але другая непатрэбная клавіша - гэта выклік кантэкстнага меню, якая настолькі непатрэбная, што выпілоўваецца шматлікімі вытворцамі наўтбукаў. Так што даводзіцца здавольвацца тым, што ёсць.

А яшчэ я не хачу пры пераключэнні вокнаў шукаць іх абразкі на панэлі задач, лавіць поглядам назвы пры гартанні праз Alt + Tab, гартаць працоўныя сталы і т. д. Я жадаю націснуць камбінацыю клавіш (у ідэале наогул адну, але вольных непатрэбных клавіш ужо няма) і адразу патрапіць у патрэбнае мне акно. Напрыклад так:

  • Alt+F: Firefox
  • Alt+D: Firefox (Private Browsing)
  • Alt+T: Terminal
  • Alt+M: Калькулятар
  • Alt+E: IntelliJ Idea
  • і г.д.

Прычым, па націску, напрыклад, на Alt+M я хачу бачыць калькулятар незалежна ад таго, ці запушчана ў дадзены момант гэтая праграма. Калі запушчана, то яе акну трэба перадаць фокус, а калі не - запусціць патрэбную праграму і перадаць фокус калі яна загрузіцца.

На выпадкі, якія не пакрываюцца папярэднім сцэнарам, я жадаю мець універсальныя камбінацыі клавіш, на якія можна лёгка прызначыць любыя з адчыненых вокнаў. Напрыклад, у мяне прызначаны 10 камбінацый ад Alt + 1 да Alt + 0, якія не прывязаныя ні да якіх праграм. Я магу проста націснуць Alt + 1 і акно, якое зараз у фокусе, будзе атрымліваць фокус пры націску Alt + 1.

Пад катом апісанне яшчэ пары фіч і адказ на тое, як можна гэта зрабіць. Але адразу папярэджу, што падобная кастамізацыя "пад сябе" можа выклікаць моцную залежнасць і нават ломку пры неабходнасці выкарыстоўваць Windows, Mac OS ці нават чужы кампутар з Linux.

Насамрэч, калі падумаць, то мы не так шмат праграм выкарыстоўваем паўсядзённа. Браўзэр, тэрмінал, IDE, нейкі месэнджэр, файлавы мэнэджар, калькулятар і, мабыць, гэта практычна ўсё. Трэба не так шмат камбінацый клавіш, каб акрыць 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 Переводчик - 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 праблема ў тым, што id акна мяняецца пры кожным запуску прыкладання і мы не можам ведаць яго загадзя. З іншага боку, гэты атрыбут адназначна паказвае на акно, што можа быць важна, калі праграма адкрывае больш за аднаго акна. Пра гэта крыху далей.

На гэтым этапе нам трэба запомніць, што мы будзем шукаць патрэбнае акно з дапамогай regex па выснове. wmctrl -lx. Але гэта ня значыць, што нам абавязкова выкарыстоўваць нешта складанае. Звычайна дастаткова імя класа або назвы акна.

У прынцыпе, асноўная ідэя ўжо павінна быць зразумелай. У наладах глабальных hotkeys/shortcuts для вашага аконнага мэнэджара наладжваем патрэбную камбінацыю на выкананне скрыпту.

Як карыстацца скрыптамі

Для пачатку трэба ўсталяваць кансольныя ўтыліты 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 не быў запушчаны, ён павінен быў запусціцца.

Калі атрымалася, то можна паспрабаваць наладзіць выкананне каманд на камбінацыі. У наладах глабальных hotkeys/shortcuts дадаем:

  • 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

І г. д. Камбінацыі клавіш і софту кожны можа наладзіць як яму зручна.
Калі ўсё атрымалася правільна, то па паказаных вышэй камбінацыях мы зможам перамыкацца паміж вокнамі простым націскам клавіш.

Расчарую аматараў хрому: звычайнае акно ён інкогніта адрозніць па выснове 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 Переводчик - Mozilla Firefox
0x04400218  0 Navigator.Firefox                   N/A Лучшие публикации за сутки / Хабр - Mozilla Firefox (Private Browsing)

Першае акно - звычайны рэжым, а другое - Private Browsing. Гэтыя вокны хацелася б лічыць рознымі праграмамі і перамыкацца ў іх па розных камбінацыях клавіш.

Трэба ўскладніць скрыпт, які пераключае вокны. Я выкарыстоўваў такое рашэнне: вывесці спіс усіх вокнаў, зрабіць Grep па regex, узяць першы радок з дапамогай галава, дастаць першую калонку (гэта будзе id акна) з дапамогай выразаць, пераключыць на акно па id.

Тут павінен быць жарт пра рэгулярныя выразы і дзве праблемы, але па факце я не выкарыстоўваю нічога складанага. Рэгуляркі мне патрэбныя для таго, каб можна было паказаць канец радка (знак "$") і адрозніваць "Mozilla Firefox$" ад "Mozilla Firefox (Private Browsing)$".

Каманда выглядае прыкладна так:

$ wmctrl -i -a `wmctrl -lx | grep -i "Mozilla Firefox$" | head -1 | cut -d" " -f1`

Тут ужо можна здагадацца пра другую асаблівасць скрыпту: калі grep нічога не выдаў, значыць патрэбнае прыкладанне не адчынена і яго трэба запусціць, выканаўшы каманду з другога параметра. А потым перыядычна правяраць ці не адчынілася патрэбнае акно, каб перадаць яму фокус. Не буду завастраць на гэтым увагу, каму трэба, той паглядзіць зыходнікі.

Калі вокны прыкладання не адрозныя

Такім чынам, мы навучыліся перадаваць фокус акну патрэбнага дадатку. Але што, калі адкапана больш аднаго акна ў прыкладання? Да якога з іх перадаваць фокус? Скрыпт вышэй перадасць, хутчэй за ўсё, першаму адчыненаму акну. Аднак, мы хацелі б большай гнуткасці. Жадалася бы мець магчымасць запомніць якое менавіта акно нам трэба і перамыкацца менавіта да гэтага акна.

Ідэя была такая: Калі мы жадаем запомніць для камбінацыі клавіш нейкае вызначанае акно, то трэба націснуць гэтую камбінацыю тады, калі патрэбнае акно ў фокусе. У далейшым пры націску гэтай камбінацыі фокус будзе аддавацца менавіта гэтаму акну. Пакуль акно не зачыніцца ці мы не зробім скід для гэтай камбінацыі скрыпту showwinDetach.

Алгарытм скрыпту showwin прыкладна такі:

  • Праверыць, ці не запомнілі мы раней id акна, якому трэба перадаць фокус.
    Калі запомнілі і такое акно ўсё яшчэ існуе, то перадаем фокус яму і выходзім.
  • Глядзім якое акно зараз у фокусе, і калі яно падыходзіць пад наш запыт, то запомнім яго id для пераходу да яго ў далейшым і выходзім.
  • Пераходзім хоць да нейкага падыходнага акна калі яно існуе або адчыняны патрэбнае прыкладанне.

Даведацца якое акно зараз у фокусе можна з дапамогай кансольнай утыліты xdotool, пераўтварыўшы яе выснову ў шаснаццатковы фармат:

$ printf "0x%08x" `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

Дадаць каментар