La cessazione del supporto a xneur mi ha causato alcune sofferenze negli ultimi sei mesi (con l'arrivo di OpenSUSE 15.1 sui miei desktop: con xneur attivo le finestre perdono il focus e lampeggiano in sincronizzazione con la digitazione sulla tastiera).
«Ah, accidenti, ho di nuovo iniziato a digitare con il layout sbagliato» — nella mia lavoro capita in modo imbarazzante frequentemente. E non porta positività.

Allo stesso tempo, io (come ingegnere progettista) posso esprimere abbastanza chiaramente cosa voglio. E quello che volevo (inizialmente da Punto Switcher, e poi, grazie a Windows Vista, finalmente passando a Linux, da xneur) era esattamente uno. Rendendomi conto che sullo schermo c'era un guazzabuglio con il layout sbagliato (questo di solito accade alla fine della digitazione di una nuova parola), dare un colpetto a «Pause/Break». E ottenere quello che ho digitato.
Attualmente il prodotto ha un rapporto ottimale (dal mio punto di vista) funzionalità/complessità. È tempo di condividerlo.
TL.DR
Ora seguiranno vari dettagli tecnici, quindi prima — per gli impazienti.
Attualmente è hardcoded il seguente comportamento:
- «Pause/Break»: elimina (Backspace) l'ultima parola, switcha il layout nella finestra attiva (tra 0 e 1) e digita di nuovo.
- «Ctrl sinistro senza nulla»: switcha il layout nella finestra attiva (tra 0 e 1).
- «Shift sinistro senza nulla»: attiva il layout n.0 nella finestra attiva.
- «Shift destro senza nulla»: attiva il layout n.1 nella finestra attiva.
Da questo momento intendo personalizzare il comportamento. Senza feedback — non è interessante (mi va già bene). Penso che su Habr ci sia una percentuale sufficiente di pubblico con problemi simili.
N.B. Poiché nella versione attuale il keylogger è collegato a "/dev/input/", xswitcher deve essere eseguito con diritti di root:
chown root:root xswitcher
chmod +xs xswitcherAttenzione: il proprietario del file con suid deve essere root, poiché chi è il proprietario — quello suid diventerà al momento dell'esecuzione.
I paranoici (io non faccio eccezione) possono clonare da e compilare in loco. Circa così:
go get "github.com/micmonay/keybd_event"
go get "github.com/gvalkov/golang-evdev"
### Intestazioni X11 per OpenSUSE/deb-based
zypper install libX11-devel libXmu-devel
apt-get install libx11-dev libxmu-dev
cd "x switcher/src/"
go build -o xswitcher -ldflags "-s -w" --tags static_all src/*.go
L'autostart da aggiungere a piacere (a seconda del DE).
Funziona, «non chiede niente» (≈30 secondi di CPU al giorno, ≈12 MB in RSS).
Dettagli
Ora — dettagli.
L'intero repository era originariamente dedicato al mio progetto personale, e non ho voglia di crearne un altro. Quindi, tutto è accumulato in un unico posto (solo per cartelle) ed è coperto da AGPL ("brevetto inverso").
Il codice xswitcher è scritto in golang, con minime integrazioni in C. Si presume che questo approccio riduca i costi di lavoro (e attualmente è così). Mantiene la possibilità di integrare le mancanze tramite cgo.
Nei testi ci sono commenti su dove ho preso cosa e perché. Poiché il codice xneur non mi ha "ispirato", ho preso come punto di partenza .
L'uso di "/dev/input/" ha i suoi pro e contro (tutto è visibile, incluso il tasto premuto con ripetizione automatica). I contro sono:
- La ripetizione automatica (eventi con codice "2") non si allinea con la ripetizione in X.
- Non è visibile l'input tramite le interfacce X11 (ad esempio, questo è il modo in cui funziona VNC).
- Serve l'accesso come root.
D'altra parte, è possibile iscriversi ad eventi X tramite "XSelectExtensionEvent()". Puoi dare un'occhiata nel . Per Go non ho trovato nulla di simile, e la prima implementazione ha prodotto subito un centinaio di righe di codice C. Al momento l'ho messo da parte.
L'output "inverso" è attualmente realizzato tramite l'aggiunta di una tastiera virtuale. Grazie all'autore di keybd_event, ma lì l'astrazione è troppo ad alto livello e dovrà essere rifatta. Ad esempio, il mio tasto Win destro seleziona il terzo rigo. E in entrata viene tradotto solo il tasto Win sinistro.
Errori noti
- Non sappiamo nulla sull'input "composito" (esempio: ½). In questo momento non è necessario.
- Riproduciamo in modo errato il tasto Win destro. Nel mio caso rompe la posizione degli accenti.
- Non c'è un'analisi chiara dell'input. Invece, ci sono alcune funzioni: Compare(), CtrlSequence(), RepeatSequence(), SpaceSequence(). Grazie per la tua attenzione: ho corretto il codice e qui. C'è una certa probabilità di incappare in bug durante la sostituzione.
In questo momento non so "come fare" e sarei felice di ricevere qualsiasi suggerimento. - (Oh no) uso concorrente dei canali (keyboardEvents, miceEvents).
Conclusione
Il codice è il più semplice possibile. E stupido come me. Quindi, mi consolo con la speranza che qualsiasi tecnico possa completare ciò che desidero. E questo prodotto grazie a ciò non scomparirà senza supporto, come la maggior parte dei progetti just-for-fun.
Buona fortuna!
Fonte: habr.com
