Klahvistikukorja „hswitcher” jaoks linuxis: teine ​​aste

Kuna eelmine postitus (хswitcher on "proof of concept" staadiumis) sai piisavalt palju konstruktiivset tagasisidet (mis on meeldiv), jĂ€tkasin oma vaba aja kulutamist projekti arendamiseks. NĂŒĂŒd tahan kulutada natuke teie
 Teine samm on veidi ebatavaline: konfiguratsiooni disaini ettepanek/arutelu.

Klahvistikukorja „hswitcher” jaoks linuxis: teine ​​aste

Kuna tavaliselt tundub, et normaalsetele programmeerijatele on nende kÔikide keerukate seadistuste tegemine ÀÀrmiselt igav.

Kuna ei ole mÔtet olla sÔnaselge, siin on nÀide sellest, millega ma kokku puutun.
SuurepÀraselt kujundatud (ja hÀsti teostatud) Apache Kafka & ZooKeeper.
— Konfiguratsioon? Aga see on ju igav! TĂ”mba-tĂ”mba xml (sest "karbist vĂ€lja").
— Oh, ja teie tahate ka ACL-i? Aga see on ju nii tĂŒĂŒtu! TĂ”mba-tĂ”mba
 Nii see on.

Ja minu töös on see tĂ€iesti vastupidine. Õigesti (kahjuks ei juhtu see peaaegu kunagi esimesel katsel) koostatud mudel vĂ”imaldab hiljem lihtsalt ja vaevata (noh, peaaegu) koos skeemi kokku panna.

Hiljuti nĂ€gin HabrĂ© artiklit andeteadlastest, kelle töö ei ole kerge

Selgub, et see aspekt on neil tĂ€ielikult realiseeritud. Ja minu praktikas, nagu öeldakse, on see "kerge versioon". Mitmeosalisemad mudelid, kogenud programmeerijad OOP-iga ja nii edasi – see kĂ”ik tuleb hiljem, kui/ja kui tĂ”usma hakkab. A konstruktor peab siin ja praegu millegagi alustama.

Asi on tĂ”sine. SĂŒntaktilise aluseks vĂ”tsin TOML see alt see kodanik.

Sest ta (TOML) on ĂŒhelt poolt inimese redigeerimiseks sobiv. Teiselt poolt – edastatakse 1:1 igasse levinumasse sĂŒntaksisse: XML, JSON, YAML.
Lisaks on minu kasutatavad rakendused ‘github.com/BurntSushi/toml’ kuigi mitte kĂ”ige moes (ikka veel sĂŒntaks 1.4), kuid sĂŒntaktiliselt ĂŒhilduv sama (‘sisseehitatud’) JSON-iga.

See tĂ€hendab, et soovi korral vĂ”ib lihtsalt öelda "kasu meetod sellest TOMList, tahan XXX" ja "patcheerida" kogu koodi ĂŒhe reaga.

Seega, kui soovite kirjutada mingisuguseid aknaid xswitcher’ile (kindlasti mitte mina) probleeme „selle teie kuradi konfiguratsiooniga” ei oodata.

Kogu ĂŒlejÀÀnud sĂŒntaks „vĂ”ti = vÀÀrtus” (ja mĂ”ne paari keerukama valikuga, nagu = [mĂ”ni, massiiv]) ma arvan
intuitiivselt mugav.
Mis on huvitav, mul endal „pĂ”les” umbes samal ajal (aasta paiku 2013). Ainult, erinevalt minust, tuli TOMLi autor loomulikult asjast lĂ€bi.

Seega on mul nĂŒĂŒd lihtsam kohandada selle rakendust enda jĂ€rgi, mitte vastupidi.

Üldiselt vĂ”tame TOML (vĂ€ga sarnane vana Windowsi INI-le). Ja seadistame konfiguratsiooni, kus kirjeldame, kuidas siduda rida hook'e olenevalt viimaste klaviatuurikoodide kogumist. Allpool tĂŒkkhaaval — see, mis hetkel vĂ€lja tuli. Ja selgitused, miks ma nii otsustasin.

0. PÔhialused

  • Klaviatuurikoodide tĂ€histamine. Sellega tuleb kindlasti midagi teha, kuna lihtsalt numbrilised koodid on tĂ€iesti mittetĂ€ielikult loetavad (ma pole siinkohal aiamaastikul). loloswitcher).
    VĂ”tsin "ecodes.go" failist "golang-evdev" (originaali jĂ€rgi ei viitsinud minna, kuigi autor on selle kenasti vĂ€lja toonud). Natuke (praegu) muutsin tĂ€iesti kohutavat. NĂ€iteks "LEFTBRACE" → "L_BRACE".
  • TĂ”in tĂ€iendavalt sisse mĂ”isted "klahvid seisundiga". Kuna kasutatud regulaarne grammatika ei vĂ”imalda pikki jutustusi. (Aga see vĂ”imaldab kontrollida minimaalsete kuludega. Kui kasutada ainult "otsest" salvestust.)
  • Sisse tuleb ehitatud "deduplicaator" vajutatud klahvide jaoks. Nii et seisund "kordus"=2 salvestatakse. ĂŒhte Mis puutub reaalsesse tööprotsessi, siis rohkem kui poole aasta jooksul ja, tĂ€helepanu, regulaarsete kuudepikkuste vĂ€rskendustega, on operatsioonisĂŒsteemi taaskĂ€ivitamine toimunud vaid ĂŒks kord, samas kui sel perioodil Windows Server 2019 GUI oli taaskĂ€ivitamisel iga kuu.

