Isilungisi sesakhiwo se-Xswitcher se-Linux: isinyathelo sesibili

Kusukela ukushicilelwa kwangaphambilini (i-xswitcher esigabeni “sobufakazi bomqondo”) ithole impendulo eminingi eyakhayo (okumnandi), ngaqhubeka ngichitha isikhathi sami sokuphumula ngithuthukisa iphrojekthi. Manje ngifuna ukuchitha okuncane kwakho... Isinyathelo sesibili ngeke sibe esijwayelekile: isiphakamiso/ingxoxo yokwakheka kokucushwa.

Isilungisi sesakhiwo se-Xswitcher se-Linux: isinyathelo sesibili

Ngandlela thize kuvele ukuthi abahleli bohlelo abajwayelekile bakuthola kuyisicefe ngendlela emangalisayo ukusetha zonke lezi zilawuli.

Ukuze kungabi nasisekelo, ngaphakathi kuyisibonelo salokho engibhekene nakho.
Sekukonke kucatshangwe kahle (futhi kwasetshenziswa kahle) i-Apache Kafka ne-ZooKeeper.
- Ukucushwa? Kodwa kuyabhora! I-xml eyisimungulu (ngoba "ingaphandle kwebhokisi").
- Oh, ingabe ufuna i-ACL? Kodwa kuyisicefe! I-Tap-blooper... Into efana naleyo.

Kodwa emsebenzini wami kuphambene ncamashi. Kulungile (maye, cishe angikaze nje okokuqala) imodeli eyakhiwe ikuvumela ukuthi uqhubeke kalula futhi ngokwemvelo (Cishe) hlanganisa umdwebo.

Ngisanda kuhlangana nendatshana ekhuluma ngoHabré mayelana nokusebenza kanzima kososayensi bedatha ...
Kuvela ukuthi lo mzuzu ugcwaliseka ngokugcwele kubo. Futhi ekusebenzeni kwami, njengoba besho, "inguqulo ekhanyayo". Amamodeli anevolumu eningi, abahleli bezinhlelo abangomakadebona abane-OOP sebelungile, njll. — konke kuzovela ngokuhamba kwesikhathi uma/uma isuka. Kodwa umklami udinga ukuqala endaweni ethile lapha futhi manje.

Thola iphuzu. Ngithathe i-TOML njengesisekelo se-syntactic kusuka kulesi sakhamuzi.

Ngoba yena (TOML) ngakolunye uhlangothi, iyahleleka ngumuntu. Ngakolunye uhlangothi, ihunyushwa ngokuthi 1:1 kunoma imaphi ama-syntaxes avame kakhulu: XML, JSON, YAML.
Ngaphezu kwalokho, ukusebenzisa engikusebenzise ku-“github.com/BurntSushi/toml”, nakuba kungeyona imfashini kakhulu (eseyi-syntax engu-1.4), kuhambisana ngokuzenzakalelayo ne-JSON efanayo (“eyakhelwe ngaphakathi”).

Okusho ukuthi, uma uthanda, ungavele uthi "dlula ehlathini ngaleyo TOML yakho, ngifuna i-XXX" futhi "unamathisele" ikhodi ngomugqa owodwa nje.

Ngakho-ke, uma ufuna ukubhala amanye windows ukuze ulungiselele i-xswitcher (Angiqiniseki) Azikho izinkinga ezilindelwe "ngalokhu kulungiselelwa kwakho okukhulu."

Kubo bonke abanye, i-syntax isuselwe "kukhiye = inani" (kanye nezinketho ezimbalwa eziyinkimbinkimbi, njenge = [okunye, lokho, uhlu]) ngibona kanjalo
intuitively elula.
Okujabulisayo ukuthi "bashile" ngesikhathi esifanayo (cishe ngo-2013). Kuphela, ngokungafani nami, umbhali we-TOML ungene ngesilinganiso esifanele.

Ngakho-ke, manje sekulula kimi ukulungisa ukuqaliswa kwayo ukuze kufanelane nami, hhayi ngokuphambene nalokho.

Ngokuvamile, sithatha i-TOML (efana kakhulu ne-Windows INI endala). Futhi sinokucushwa lapho sichaza khona indlela yokunamathisela uchungechunge lwamahhuku kuye ngesethi yamakhodi wokuskena wakamuva asuka kukhibhodi. Ngezansi, isiqephu ngesiqephu, yilokho okwenzekile kuze kube manje. Nencazelo yokuthi kungani nginqume ngale ndlela.

