mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-19 02:13:03 +08:00
[feat] allow pinch zoom outside the remote image on mobile
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
- 官方或自托管 WSS 信令服务器;授权后进入前台即自动注册或登录本机身份,首页实时显示连接、重连及失败状态。发起桌面连接时复用该身份;切换服务器会重新登录,撤回授权会关闭连接。已有远程会话优先通过系统画中画保持连接,画中画不可用时由带连接通知的前台服务兜底;首页空闲信令在后台关闭。
|
||||
- 优先使用 MediaCodec 硬件解码 H.264 / AV1,硬件缓冲区直接提交 Surface;设备无对应硬件、分辨率超限或运行失败时,按原编码格式回退到 OpenH264 / dav1d。软件输出由独立显示线程将 NV12 转 RGBA;只保留最新待显示帧。MiniRTC 原有的通用压缩帧解码队列保持不变。
|
||||
- 48 kHz 单声道 PCM 播放,支持静音,音频队列有容量限制。
|
||||
- 相对鼠标(触控板)和绝对位置模式;单指点击、绝对模式按住拖动、长按右键,以及外接键盘、鼠标。画面手势与 iOS 一致:双指捏合以触点为中心缩放(1–10 倍),放大后双指拖动画面,原始比例下双指上下滑动控制滚轮。相对鼠标移到可见画面的上、下边缘后继续向外移动,会反向上下平移画面,不触发左右平移;未放大时和按住虚拟鼠标键拖动时同样生效,停止移动即停止平移,抬手保留位置。移动到极限时,画面可见部分至少占当前显示区域高度的 20%,与缩放倍数无关;整幅画面高度不足该比例时完整保留,范围计入上下黑边;缩放结束及缩回 1 倍时保留平移位置,仅在超过可见边界时限制位置;切换显示器恢复居中。
|
||||
- 相对鼠标(触控板)和绝对位置模式;单指点击、绝对模式按住拖动、长按右键,以及外接键盘、鼠标。画面手势与 iOS 一致:双指可在整个触控区域(包括画面外黑边)捏合,以触点为中心缩放(1–10 倍),放大后双指拖动画面,原始比例下双指上下滑动控制滚轮。相对鼠标移到可见画面的上、下边缘后继续向外移动,会反向上下平移画面,不触发左右平移;未放大时和按住虚拟鼠标键拖动时同样生效,停止移动即停止平移,抬手保留位置。移动到极限时,画面可见部分至少占当前显示区域高度的 20%,与缩放倍数无关;整幅画面高度不足该比例时完整保留,范围计入上下黑边;缩放结束及缩回 1 倍时保留平移位置,仅在超过可见边界时限制位置;切换显示器恢复居中。
|
||||
- 横竖屏等比例显示、远端多显示器切换。与 iOS 一致的画面质量(低/中/高)、采集帧率(30/60 fps)、画面偏好;支持能力检测、电脑端确认、失败/5 秒超时回退及连续操作的应答排序。
|
||||
- 根据常见移动设备解码能力和屏幕尺寸设置起始参数:显示长边不超过 1280 像素时默认低画质(最高 720p)/30 fps,其余默认中画质(最高 1080p)/30 fps。用户保存的画面偏好不变,仍可手动选择高画质或 60 fps。
|
||||
- 网络状态按视频、音频、数据、合计展示收发速率和丢包率,并显示实际提交帧率、分辨率、画面延时、平滑 RTT、P2P/TURN 和实际 SRTP 状态。每秒刷新,过期或无效测量显示“—”。
|
||||
|
||||
@@ -78,7 +78,8 @@ final class RemoteVideoView extends FrameLayout implements SurfaceHolder.Callbac
|
||||
scales = new ScaleGestureDetector(context, new ScaleGestureDetector.SimpleOnScaleGestureListener() {
|
||||
@Override public boolean onScaleBegin(ScaleGestureDetector detector) {
|
||||
if (mouseInput.hasVirtualButton()) return false;
|
||||
if (!viewport.contains(detector.getFocusX(), detector.getFocusY())) return false;
|
||||
// Pinches can start anywhere on the touch surface, including letterboxing.
|
||||
if (viewport.width() <= 0 || viewport.height() <= 0) return false;
|
||||
viewportGesture = true;
|
||||
viewportPanActive = true;
|
||||
return true;
|
||||
|
||||
@@ -375,7 +375,8 @@ final class RemoteTouchSurface: UIView, UIGestureRecognizerDelegate {
|
||||
let focus = recognizer.location(in: self)
|
||||
switch recognizer.state {
|
||||
case .began:
|
||||
pinchActive = renderRect()?.contains(focus) == true
|
||||
// The full touch surface accepts pinches, including letterboxing.
|
||||
pinchActive = bounds.contains(focus) && renderRect() != nil
|
||||
recognizer.scale = 1
|
||||
case .changed:
|
||||
guard pinchActive else { return }
|
||||
@@ -414,13 +415,13 @@ final class RemoteTouchSurface: UIView, UIGestureRecognizerDelegate {
|
||||
if viewportScale > 1.001 || pinchActive {
|
||||
switch recognizer.state {
|
||||
case .began:
|
||||
viewportPanActive = renderRect()?.contains(
|
||||
viewportPanActive = pinchActive || renderRect()?.contains(
|
||||
recognizer.location(in: self)
|
||||
) == true
|
||||
recognizer.setTranslation(.zero, in: self)
|
||||
case .changed:
|
||||
if !viewportPanActive {
|
||||
viewportPanActive = renderRect()?.contains(
|
||||
viewportPanActive = pinchActive || renderRect()?.contains(
|
||||
recognizer.location(in: self)
|
||||
) == true
|
||||
}
|
||||
|
||||
@@ -431,6 +431,11 @@ Old previews saved without this choice are removed on upgrade.
|
||||
|
||||
## Pointer edge panning
|
||||
|
||||
Pinch-to-zoom can start anywhere on the touch surface, including black margins
|
||||
outside the image, in either pointer mode. A pinch also follows the fingers'
|
||||
midpoint movement when it starts in a margin. Held virtual mouse buttons still
|
||||
prevent viewport gestures.
|
||||
|
||||
In relative mouse mode, continuing to move outward at the top or bottom of the
|
||||
visible image pans the video vertically in the opposite direction. Moving
|
||||
down-left at the bottom edge pans upward without shifting the video horizontally;
|
||||
|
||||
Reference in New Issue
Block a user