XMonad: Има ли начин за обвързване на едновременно задействан клавишен акорд?

Има ли начин едновременните натискания на клавиши да се превърнат в свързване на клавиши, напр. за клавишите w, e, f, когато бъдат натиснати в рамките на 0,05 секунди един от друг, за да задействат команда?

За да бъдем по-конкретни:

  1. Ако w, e, f са натиснати в рамките на 0,05 секунди един от друг, тогава при натискане на последното XMonad трябва да задейства споменатата команда . XMonad също трябва да е прихванал трите ключа, така че да не бъдат излишно изпратени до фокусирания прозорец.

  2. В противен случай (ако поне един от тях не бъде натиснат в рамките на период от 0,05 секунди) XMonad трябва да изпрати клавишите към фокусирания прозорец, както обикновено.

Моята цел в това е да използвам w, e, f за "Избягане" в подобен на vim "Нормален режим", XMonad. Действия. Подкарта (подкарта).


Актуализирайте с неуспешен метод, в случай че някой види начин да го поправи:

Опитах се да приложа това с помощта на подкарти, така че, например, ако натиснете w, ще свършите в chord_mode_w, ако натиснете e оттам, ще свършите в chord_mode_we и ако натиснете f оттам, накрая ще стигнете до normal_mode, например. Внедряването беше много объркано: включих в основните си клавишни връзки нещо като:

("w", spawn "xdotool key <chord_mode_w_keybinding> ; sleep 0.05 ; xdotool key <abort_keybinding>")
(chord_mode_w_keybinding, chord_mode_w)

за откриване на w (останалото би било подобно), заедно с (непълни) подкарти като:

 chord_mode_w = submap . mkKeymap c $
              [
                      ("e",  chord_mode_we )
                    , ("f",  chord_mode_wf )
                    , (abort_keybinding, pasteString "w")

                    -- in order for the submap to not eat all other letters,
                    -- would need to include all mappings like:
                    , ("a", pasteString "wa")
                    , ("b", pasteString "wb")
                    ...
              ]

 chord_mode_we = submap . mkKeymap c $
               [
                      ("f",  normal_mode )
                    , (abort_keybinding, pasteString "we")


                    -- in order for the submap to not eat all other letters,
                    -- would need to include all mappings like:
                    , ("a", pasteString "wea")
                    , ("b", pasteString "web")
                    ...
               ]

 chord_mode_wf = submap . mkKeymap c $
               [
                      ("e",  normal_mode )
                    , (abort_keybinding, pasteString "wf")

                    -- in order for the submap to not eat all other letters,
                    -- would need to include all mappings like:
                    , ("a", pasteString "wfa")
                    , ("b", pasteString "wfb")
                    ...
               ]

Цялостното внедряване очевидно би било много объркано, но на теория трябваше да ме изпрати до normal_mode, ако натисна "wef" в рамките на 0,05 секунди един от друг, прекъсвайки и изписвайки знаците в противен случай. Имаше обаче два проблема:

  1. pasteString (както и другите функции за поставяне в XMonad.Util.Paste) е твърде бавен за нормално писане

  2. Ще се окажа в normal_mode само малка част от времето, дори ако настроя забавянето на прекъсването много по-високо. Не съм сигурен за причината зад това.

(Причината, поради която използвах pasteString при прекъсване, вместо да създам друг xdotool, беше, че изходът от xdotool ще задейства отново едно от chord_mode_w_keybinding, chord_mode_e_keybinding, chord_mode_f_keybinding, обратно в главните клавишни връзки, връщайки ме обратно към режимите на акорд за неопределено време.)


person spacingissue    schedule 02.01.2015    source източник
comment
Не искам да звуча арогантно, но мисля, че не разбирам въпроса ви. Има пример в Submap документация. Искате ли да имате такова забавяне (0.05 s) или какво точно е това, което примерът не прави за вас?   -  person deshtop    schedule 02.01.2015
comment
Направих редакция, която се надявам да изясни въпроса. Активирането на подкарта беше само примерът, за който исках да я използвам; въпросът наистина е за това как човек би се заел да прави ключови акорди за свързване на клавиши.   -  person spacingissue    schedule 03.01.2015