0. Izifinyezo eziyisisekelo

  • Skena amakhodi wokuqokwa. Kukhona okufanele kwenziwe ngempela ngalokhu, njengoba amakhodi edijithali nhlobo awafundeki umuntu (mina nje loloswitcher).
    Ngathintitha okuthi “ecodes.go” ku-“golang-evdev” (Nganginqena ukubheka umthombo wokuqala, nakuba umbhali ewubonisa ngokwesiko). Ngilungise kancane (okwamanje) into eyesabeka kakhulu. Njengokuthi “LEFTBRACE” → “L_BRACE”.
  • Ukwengeza, wethula umqondo "wezikhiye zesimo". Njengoba uhlelo lolimi olujwayelekile olusetshenziswayo alukuvumeli ukudlula amavesi amade. (Kodwa ikuvumela ukuthi uhlole ngokuphezulu okuncane. Uma usebenzisa ukurekhoda “okuqondile” kuphela.)
  • Kuzoba khona "i-deduplicator" eyakhelwe ngaphakathi yalokho okucindezelwe. Ngakho, isimo "phinda" =2 sizobhalwa один isikhathi.

1. Isigaba sezifanekiso

[Templates] # "@name@" to simplify expressions
 # Words can consist of these chars (regex)
 "WORD" = "([0-9A-Z`;']|[LR]_BRACE|COMMA|DOT|SLASH|KP[0-9])"

Liquketheni igama lolimi lomuntu elinefonetiki? (kungaba indaba yama-graphem aka “hieroglyphs”)? Uhlobo oluthile "lweshidi" elibi. Ngakho-ke, ngethula ngokushesha umqondo othi "isifanekiso".

2. Okufanele ukwenze uma okuthile kuchofozwa (enye ikhodi yokuskena isifikile)

[ActionKeys]
 # Collect key and do the test for command sequence
 # !!! Repeat codes (code=2) must be collected once per key!
 Add = ["1..0", "=", "BS", "Q..]", "L_CTRL..CAPS", "N_LOCK", "S_LOCK",
        "KP7..KPDOT", "R_CTRL", "KPSLASH", "R_ALT", "KPEQUAL..PAUSE",
        "KPCOMMA", "L_META..COMPOSE", "KPLEFTPAREN", "KPRIGHTPAREN"]

 # Drop all collected keys, including this.  This is default action.
 Drop = ["ESC", "-", "TAB", "ENTER", "KPENTER", "LINEFEED..POWER"]
 # Store extra map for these keys, when any is in "down" state.
 # State is checked via "OFF:"|"ON:" conditions in action.
 # (Also, state of these keys must persist between buffer drops.)
 # ??? How to deal with CAPS and "LOCK"-keys ???
 StateKeys = ["L_CTRL", "L_SHIFT", "L_ALT", "L_META", "CAPS", "N_LOCK", "S_LOCK",
              "R_CTRL", "R_SHIFT", "R_ALT", "R_META"]

 # Test only, but don't collect.
 # E.g., I use F12 instead of BREAK on dumb laptops whith shitty keyboards (new ThinkPads)
 Test = ["F1..F10", "ZENKAKUHANKAKU", "102ND", "F11", "F12",
          "RO..KPJPCOMMA", "SYSRQ", "SCALE", "HANGEUL..YEN",
          "STOP..SCROLLDOWN", "NEW..MAX"]

Kunamakhodi angama-768 esewonke. (Kodwa "uma kwenzeka" ngifake ukubamba "izimanga" kukhodi ye-xswitcher).
Ngaphakathi ngichaze ukugcwalisa uhlu ngezixhumanisi zemisebenzi ethi “okufanele ukwenze”. Ku-golang lokhu (ngokungazelelwe) Kwaba lula futhi kusobala.

  • Ngihlela ukunciphisa okuthi "Drop" kube okungenani kule ndawo. Ngithanda ukucubungula okuvumelana nezimo (ngizokubonisa ngezansi).

3. Ithebula elinamawindi amakilasi

# Some behaviour can depend on application currently doing the input.
[[WindowClasses]]
 # VNC, VirtualBox, qemu etc. emulates there input independently, so never intercept.
 # With the exception of some stupid VNC clients, which does high-level (layout-based) keyboard input.
 Regex = "^VirtualBox"
 Actions = "" # Do nothing while focus stays in VirtualBox

[[WindowClasses]]
 Regex = "^konsole"
 # In general, mouse clicks leads to unpredictable (at the low-level where xswitcher resides) cursor jumps.
 # So, it's good choise to drop all buffers after click.
 # But some windows, e.g. terminals, can stay out of this problem.
 MouseClickDrops = 0
 Actions = "Actions"

[[WindowClasses]] # Default behaviour: no Regex (or wildcard like ".")
 MouseClickDrops = 1
 Actions = "Actions"

