Tentativa de capturar scroll via mini janela sempre-no-topo. Inclui: MoveWindow/GetMonitorWorkArea via Win32, park consistente em wx+150/wy+50, ShowCursor loop no goroutine pós-resize. Revertível: git checkout HEAD~1 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
129 lines
2.7 KiB
Go
129 lines
2.7 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"kvmote/internal/input"
|
|
"kvmote/internal/kvm"
|
|
"kvmote/internal/transport"
|
|
|
|
"github.com/wailsapp/wails/v2/pkg/runtime"
|
|
)
|
|
|
|
// App struct
|
|
type App struct {
|
|
ctx context.Context
|
|
engine *kvm.Engine
|
|
|
|
// Estado da janela (pixels físicos Win32)
|
|
origX, origY int32
|
|
origW, origH int32
|
|
isMini bool
|
|
}
|
|
|
|
// NewApp creates a new App application struct
|
|
func NewApp() *App {
|
|
t := transport.NewBleTransport()
|
|
h := input.NewInputHandler()
|
|
e := kvm.NewEngine(t, h)
|
|
app := &App{
|
|
engine: e,
|
|
}
|
|
e.SetWindowManager(app) // Vincula o app como gerenciador de janela da engine
|
|
return app
|
|
}
|
|
|
|
const miniW, miniH = int32(300), int32(100)
|
|
|
|
func (a *App) SetMiniMode() {
|
|
if a.isMini {
|
|
return
|
|
}
|
|
|
|
// Salva posição/tamanho via Win32 (pixels físicos — mesma base do MoveWindow)
|
|
wx, wy := a.engine.GetWindowPos()
|
|
ww, wh := a.engine.GetWindowSize()
|
|
if ww > 200 {
|
|
a.origX, a.origY = wx, wy
|
|
a.origW, a.origH = ww, wh
|
|
}
|
|
|
|
a.isMini = true
|
|
runtime.EventsEmit(a.ctx, "window-mode", "mini")
|
|
|
|
// Posiciona usando Win32 SetWindowPos (evita mistura de coordenadas lógicas/físicas)
|
|
// MonitorFromWindow garante monitor correto em setups multi-monitor
|
|
mx, my, mw, mh := a.engine.GetMonitorWorkArea()
|
|
tx := mx + mw - miniW - 20
|
|
ty := my + mh - miniH - 50
|
|
a.engine.MoveWindow(tx, ty, miniW, miniH, true) // topmost=true
|
|
}
|
|
|
|
func (a *App) RestoreNormalMode() {
|
|
if !a.isMini {
|
|
return
|
|
}
|
|
a.isMini = false
|
|
runtime.EventsEmit(a.ctx, "window-mode", "normal")
|
|
|
|
// Restaura via Win32 (mesma base de coordenadas do SetMiniMode)
|
|
a.engine.MoveWindow(a.origX, a.origY, a.origW, a.origH, false)
|
|
}
|
|
|
|
// startup is called when the app starts. The context is saved
|
|
// so we can call the runtime methods
|
|
func (a *App) startup(ctx context.Context) {
|
|
a.ctx = ctx
|
|
err := a.engine.Start(ctx)
|
|
if err != nil {
|
|
fmt.Printf("Error starting engine: %v\n", err)
|
|
}
|
|
}
|
|
|
|
func (a *App) Connect() string {
|
|
err := a.engine.Start(a.ctx)
|
|
if err != nil {
|
|
return fmt.Sprintf("Erro Hook: %v", err)
|
|
}
|
|
|
|
// Lógica real de conexão Bluetooth
|
|
ctx, cancel := context.WithTimeout(a.ctx, 10*time.Second)
|
|
defer cancel()
|
|
|
|
ok, err := a.engine.Transport().Detect(ctx)
|
|
if err != nil || !ok {
|
|
return "Erro: KVMote não encontrado"
|
|
}
|
|
|
|
err = a.engine.Transport().Connect(ctx)
|
|
if err != nil {
|
|
return fmt.Sprintf("Erro Conexão: %v", err)
|
|
}
|
|
|
|
return "Conectado"
|
|
}
|
|
|
|
func (a *App) Disconnect() string {
|
|
a.engine.Transport().Disconnect()
|
|
return "Desconectado"
|
|
}
|
|
|
|
func (a *App) SendCtrlAltDel() {
|
|
kvm.LogDebug("App: Chamando SendCtrlAltDel")
|
|
a.engine.SendCtrlAltDel()
|
|
}
|
|
|
|
func (a *App) ChangeLayout(layout int) {
|
|
a.engine.SetLayout(layout)
|
|
}
|
|
|
|
func (a *App) SetPosition(pos int) {
|
|
a.engine.SetPosition(pos)
|
|
}
|
|
|
|
func (a *App) HandleScroll(delta int) {
|
|
a.engine.HandleManualScroll(delta)
|
|
}
|