Zakończenie wsparcia xneur spowodowało pewne trudności w ciągu ostatnich sześciu miesięcy (po wprowadzeniu OpenSUSE 15.1 na moich komputerach stacjonarnych: gdy xneur jest włączony, okna tracą fokus i zabawnie migoczą w rytm pisania na klawiaturze).
„A, cholera, znów zacząłem pisać w niewłaściwej układzie” — w mojej pracy zdarza się to z nieprzyzwoitą częstotliwością. I nie dodaje to pozytywnego nastroju.

Jednocześnie, jako inżynier, potrafię dość jasno określić, czego chcę. A chciałem (najpierw od Punto Switcher, a potem, dzięki Windows Vista, całkowicie przesiadając się na Linux, od xneur) dokładnie jednego. Uświadomiwszy sobie, że na ekranie jest bełkot w niewłaściwym układzie (to zwykle zdarza się pod koniec wpisywania nowego słowa), nacisnąć „Pause/Break”. I otrzymać to, co pisałem.
Obecnie produkt ma optymalne (z mojego punktu widzenia) miejsce w relacji funkcjonalność/trudność. Czas się podzielić.
TL.DR
Dalej będą różne szczegóły techniczne, więc najpierw — dla niecierpliwych.
Obecnie następujące zachowania zostały twardo zakodowane:
- „Pause/Break”: kasuje (Backspace) ostatnie słowo, przełącza układ w aktywnym oknie (między 0 a 1) i wpisuje ponownie.
- „Lewy Ctrl bez niczego”: przełącza układ w aktywnym oknie (między 0 a 1).
- „Lewy Shift bez niczego”: włącza w aktywnym oknie układ nr 0.
- „Prawy Shift bez niczego”: włącza w aktywnym oknie układ nr 1.
Od tego momentu planuję dostosować działanie. Bez informacji zwrotnej — nie ma sensu (i tak mi odpowiada). Uważam, że na Habrze znajdzie się wystarczająca liczba osób z podobnymi problemami.
N.B. Ponieważ w bieżącej wersji keylogger jest podłączany do "dev/input/", xswitcher musi być uruchamiany z uprawnieniami roota:
chown root:root xswitcher
chmod +xs xswitcherZwróć uwagę: właścicielem pliku z suid musi być root, ponieważ to od właściciela zależy, kto nabędzie suid przy uruchomieniu.
Paranoicy (ja się nie wykluczam) mogą sklonować z i skompilować na miejscu. Przykładowo tak:
go get "github.com/micmonay/keybd_event"
go get "github.com/gvalkov/golang-evdev"
### Nagłówki X11 dla 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
Dodawanie autostartu według gustu (w zależności od DE).
Działa, „nie żąda wody” (≈30 sekund CPU dziennie, ≈12 MB w RSS).
Szczegóły
Teraz — szczegóły.
Cały repozytorium początkowo było poświęcone mojemu projektowi, a nie chce mi się zakładać kolejnego. Tak więc wszystko jest pomieszane (po prostu w folderach) i przykryte AGPL ("patent wsteczny").
Kod xswitcher został napisany w golang, z minimalnymi wtrąceniami C. Zakłada się, że takie podejście przyniesie najmniejsze nakłady pracy (do tej pory tak jest). Zachowując możliwość podłączania brakujących elementów za pomocą cgo.
W tekście umieszczono komentarze, skąd co wzięto i po co. Ponieważ kod xneur mnie "nie zainspirował", wziąłem za punkt wyjścia. .
Użycie "\/dev\/input\/" ma zarówno plusy (wszystko widać, w tym przytrzymany klawisz z powtarzaniem), jak i minusy. Minusami są:
- Powtarzanie automatyczne (zdarzenia z kodem "2") nie pokrywa się z powtarzaniem w Xach.
- Nie widać wejścia przez interfejsy X11 (np. VNC działa w ten sposób).
- Potrzebny jest root.
Z drugiej strony, można subskrybować zdarzenia X za pomocą „XSelectExtensionEvent()”. Można to zobaczyć w . Dla go nie znalazłem nic podobnego, a wstępna implementacja dała od razu sto linii kodu C. Na razie odłożyłem na bok.
Wyjście "wstecz" tymczasowo zrealizowano poprzez dodanie wirtualnej klawiatury. Dziękuję autorowi keybd_event, ale tam jest zbyt wysoka abstrakcja, więc będę musiał to przekształcić. Na przykład, w moim przypadku prawy klawisz Win wybiera 3. rząd. A z powrotem przetwarzany jest tylko lewy Win.
Znane błędy.
- Nie wiemy nic o „kompozytowym” wejściu (przykład: ½). Na chwilę obecną nie jest to potrzebne.
- Nieprawidłowo odtwarzamy prawy Win. W moim przypadku psuje to układ akcentów.
- Brak jasnej analizy wejścia. Zamiast tego — kilka funkcji: Compare(), CtrlSequence(), RepeatSequence(), SpaceSequence(). Dziękuję za uwagę: poprawiłem w kodzie i tutaj. Z pewnym prawdopodobieństwem można napotkać błędy podczas zamiany.
W tym miejscu nie wiem "jak powinno być" i będę wdzięczny za wszelkie propozycje. - (O zgrozo) współbieżne użycie kanałów (keyboardEvents, miceEvents).
Podsumowanie
Kod — najprostszy proceduralny. I głupi, jak ja. Więc pocieszam się nadzieją, że napisanie tego, co chcę, będzie w stanie praktycznie każdy technik. I ten produkt dzięki temu nie zniknie bez wsparcia, jak większość projektów just-for-fun.
Powodzenia!
Źródło: habr.com