Imigqa yetafula ikubakaki abayisikwele esiphindwe kabili negama layo. Bekungeke kube lula kusukela elulwaneni. Ngokuya ngewindi elisebenzayo njengamanje, ungakhetha izinketho ezilandelayo:

  • Isethi yakho "yokhiye abashisayo" "Izenzo = ...". Uma kungenjalo/kungenalutho, ungenzi lutho.
  • Shintsha okuthi “MouseClickDrops” - okufanele ukwenze uma kutholwa ukuchofoza kwegundane. Njengoba endaweni lapho i-xswitcher ivulwa khona ingekho imininingwane yokuthi “bachofoza kuphi,” sisetha kabusha isigcinalwazi ngokuzenzakalelayo. Kodwa kumatheminali (ngokwesibonelo) akudingeki wenze lokhu (imvamisa).

4. Ukulandelana okukodwa (noma okuningana) kokuchofoza kucupha ihhuku eyodwa noma enye

# action = [ regex1, regex2, ... ]
# "CLEAN" state: all keys are released
[Actions]
# Inverse regex is hard to understand, so extract negation to external condition.
# Expresions will be checked in direct order, one-by-one. Condition succceds when ALL results are True.
 # Maximum key sequence length, extra keys will be dropped. More length - more CPU.
 SeqLength = 8
 # Drop word buffer and start collecting new one
 NewWord = [ "OFF:(CTRL|ALT|META)  SEQ:(((BACK)?SPACE|[LR]_SHIFT):[01],)*(@WORD@:1)", # "@WORD@:0" then collects the char
             "SEQ:(@WORD@:2,@WORD@:0)", # Drop repeated char at all: unlikely it needs correction
             "SEQ:((KP)?MINUS|(KP)?ENTER|ESC|TAB)" ] # Be more flexible: chars line "-" can start new word, but must not completelly invalidate buffer!
 # Drop all buffers
 NewSentence = [ "SEQ:(ENTER:0)" ]

 # Single char must be deleted by single BS, so there is need in compose sequence detector.
 Compose = [ "OFF:(CTRL|L_ALT|META|SHIFT)  SEQ:(R_ALT:1,(R_ALT:2,)?(,@WORD@:1,@WORD@:0){2},R_ALT:0)" ]

 "Action.RetypeWord" = [ "OFF:(CTRL|ALT|META|SHIFT)  SEQ:(PAUSE:0)" ]
 "Action.CyclicSwitch" = [ "OFF:(R_CTRL|ALT|META|SHIFT)  SEQ:(L_CTRL:1,L_CTRL:0)" ] # Single short LEFT CONTROL
 "Action.Respawn" = [ "OFF:(CTRL|ALT|META|SHIFT)  SEQ:(S_LOCK:2,S_LOCK:0)" ] # Long-pressed SCROLL LOCK

 "Action.Layout0" = [ "OFF:(CTRL|ALT|META|R_SHIFT)  SEQ:(L_SHIFT:1,L_SHIFT:0)" ] # Single short LEFT SHIFT
 "Action.Layout1" = [ "OFF:(CTRL|ALT|META|L_SHIFT)  SEQ:(R_SHIFT:1,R_SHIFT:0)" ] # Single short RIGHT SHIFT

 "Action.Hook1" = [ "OFF:(CTRL|R_ALT|META|SHIFT)  SEQ:(L_ALT:1,L_ALT:0)" ]

Izingwegwe zihlukaniswe izinhlobo ezimbili. Okwakhelwe ngaphakathi, ngamagama azichazayo (NewWord, NewSentence, Compose) futhi kuyahleleka.

Amagama ahlelekayo aqala ngokuthi “Isenzo.” Ngoba I-TOML v1.4, amagama anamachashazi kufanele abe ngamakhwothi.

Isigaba ngasinye kufanele sichazwe ngezansi enegama elifanayo.

Ukuze ungashayi imiqondo yabantu ngezijwayelekile "ze" (kusuka kokuhlangenwe nakho, kwabo ukubhalamhlawumbe oyedwa kwabayishumi ochwepheshe), ngisebenzisa ngokushesha i-syntax eyengeziwe.

  • "VALIWE:" (noma "VULIWE:") ngaphambi kwe-regexp (inkulumo evamile) idinga ukuthi izinkinobho ezilandelayo zikhishwe (noma zicindezelwe).
    Okulandelayo ngizokwenza inkulumo evamile "engalungile". Ngokuhlola okuhlukene kwezingcezu phakathi kwamapayipi "|". Ukuze wehlise inani lamarekhodi afana ne-"[LR]_SHIFT" (lapho lokhu kungenasidingo ngokusobala).
  • "SEQ:" Uma isimo sangaphambilini sihlangatshezwana naye (noma singekho), sizobe sesihlola ngokumelene nenkulumo evamile “evamile”. Ukuze uthole imininingwane, ngokushesha ngithumela ku-^W umtapo wezincwadi "regexp". Ngoba namanje angikazihluphi ngokuthola izinga lokuhambisana ne-pcre engiyithandayo ("i-perl ehambisanayo").
  • Inkulumo ibhalwe ngendlela "BUTTON_1: CODE1, BUTTON_2: CODE2" njll., ngendlela amakhodi askeniwe atholwa ngayo.
  • Isheke lihlala "ligxilile" kuze kube sekugcineni kokulandelana, ngakho-ke asikho isidingo sokwengeza "$" emsileni.
  • Konke ukuhlola emgqeni owodwa kwenziwa ngokulandelana futhi ahlanganiswe ngokuthi “Mina”. Kodwa njengoba inani lichazwa njengelungu elifanayo, ungabhala elinye isheke ngemva kwekhefana. Uma lokhu kudingekile ngesizathu esithile.
  • Okushoyo "SeqLength = 8" ikhawulela usayizi webhafa lapho konke ukuhlola okwenziwa khona. Ngoba Angikaze (kuze kube manje) ngihlangabezane nezinsiza ezingapheli empilweni yami.

