began work on better character streaming with xdotool

This commit is contained in:
Kevin F 2023-01-22 01:08:48 -06:00
parent 6779f87be3
commit 40be382c2d
2 changed files with 57 additions and 15 deletions

View File

@ -62,7 +62,6 @@ import(
"os"
"net/http"
"fmt"
"strings"
"log"
"keyboard.voidnet.tech/auth"
@{gorilla/websocket import string}

View File

@ -1,6 +1,12 @@
# Streaming keyboard input
We use the Gorilla websocket library to handle the websocket connection. We then use the sendkeys library to stream the keyboard input to the client.
We use the Gorilla websocket library to handle the websocket connection.
Most of the time, we can use sendkeys (which uses libinput) to effeciently press keys. However, if we need to send a character that sendkeys doesn't know about, we can use the xdotool command.
xdotool spawns a new process for each keypress, so it's not as effecient as sendkeys.
To specify xdotool usage, the client should send a message with the format `{kb_cmd:xdotool}:message` where message is a utf-8 string.
``` go
--- streaming keyboard input
@ -31,7 +37,6 @@ func clientConnected(w http.ResponseWriter, r *http.Request) {
}
c.WriteMessage(websocket.TextMessage, []byte("authenticated"))
var parts []string
for {
time.Sleep(25 * time.Millisecond)
_, message, err := c.ReadMessage()
@ -45,18 +50,56 @@ func clientConnected(w http.ResponseWriter, r *http.Request) {
message_string = "\n"
}
parts = strings.Split(message_string, "\n")
for _, part := range parts {
err = keyboard.Type(part)
if err != nil {
log.Println("type:", err)
}
if len(parts) > 1 {
keyboard.Enter()
}
}
@{send keys to system}
}
}
---
```
# Sending the keys
Sending the keys is a bit tricky as we need to manually convert backspace, tab, and enter.
``` go
--- send keys to system
if strings.HasPrefix(message_string, "{kb_cmd:xdotool}:") {
message_string = strings.TrimPrefix(message_string, "{kb_cmd:xdotool}:")
if message_string == "" {
message_string = "\n"
}
// regex if string has characters we need to convert to key presses
// if it does, convert them and send them
// if it doesn't, send the whole string
cmd := exec.Command("xdotool", "type", message_string)
err = cmd.Run()
if err != nil {
log.Println("xdotool:", err)
}
continue
}
for _, character := range message_string {
charString := string(character)
if charString == "\n" {
keyboard.Enter()
continue
}
if charString == "\t" {
keyboard.Tab()
continue
}
if charString == "\b" {
keyboard.BackSpace()
continue
}
err = keyboard.Type(charString)
if err != nil {
log.Println("type:", err)
}
}
```