Отговори (1)


https://hackage.haskell.org/package/xmonad-contrib-0.13/docs/XMonad-Actions-Submap.html

Submap наистина прави почти това, което искате (достига ви по-голямата част от пътя) ... и аз ще ви предложа да промените това, което се опитвате да направите, дори и леко, и тогава Submaps се справят перфектно.

Можете да конфигурирате Submap да улавя w ключово събитие и да започнете да чакате e, което след това изчаква f. Дори опитах това и потвърдих, че работи:

, ((0, xK_w), submap . M.fromList $
    [ ((0, xK_e),    submap . M.fromList $
      [ ((0, xK_f),  spawn "notify-send \"wef combo detected!\"" ) ])
    ])

Горното обаче почти със сигурност не е нещо, което всъщност бихте искали да направите... тъй като вече е невъзможно да изпратите w натискане на клавиш към прозорец (трябваше да деактивирам тази конфигурация, преди да напиша този отговор, което изискваше изпращане на няколко w натискания на клавиш събития към активния прозорец)

Поведението, което видях току-що, когато играх с това, е: ако натисна w, xmonad улавя това събитие (не го изпраща в активния прозорец) и сега е в състояние, в което чака или e, или нещо друго ... ако натисна нещо друго, xmonad вече не е в това състояние, но не "възпроизвежда" тези уловени събития. Така че, ако натисна w и след това някой друг клавиш, който не е e, резултатът е само, че xmonad се връща извън състоянието на слушане за ключове в подкартата. Никога не позволява w да премине към активния прозорец... което ми се стори неудобно.

Вашите опции, както виждам, са: 1) задоволете се с първоначалното свързване на клавиши с модификатор, така че вашата команда с множество клавиши ще бъде Mod4-w e f 2) намерете начин да хакнете логиката на забавяне, която описахте, в действието в подкартата

Започнах да използвам конфигурация като тази, където влагам концептуално подобни действия, които са рядко необходими под дърво от вложени подкарти, аналогично на това, което поставих по-горе. Коренът на това дърво обаче винаги има модификатор, така че не краде натискания на клавиши, които искам да препратя към активния прозорец. Използвам Mod3-semicolon като корен на това дърво и след това има много немодифицирани натискания на клавиши, които са само букви (те са мнемоника за действията).

За мен това изглежда като по-добро решение, вместо да чакам няколкостотин милисекунди и след това да препращам събитията, освен ако не съвпадат. Чувствам, че ще го намеря за досадно, тъй като би забавило всяко събитие w натискане на клавиш...

YMMV, надявам се да помогне на някого

person Blake Miller    schedule 15.08.2015
comment
Това е наистина полезно! Въпреки това получавам проблем, когато дефинирам множество комбинации, които започват с един и същ ключ: работи само последната посочена комбинация, всички останали се игнорират - какъв може да е проблемът? - person user905686; 31.08.2017
comment
Това, което описвате, работи за мен. Мога ли да ви предложа да зададете нов въпрос и да публикувате кода, който използвате? Мисля, че докато първият ключ е обвързан с подкарта (както е в моя пример), трябва да работи. Ако коментирате тук с връзка към вашия въпрос, ще се опитам да помогна. - person Blake Miller; 12.09.2017
comment
Благодаря ви, публикувах нов въпрос. - person user905686; 14.09.2017
comment
Имайте предвид, че има submapDefaultWithKey, който може да се използва за ръчно възпроизвеждане на ключовите събития, когато няма съвпадение в подкартата. Това пак ще остави проблема, че не можете да въведете wef. - person marzipankaiser; 20.03.2020