5. Ukusetha izingwegwe ezichazwe esigabeni esandulele

# Action is the array, so actions could be chained (m.b., infinitely... Have I to check this?).
# For each action type, extra named parameters could be collected. Invalid parameters will be ignored(?).
[Action.RetypeWord] # Switch layout, drop last word and type it again
 Action = [ "Action.CyclicSwitch", "RetypeWord" ] # Call Switch() between layouts tuned below, then RetypeWord()

[Action.CyclicSwitch] # Cyclic layout switching
 Action = [ "Switch" ] # Internal layout switcher func
 Layouts = [0, 1]

[Action.Layout0] # Direct layout selection
 Action = [ "Layout" ] # Internal layout selection func
 Layout = 0

[Action.Layout1] # Direct layout selection
 Action = [ "Layout" ] # Internal layout selection func
 Layout = 1

[Action.Respawn] # Completely respawn xswitcher. Reload config as well
 Action = [ "Respawn" ]

[Action.Hook1] # Run external commands
  Action = [ "Exec" ]
  Exec = "/path/to/exec -a -b --key_x"
  Wait = 1
  SendBuffer = "Word" # External hook can process collected buffer by it's own means.

Into esemqoka lapha "Isenzo = [Uhlu]". Ngokufanayo nesigaba sangaphambilini, kunesethi elinganiselwe yezenzo ezakhelwe ngaphakathi. Futhi ithuba lokufaka i-docking alinqunyelwe ngokomthetho (bhala "Isenzo.XXX" futhi ungavilaphi ukusibhalela esinye isigaba).
Ikakhulukazi, ukuthayipha kabusha kwegama esakhiweni esilungisiwe kuhlukaniswe izingxenye ezimbili: "shintsha isakhiwo njengoba kushiwo lapho" и "thayipha kabusha" ("RetypeWord").

Imingcele esele ibhalwe “kusichazamazwi” ("imephu" ngesi-golang) ngesenzo esinikeziwe, uhlu lwabo luncike kulokho okubhalwe "Esenzweni".

Izenzo eziningana ezahlukene zingachazwa enqwabeni eyodwa (izigaba). Noma ungayihlukanisa. Njengoba ngibonise ngenhla.

Ngokushesha ngisetha isenzo esithi "Exec" ukuze ngisebenzise iskripthi sangaphandle. Ngenketho yokucindezela isigcinalwazi esirekhodiwe ku-stdin.

  • “Linda = 1” — linda inqubo esebenzayo iphele.
  • Mhlawumbe, "enqwabeni" uzofuna ukubeka abantu abengeziwe endaweni. ulwazi olufana negama lesigaba sewindi lapho inqanyulwe khona.
    “Uyafuna ukuxhuma isibambi sakho? Yilapho okufanele uye khona.”

Phew (edonsa umoya). Kubukeka sengathi angikhohliwe lutho.

Eshu! Yebo, angizange ngikhohlwe...
Kuphi ukulungiselelwa kokuqaliswa? Ngekhodi eqinile? Kanjalo:

[ScanDevices]
 # Must exist on start. Self-respawn in case it is younger then 30s
 Test = "/dev/input/event0"
 Respawn = 30
 # Search mask
 Search = "/dev/input/event*"
 # In my thinkPads there are such a pseudo-keyboards whith tons of unnecessary events
 Bypass = "(?i)Video|Camera" # "(?i)" obviously differs from "classic" pcre's.

Ngikhohlwe/ngenze iphutha kuphi? (ayikho indlela ngaphandle kwalokhu), ngethemba ngempela ukuthi abafundi abalalelisisayo ngeke bavilaphe kakhulu ukucikica amakhala.

Good luck!

Source: www.habr.com

Engeza amazwana