La cessazione del supporto per xneur mi ha causato alcune difficoltà negli ultimi sei mesi (con l'arrivo di OpenSUSE 15.1 sui miei desktop: con xneur attivo, le finestre perdono il focus e brillano in modo divertente in sincronizzazione con la digitazione sulla tastiera).
«Ah, accidenti, ho di nuovo iniziato a digitare con la disposizione sbagliata» — nella mia attività capita fin troppo spesso. E non aggiunge positività.

Allo stesso tempo, io (come ingegnere progettista) posso formulare piuttosto chiaramente ciò che voglio. E io volevo (inizialmente da Punto Switcher, e poi, grazie a Windows Vista, passando completamente a Linux, da xneur) una sola cosa. Realizzando che sullo schermo c'era un gran caos con la disposizione sbagliata (questo di solito accade alla fine della digitazione di una nuova parola), premere 'Pause/Break'. E ricevere ciò che avevo digitato.
Attualmente, il prodotto ha un rapporto funzionalità/complessità ottimale (dal mio punto di vista). È tempo di condividerlo.
TL.DR
Segue una serie di dettagli tecnici, quindi prima — per i più impazienti.
Attualmente è hardcoded il seguente comportamento:
- «Pause/Break»: cancella l'ultima parola (Backspace), cambia la tastiera attiva nella finestra (tra 0 e 1) e ridigita di nuovo.
- «Ctrl sinistro senza nulla»: cambia la tastiera attiva nella finestra (tra 0 e 1).
- «Shift sinistro senza nulla»: attiva la tastiera №0 nella finestra.
- «Shift destro senza nulla»: attiva la tastiera №1 nella finestra.
Da questo momento intendo personalizzare il comportamento. Senza feedback — non è interessante (sono già soddisfatto). Credo che su Habr ci sarà una percentuale sufficiente di pubblico con problemi simili.
N.B. Poiché nella versione attuale il keylogger si collega a "/dev/input/", xswitcher deve essere avviato con diritti di root:
chown root:root xswitcher
chmod +xs xswitcherNota bene: il proprietario del file con suid deve essere root, poiché il proprietario — diventerà suid all'avvio.
I paranoici (non sono un'eccezione) possono clonare da e compilare in loco. Ecco come:
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
Aggiungere l'avvio automatico a piacere (a seconda del DE).
Funziona, "non chiede molto" (≈30 secondi di CPU al giorno, ≈12 MB in RSS).
Dettagli
Ora — i dettagli.
L'intero repository era originariamente dedicato al mio progetto personale, e non avevo voglia di crearne un altro. Quindi, tutto è stato accorpato (semplicemente per cartelle) e coperto con AGPL ("brevetto al contrario").
Il codice xswitcher è scritto in golang, con minime integrazioni in C. Si presume che questo approccio riduca al minimo i tempi di lavoro (ed al momento è così). Mantiene la possibilità di collegare ciò che manca tramite cgo.
Nei testi sono commentati da dove è stato preso cosa e perché. Poiché il codice xneur non mi ha "ispirato", ho preso come punto di partenza .
L'uso di "/dev/input/" ha sia i suoi vantaggi (tutto è visibile, inclusa la pressione prolungata di un tasto con ripetizione automatica), sia svantaggi. I svantaggi sono i seguenti:
- La ripetizione automatica (eventi con codice "2") non corrisponde alla ripetizione negli X.
- Non è possibile vedere l'input tramite le interfacce X11 (ad esempio, così funziona VNC).
- È necessario essere root.
D'altra parte, è possibile iscriversi agli eventi X tramite "XSelectExtensionEvent()". Puoi dare un'occhiata nel . Per go non ho trovato nulla di simile, e la bozza di implementazione ha portato immediatamente a un centinaio di righe di codice C. Per ora ho messo da parte.
L'output "al contrario" è attualmente realizzato tramite l'aggiunta di una tastiera virtuale. Grazie all'autore di keybd_event, ma lì c'è un'astrazione troppo alta e dovremo rifare. Ad esempio, nel mio caso, il tasto Win destro seleziona il terzo rigo. E il back è trasmesso solo dal tasto Win sinistro.
Errori noti
- Non sappiamo nulla dell'input "composito" (esempio: ½). Al momento non è necessario.
- Riproduciamo erroneamente il tasto Win destro. Nel mio caso, rompe la disposizione degli accenti.
- Non c'è un'analisi chiara dell'input. Invece, ci sono diverse funzioni: Compare(), CtrlSequence(), RepeatSequence(), SpaceSequence(). Grazie Per l'attenzione: ho corretto nel codice e qui. Con una certa probabilità, è possibile raccogliere bug durante la sostituzione.
In questo punto non so "come si deve" e sarei felice di ricevere qualsiasi suggerimento. - (Oh, orrore) Utilizzo competitivo dei canali (keyboardEvents, miceEvents).
Conclusione
Il codice è il più semplice procedurale. Ed è stupido come me. Quindi, mi consolo sperando che qualsiasi tecnico possa completare ciò che desidera. E questo prodotto non scomparirà senza supporto, a differenza della maggior parte dei progetti solo per divertimento.
Buona fortuna!
Fonte: habr.com