1. Mallide jaotamine

[Templates] # "@name@" vÀljendite lihtsustamiseks
 # SÔnad vÔivad koosneda jÀrgmistes mÀrkidest (regex)
 "WORD" = "([0-9A-Z`;']|[LR]_BRACE|COMMA|DOT|SLASH|KP[0-9])"

Millest koosneb sĂ”na inimkeeles koos fonoloogilise kirjutamisega. (berreak kevadest aka "hieroglĂŒĂŒfid")? КаĐșая-Ń‚ĐŸ ŃƒĐ¶Đ°ŃĐœĐ°Ń Â«ĐżŃ€ĐŸŃŃ‚Ń‹ĐœŃÂ». ĐŸĐŸŃŃ‚ĐŸĐŒŃƒ ŃŃ€Đ°Đ·Ńƒ заĐșлаЎыĐČаю ĐżĐŸĐœŃŃ‚ĐžĐ” Â«ŃˆĐ°Đ±Đ»ĐŸĐœĐ°Â».

2. Mida teha, kui midagi vajutatakse (jÀrjekordne klaviatuurikood saabus)

[ActionKeys]
 # Kogu klahv ja testi kÀsu jÀrjestus
 # !!! Korduvad koodid (code=2) tuleb koguda ainult ĂŒhe klahvi kohta!
 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"]

 # Viska kÔik kogutud klahvid, sealhulgas see. See on vaikimisi toiming.
 Drop = ["ESC", "-", "TAB", "ENTER", "KPENTER", "LINEFEED..POWER"]
 # Salvestage ekstra kaart nende klahvide jaoks, kui mÔni on "all" seisundis.
 # Seisundit kontrollitakse "OFF:"|"ON:" tingimuste kaudu tegevuses.
 # (Samuti peavad nende klahvide seisundid pĂŒsima puhverlagede vahel.)
 # ??? Kuidas tegeleda CAPS ja "LOCK"-klahvidega ???
 StateKeys = ["L_CTRL", "L_SHIFT", "L_ALT", "L_META", "CAPS", "N_LOCK", "S_LOCK",
              "R_CTRL", "R_SHIFT", "R_ALT", "R_META"]

 # Testimiseks, kuid Àra kogu.
 # NĂ€iteks kasutan F12 asemel BREAK odavatel sĂŒlearvutitel, millel on kehvad klaviatuurid (uued ThinkPadid)
 Test = ["F1..F10", "ZENKAKUHANKAKU", "102ND", "F11", "F12",
          "RO..KPJPCOMMA", "SYSRQ", "SCALE", "HANGEUL..YEN",
          "STOP..SCROLLDOWN", "NEW..MAX"]

