146 lines
5.1 KiB
Markdown
146 lines
5.1 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
# KVMote (Go/Wails)
|
|
|
|
Reescrita em Go do KVMote (original em C#/WinForms em `C:\vscode\KVMote`).
|
|
|
|
---
|
|
|
|
## O que é
|
|
|
|
KVM over Bluetooth/BLE. Controla PC remoto (cliente) a partir do host usando microcontrolador como HID USB. **Sem software no PC cliente.**
|
|
|
|
```
|
|
Host PC ──BLE NUS──► ESP32-S3 ──USB HID──► Cliente PC (sem sw)
|
|
```
|
|
|
|
Hardware suportado: ESP32-S3 (BLE NUS) e Arduino Leonardo + HC-06 (Serial SPP). Ver CLAUDE.md do projeto C# para detalhes de hardware e firmware.
|
|
|
|
---
|
|
|
|
## Stack
|
|
|
|
- **Go 1.23** + **Wails v2** (webview desktop)
|
|
- **tinygo.org/x/bluetooth** — BLE via WinRT
|
|
- **golang.org/x/sys/windows** — hooks globais (WH_MOUSE_LL, WH_KEYBOARD_LL)
|
|
- **github.com/atotto/clipboard** — leitura de clipboard
|
|
- Frontend: HTML estático em `frontend/dist/` (sem framework JS)
|
|
|
|
---
|
|
|
|
## Estrutura
|
|
|
|
```
|
|
main.go — entry point Wails, bind App
|
|
app.go — App struct, métodos expostos ao frontend; implementa WindowManager
|
|
internal/
|
|
transport/
|
|
transport.go — interface Transport (Detect/Connect/Send/SendLossy...)
|
|
ble_windows.go — BLE NUS via tinygo/bluetooth
|
|
kvm/
|
|
engine.go — lógica KVM: mouse, teclado, clipboard, modo cliente
|
|
WindowManager interface (SetMiniMode/RestoreNormalMode)
|
|
LogDebug → kvmote_debug.log (arquivo na raiz)
|
|
input/
|
|
input.go — interface InputHandler + tipos (Point, MouseEvent, KeyboardEvent)
|
|
input_windows.go — hooks Win32, SetCursorPos, ShowCursor, GetSystemMetrics
|
|
overlay_windows.go — janela Win32 nativa independente do Wails (neon "KVMote")
|
|
aparece no canto durante modo cliente; usa sua própria goroutine
|
|
com LockOSThread + message pump próprio
|
|
frontend/
|
|
dist/index.html — UI
|
|
wails.json — config Wails
|
|
```
|
|
|
|
---
|
|
|
|
## Protocolo binário (Host → Dispositivo)
|
|
|
|
Idêntico ao projeto C#:
|
|
|
|
| Cmd | Bytes | Ação |
|
|
|-----|-------|------|
|
|
| `M` dx dy | 3 | Mouse move (int8) |
|
|
| `W` delta | 2 | Scroll (int8) |
|
|
| `K` char | 2 | Keyboard.write |
|
|
| `P` key | 2 | Keyboard.press |
|
|
| `U` key | 2 | Keyboard.release |
|
|
| `A` | 1 | releaseAll |
|
|
| `C` L\|R | 2 | Click |
|
|
| `D` L\|R | 2 | Mouse press |
|
|
| `E` L\|R | 2 | Mouse release |
|
|
| `T` lenH lenL data | 3+N | Clipboard batch (Go-specific) |
|
|
| `O` | 1 | LED magenta (modo cliente) |
|
|
| `H` | 1 | LED azul (host conectado) |
|
|
| `G` | 1 | LED verde (desconectado) |
|
|
| `~` | 1 | Ping → `[PONG]` |
|
|
|
|
---
|
|
|
|
## Lógica KVM (engine.go)
|
|
|
|
- **Entrada modo cliente:** cursor atinge borda configurada → esconde cursor, warp centro, acumula deltas (técnica FPS)
|
|
- **Retorno ao host:** coordenadas virtuais cruzam `-ReturnThreshold` (120px) na direção de entrada
|
|
- **Debounce:** 800ms anti-bounce após troca de modo
|
|
- **Mouse throttle:** 40ms (~25 pacotes/s)
|
|
- **Scroll:** `scrollActive` suprime warp por 200ms durante scroll (evita cancelar gesto touchpad)
|
|
- **Clipboard:** Ctrl+C no host seta `clipboardReady`, Ctrl+V em modo cliente envia via comando `T` (batch)
|
|
- **Ctrl+Alt+Del:** sequência P/U com delay 50ms
|
|
|
|
---
|
|
|
|
## Hooks Win32 (input_windows.go)
|
|
|
|
- `runtime.LockOSThread()` obrigatório — hooks Win32 exigem message pump na mesma thread
|
|
- Loop `GetMessageW` mantém thread viva
|
|
- `Uninstall()` via `PostThreadMessageW(WM_QUIT)`
|
|
- `SetProcessDPIAware` chamado no init()
|
|
|
|
---
|
|
|
|
## Build
|
|
|
|
```bash
|
|
# Dev
|
|
wails dev
|
|
|
|
# Produção
|
|
wails build
|
|
```
|
|
|
|
Saída: `build/bin/kvmote.exe`
|
|
|
|
---
|
|
|
|
## Diferenças do projeto C#
|
|
|
|
| Aspecto | C# (WinForms) | Go (Wails) |
|
|
|---------|---------------|------------|
|
|
| UI | WinForms nativo | Webview (HTML) |
|
|
| Transporte | Serial + BLE (dual) | Só BLE (por enquanto) |
|
|
| Clipboard | char-a-char com delay | Batch via comando `T` |
|
|
| ClipboardMax | 500/1000 chars | 65536 chars |
|
|
| Scroll | acumulador _wheelAccum + _scrollActive | scrollActive only |
|
|
| ReturnThreshold | 15px | 120px |
|
|
| Reconexão | auto-reconnect loop | manual |
|
|
| Heartbeat/Watchdog | sim | não implementado |
|
|
|
|
---
|
|
|
|
## Mini-mode / Overlay
|
|
|
|
Ao entrar em modo cliente, `engine` chama `WindowManager.SetMiniMode()` → `App` emite evento `window-mode:mini` ao frontend e exibe `OverlayWindow` nativo Win32. `OverlayWindow` tem goroutine própria com `LockOSThread` e message pump independente do Wails — não interfere com WebView2, Raw Input, nem coordenadas Wails.
|
|
|
|
---
|
|
|
|
## ⚠️ Cuidados
|
|
|
|
- **Scroll touchpad:** `scrollActive` e `scrollTimer` não devem ser resetados em enter/exitClientMode
|
|
- **runtime.LockOSThread:** nunca remover da goroutine de hooks nem da goroutine do overlay
|
|
- **isWarping flag:** previne loop infinito SetCursorPos → WM_MOUSEMOVE → SetCursorPos
|
|
- **Mutex ordering:** engine.mu protege todo estado KVM; transport.mu protege conexão BLE
|
|
- **overlayOnce:** `RegisterClassExW` só pode ser chamado uma vez por processo; overlay usa `sync.Once`
|
|
- **LogDebug:** escreve em `kvmote_debug.log` na raiz do projeto (ignorado pelo git)
|