Improve(Web): Headless host opens terminal

fix two-finger scroll speed and zoom misdetect
This commit is contained in:
yuanyuanxiang
2026-05-15 01:42:31 +02:00
parent 5a92c3306f
commit 744ebfba0d

View File

@@ -2059,13 +2059,22 @@ inline std::string GetWebPageHTML() {
// Part 8b1: Device connect / terminal session (split to avoid MSVC string literal length limit)
html += R"HTML(
function connectDevice(id) {
const compat = checkWebCodecs();
if (!compat.supported) { alert('Browser does not support H264: ' + compat.reason); return; }
currentDevice = devices.find(d => d.id === id || d.id === String(id));
if (!currentDevice || !currentDevice.online) {
const dev = devices.find(d => d.id === id || d.id === String(id));
if (!dev || !dev.online) {
alert('Device is offline');
return;
}
// 无显示器screen 字段格式 "n:WxH"n=0 表示无显示器)→ 远程桌面没有意义,
// 直接走终端。
const screenStr = String(dev.screen || '');
const screenCount = parseInt(screenStr.split(':')[0], 10);
if (!isNaN(screenCount) && screenCount === 0) {
openTerminal(id);
return;
}
const compat = checkWebCodecs();
if (!compat.supported) { alert('Browser does not support H264: ' + compat.reason); return; }
currentDevice = dev;
document.getElementById('device-name').textContent = currentDevice.name;
document.getElementById('frame-info').textContent = '';
updateScreenStatus('connecting');
@@ -2574,9 +2583,20 @@ inline std::string GetWebPageHTML() {
// Part 14b: JavaScript - Zoom state and touch helpers
html += R"HTML(
// Two-finger gesture constants
const ZOOM_THRESHOLD = 0.05; // 5% distance change to trigger zoom
const SCROLL_SENSITIVITY = 3; // Scroll speed multiplier
const SCROLL_DEADZONE = 2; // Minimum scroll delta to send
// 缩放 vs 滚动判定(仅在双指 + 触摸场景):
// 1) 间距比例变化 > ZOOM_THRESHOLD 且
// 2) 间距绝对变化 > ZOOM_MIN_PX 且
// 3) 间距变化 > 中心垂直位移 → 判为缩放
// 三个条件同时满足才触发缩放,避免双指上下滚动时手指自然张合的 ~5% 抖动被误判。
// 真实缩放:双指主动张合,间距变化幅度本身就远大于这些阈值。
const ZOOM_THRESHOLD = 0.15; // 间距比例变化阈值15%
const ZOOM_MIN_PX = 30; // 间距绝对变化阈值px
// 注:服务端 (WebService.cpp HandleMouse) 把 wheelDelta 钳成 ±120 一格 notch
// SCROLL_SENSITIVITY 实际不起作用;真正决定滚动速度的是 SCROLL_DEADZONE。
// 触摸 touchmove 在 60fps 下高频触发,旧值 2px 等于手指动一下就连发一堆 notch体感非常飘。
// 现在 28px ≈ 让手指移动 ~1 个文本行距离才发一格,接近 iOS 原生触摸滚动节奏。
const SCROLL_SENSITIVITY = 1; // (server clamps to ±120, kept for clarity only)
const SCROLL_DEADZONE = 28; // Minimum finger-Y delta (px) to send one wheel notch
// Pinch-to-zoom state
let zoomState = {
@@ -2595,7 +2615,9 @@ inline std::string GetWebPageHTML() {
// Two-finger gesture detection
hasZoomed: false, // Whether zoom occurred in current gesture
lastScrollY: 0, // For scroll delta calculation
initialPinchDist: 0 // Distance at gesture start (for cumulative detection)
initialPinchDist: 0, // Distance at gesture start (for cumulative detection)
initialCenterX: 0, // Pinch center at gesture start (for scroll-vs-zoom intent)
initialCenterY: 0
};
const zoomIndicator = document.getElementById('zoom-indicator');
let zoomIndicatorTimer = null;
@@ -2801,6 +2823,8 @@ inline std::string GetWebPageHTML() {
const center = getPinchCenter(e.touches);
zoomState.pinchCenterX = center.x;
zoomState.pinchCenterY = center.y;
zoomState.initialCenterX = center.x;
zoomState.initialCenterY = center.y;
zoomState.lastScrollY = center.y;
if (zoomState.scale === 1) {
@@ -2904,16 +2928,28 @@ inline std::string GetWebPageHTML() {
const totalDelta = newDist / zoomState.initialPinchDist; // Cumulative change from gesture start
// Detect gesture type: zoom vs scroll
// Use CUMULATIVE change to detect zoom intent (catches slow pinch gestures)
// Also treat as zoom if already at scale boundary and trying to zoom further
// 缩放意图 = 间距比例显著变 + 间距绝对显著变 + 间距变化 > 中心垂直位移
// 单纯比例阈值 5% 太敏感:双指上下滚动时手指自然张合 ~5% 就被误判为缩放。
// 结合绝对像素阈值 + "间距变化 vs 中心位移" 的方向性,能稳定区分两种意图。
const distAbsChange = Math.abs(newDist - zoomState.initialPinchDist);
const distRatioChange = Math.abs(totalDelta - 1);
const centerMoveY = Math.abs(newCenter.y - zoomState.initialCenterY);
const isClearZoom = distRatioChange > ZOOM_THRESHOLD &&
distAbsChange > ZOOM_MIN_PX &&
distAbsChange > centerMoveY;
// 已到缩放边界仍朝同方向尝试 → 给视觉反馈,但要求绝对像素变化 > 半阈值,
// 避免静止时手指轻微抖动也被认为"想缩放"。
const atMinScale = zoomState.scale <= zoomState.minScale;
const atMaxScale = zoomState.scale >= zoomState.maxScale;
const tryingToShrink = totalDelta < 1; // Use cumulative for direction
const tryingToShrink = totalDelta < 1;
const tryingToEnlarge = totalDelta > 1;
const boundaryFeedback = distAbsChange > ZOOM_MIN_PX / 2 && (
(atMinScale && tryingToShrink) || (atMaxScale && tryingToEnlarge)
);
if (Math.abs(totalDelta - 1) > ZOOM_THRESHOLD ||
(atMinScale && tryingToShrink) ||
(atMaxScale && tryingToEnlarge)) {
if (isClearZoom || boundaryFeedback) {
zoomState.hasZoomed = true;
}