Kokku on ette nĂ€htud 768 koodi. (Aga "iga juhuks" lisasin koodi xswitcher'i ĂŒllatuste pĂŒĂŒdmiseks).
Sisemiselt kirjeldasin massiivi tĂ€itmist linkidega funktsioonide "mida teha". Go keeles on see (ĂŒllatuslikult) osutunud mugavaks ja ilmseks.

  • Kavasin plaanin "Drop" selle koha pealt minimeerida. Paindlikuma töötlemise kasuks (nĂ€itan allpool).

3. Akende klasside tabel

# 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"

Tabeli read — topelt-konditsioneerivate nurkade vahel koos selle nimega. Lihtsalt esimesel katsel ei Ă”nnestunud. SĂ”ltuvalt aktiivsest aknast saad valida valikud:

  • Oma komplekt "kiirklahve" "Actions = 
". Kui pole / tĂŒhi — midagi ei toimu.
  • LĂŒliti "MouseClickDrops" — mida teha, kui hiirekliki tuvastatakse. Kuna xswitcheri sisselĂŒlitamise punktis pole mingeid ĂŒksikasju "kuhu klikkida", lĂ€htestame vaikimisi vahemĂ€lu. Kuid terminalides (nĂ€iteks) ei pruugi seda teha. (ĂŒldiselt).

4. Üks (vĂ”i mitu) vajutust kĂ€ivitavad selle vĂ”i teise hook'i

# 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)" ]

Hoope jagasin kaheks tĂŒĂŒbiks. Sissetoodud, "rÀÀkivate" nimede (NewWord, NewSentence, Compose) ja programmeeritavad.

Programmeeritavate nimed algavad "Action.". TOML v1.4 alusel peavad punktidega nimed olema jutumÀrkides.

Allpool peab igaĂŒhe jaoks olema kirjeldatud sektsioon sama nimega.

Et mitte inimestele "paljaste" regulaarmĂ€rkide tĂ”ttu pead lĂ”hkuda (kogemus nĂ€itab, et kirjutada- vĂ”ib olla ĂŒks kĂŒmnest professionaalist), tutvustan kohe tĂ€iendavat sĂŒntaksit.

  • "OFF:" (vĂ”i "ON:") enne regexp (regulaarmĂ€rk) nĂ”uavad, et edasi antud nupud oleksid vabastatud (vĂ”i vajutatud).
    Edasi plaanin teha "ebaregulaarse" regulaarmĂŒĂŒgi. Eraldi kontrolliga osade vahel pipe'ide "|". EesmĂ€rgiga vĂ€hendada salvestuste arvu, nagu "[LR]_SHIFT" (seal, kus see ei ole selgelt vajalik).
  • "SEQ:" Kui eelmised tingimused on tĂ€idetud (vĂ”i puuduvad), kontrollime edasi "tavalise" regulaarmĂŒĂŒgi suhtes. Üksikasjade jaoks saadan koheselt raamatukogusse "regexp." Sest ma pole endiselt viitsinud vĂ€lja selgitada ĂŒhilduvuse taset minu lemmikute pcre-dega ("perl compatible").
  • VĂ€ljend sĂ”nastatakse kujul "BUTTON_1: CODE1, BUTTON_2: CODE2" jne, saabumise jĂ€rjekorras sken-koodide jĂ€rgi.
  • Kontroll toimub alati jĂ€relduse lĂ”pus, seega ei pea lĂ”ppu "$" lisama.
  • KĂ”ik kontrollid ĂŒhes reas toimuvad jĂ€rjestikku ja ĂŒhendatakse "JA". Kuid kuna vÀÀrtus on mÀÀratletud massiivina, vĂ”ib pĂ€rast koma kirjutada alternatiivse kontrolli. Kui see on mingil pĂ”hjusel vajalik.
  • TĂ€hendus "SeqLength = 8" piirab vahemĂ€lu suurust, mille suhtes kĂ”ik kontrollid toimuvad. Kuna mul pole elus (kuni praeguseni) olnud piiramatu ressursi kogemust.

5. Eelmises osas kirjeldatud hookide seadistamine

# 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.

Peamine siin — „Action = [Massiiv]“. Nagu eelnevas osas, on olemas piiratud hulk sisseehitatud tegevusi. Ja pĂ”himĂ”tteliselt pole piiratud vĂ”imalus siduda (kirjuta „Action.XXX“ ja Ă€ra unusta kirjutada sellele veel ĂŒks sektsioon).
Sealhulgas, Ă”igekirjakorrektuuri sĂ”na ĂŒlekirjutamine jaguneb kaheks osaks: „vaheta klaviatuur sarnaselt seal mÀÀratletule“ ja â€žĂŒlekirjuta“ („RetypeWord“).

ÜlejÀÀnud parameetrid salvestatakse „sĂ”nastikku“ („map“ golangis) selle tegevuse jaoks, nende loetelu sĂ”ltub „Actionis“ kirjutatust.

MĂ”ningaid erinevaid tegevusi saab kirjeldada ĂŒhes kastmes (sektsioonid). Ja neid saab ka laiali tassida. Nagu ma eespool nĂ€itasin.

Kohe seadistan tegevuse „Exec“ — teosta vĂ€lise skripti. Valikuga, et tal oleks stdin'is kirja pandud puhver.

  • „Wait = 1“ — oota, kuni kĂ€ivitatud protsess lĂ”petatakse.
  • TĂ”enĂ€oliselt tahad „lisaks“ keskkonda visata tĂ€iendavat teavet, nagu akna klassi nimi, millest on kinni peetud.
    „Tahtsid oma töötlejat lisada? Siin on sul koht.”

Uf (hingasin vÀlja). NÀib, et midagi pole ununenud.

Ops! Jah, ei unustanud

Ja kus on kÀivituskonfiguratsioon? KÔvakoodis? Umbes nii:

[ScanDevices]
 # Peab olemas olema kÀivitamisel. Enda taastamine, kui see on noorem kui 30s
 Test = "\/dev\/input\/event0"
 Respawn = 30
 # Otsimismask
 Search = "\/dev\/input\/event*"
 # Minu ThinkPadidel on sellised pseudo-klaviatuurid, kus on tohutult ĂŒleliigseid sĂŒndmusi
 Bypass = "(?i)Video|Camera" # "(?i)" erineb ilmselgelt „klassikalisest“ pcre'st.

Ja kus ma unustasin/vÀÀratustasin (ilma selleta — ei saa), loodan tĂ”eliselt, et tĂ€helepanelikud lugejad ei viitsi nina sisse torgata.

Edu!

Allikas: habr.com

Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster