Skip to content

fix(stream): adapt floating window viewport sizing#47

Merged
qiin2333 merged 2 commits into
masterfrom
codex/fix-floating-window-viewport
Jun 23, 2026
Merged

fix(stream): adapt floating window viewport sizing#47
qiin2333 merged 2 commits into
masterfrom
codex/fix-floating-window-viewport

Conversation

@qiin2333

@qiin2333 qiin2333 commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

改了啥呀

  • 浮窗/窗口模式下改用当前窗口内容区 drawableRect/windowRect 计算 XComponent 尺寸,别再拿整块屏幕尺寸硬塞进小窗口里了,裁剪感这个小坏蛋先按住。
  • windowSizeChange 监听和防抖通知收敛到 StreamWindowManager,窗口 recover/maximize、拖拽缩放、系统布局 settle 后统一触发重算。
  • 旋转和服务端分辨率变化时,也按全屏/浮窗分别选择屏幕尺寸或实际窗口视口,避免后续状态刷新把浮窗尺寸又算回整屏。

为啥要改

  • 用户反馈横屏浮窗时画面像被裁剪,本质是浮窗模式继续按全屏尺寸计算视频 Surface,父容器会裁掉超出窗口的部分。
  • ArkUI 这类窗口/多窗场景更适合跟随系统窗口属性和尺寸事件做状态驱动刷新,而不是页面层写固定延时猜窗口什么时候稳定。

验证

  • git diff --check
  • JAVA_HOME=/Applications/DevEco-Studio.app/Contents/jbr/Contents/Home PATH=/Applications/DevEco-Studio.app/Contents/jbr/Contents/Home/bin:$PATH DEVECO_SDK_HOME=/Applications/DevEco-Studio.app/Contents/sdk NODE_PATH=/Users/mac/Program/moonlight-harmony/node_modules node hvigorw.js --no-daemon assembleHap --mode module -p module=entry --stacktrace
  • MatePad Pro 13 模拟器 HarmonyOS 6.1.1(24):hdc install -r entry/build/default/outputs/default/entry-default-unsigned.hap
  • MatePad Pro 13 模拟器:aa start -a EntryAbility -b com.alkaidlab.sdream -m entry
  • 模拟器确认应用前台运行并渲染首页。

需要测试

  • 2in1/平板真实设备横屏串流后,从全屏切到浮窗,确认画面完整等比显示,没有放大裁剪。
  • 浮窗模式下拖拽改变窗口大小,确认视频画面随窗口变化 letterbox/pillarbox,不卡在旧尺寸。
  • 浮窗中开启/关闭“拉伸画面”,确认拉伸时填满窗口,关闭后按比例留黑边。
  • 串流中服务端分辨率变化,例如 16:9、16:10、21:9、竖屏分辨率,确认 XComponent 重算正确。
  • 窗口模式和全屏模式来回切换多次,确认没有黑边异常、没有触控映射偏移。

需要回归

  • 全屏串流的横竖屏旋转、沉浸式系统栏隐藏/恢复。
  • 串流开始和结束后的窗口恢复、常亮、亮度、横屏多窗启停。
  • 触控/鼠标/手柄映射,尤其是浮窗尺寸变化后的坐标映射。
  • 画面位置、偏移、缩放、平移相关设置。
  • 没有可用 Sunshine 主机时的首页、扫描网络、手动添加入口。

Summary by CodeRabbit

  • Bug Fixes
    • 改进窗口模式切换:在完成尺寸重算后再继续后续逻辑,降低切换后的显示错位风险
    • 优化全屏/非全屏下的旋转与服务器分辨率变更处理:同步更新屏幕信息,并按实时视口尺寸重新计算画面宽高
  • Performance
    • 窗口大小变化新增统一 120ms 防抖通知,减少频繁重算带来的卡顿与抖动

@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7fa0f695-3d5e-4994-95e7-78fbb4222bfd

📥 Commits

Reviewing files that changed from the base of the PR and between 9b86b1a and c908a07.

📒 Files selected for processing (2)
  • entry/src/main/ets/pages/StreamPage.ets
  • entry/src/main/ets/service/streaming/StreamLifecycleManager.ets
🚧 Files skipped from review as they are similar to previous changes (1)
  • entry/src/main/ets/service/streaming/StreamLifecycleManager.ets

📝 Walkthrough

变更说明

重构了窗口模式下 XComponent 尺寸的计算流程:StreamWindowManager 新增实例级防抖机制、getCurrentWindowViewportSize()calculateXComponentSizeForViewport() 方法;StreamLifecycleManager 的旋转与分辨率变更处理按全屏/非全屏分支调用不同计算路径;StreamPage 的模式切换改为 await,全屏分支先获取实时屏幕尺寸再计算。

变更详情

窗口模式视口尺寸重构

Layer / File(s) Summary
防抖基础设施与视口尺寸方法
entry/src/main/ets/service/streaming/StreamWindowManager.ets
新增 windowSizeDebounceTimer 字段实现实例级防抖;notifyWindowSizeChanged() 统一 120ms 防抖触发 onWindowSizeChangedgetCurrentWindowViewportSize() 优先读取窗口 drawableRect 计算 vp 尺寸,失败回退屏幕尺寸;calculateXComponentSizeForViewport() 按等比或拉伸占满返回 XComponentSize
事件流统一化与 toggleWindowMode 改造
entry/src/main/ets/service/streaming/StreamWindowManager.ets
registerWindowSizeListener 回调改为转发至 notifyWindowSizeChanged() 的统一防抖;toggleWindowMode 两种模式切换后均主动调用 notifyWindowSizeChanged(),窗口模式切换时先注册监听再退出沉浸式。
StreamPage 尺寸重算的 await 与分支重写
entry/src/main/ets/pages/StreamPage.ets
onToggleWindowMode 改为 await recalculateXComponentSize();全屏分支先调用 windowManager.updateScreenSize() 获取实时屏幕尺寸,同步更新至 viewModelpanZoomHandler,再计算 xComponentWidth/Height;窗口/浮窗分支由固定 '100%' 改为基于视口尺寸的动态计算。
生命周期事件的视口分支计算
entry/src/main/ets/service/streaming/StreamLifecycleManager.ets
updateScreenSizeAfterRotationhandleServerResolutionChanged 均改为 windowManager 缺失时直接返回,非全屏时改用 getCurrentWindowViewportSize() 获取视口尺寸,按全屏/非全屏分别调用 calculateXComponentSize()calculateXComponentSizeForViewport() 后回调更新。

代码审查估计

🎯 3 (Moderate) | ⏱️ ~20 minutes

可能相关的 PR

  • AlkaidLab/moonlight-harmony#41: 同样修改了浮窗/窗口模式下串流视口几何信息的获取方式,与本 PR 新增的 getCurrentWindowViewportSize() 和视口尺寸适配逻辑直接相关。
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR标题准确反映了主要变更:修复浮窗模式下的视口尺寸自适应问题,这是本次PR的核心目标。
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-floating-window-viewport

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
entry/src/main/ets/pages/StreamPage.ets (1)

913-916: ⚡ Quick win

窗口模式切换触发了两次尺寸重算,建议保留单一触发源

toggleWindowMode() 内部已经通过 notifyWindowSizeChanged() 触发重算(并且已防抖);Line 915 再 await this.recalculateXComponentSize() 会重复执行同一套异步计算,容易带来短时抖动和额外开销。

建议修复
       onToggleWindowMode: async () => {
         await this.windowManager?.toggleWindowMode();
-        await this.recalculateXComponentSize();
       },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@entry/src/main/ets/pages/StreamPage.ets` around lines 913 - 916, The
onToggleWindowMode method is triggering size recalculation twice: once
internally within toggleWindowMode via notifyWindowSizeChanged (which is already
debounced), and again explicitly with the await this.recalculateXComponentSize()
call on line 915. Remove the explicit recalculateXComponentSize call since
toggleWindowMode already handles the size recalculation internally, eliminating
the duplicate computation and potential visual jitter.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@entry/src/main/ets/service/streaming/StreamLifecycleManager.ets`:
- Around line 201-218: The StreamLifecycleManager currently updates
viewModel.displayInfo and calls the updateXComponentSize callback after rotation
or resolution changes, but it does not sync the parent container size for
PanZoomHandler, causing touch coordinate offsets when zoom is active. After
updating the XComponent size in both code paths (the fullscreen path around line
201-218 and the viewport path around line 243-260), you must also add a callback
to update the PanZoomHandler's parent container dimensions to match the same
viewport width and height being used for the XComponent size calculation. This
ensures that subsequent inverseTransform operations in PanZoomHandler use the
correct parent size rather than stale dimensions.

---

Nitpick comments:
In `@entry/src/main/ets/pages/StreamPage.ets`:
- Around line 913-916: The onToggleWindowMode method is triggering size
recalculation twice: once internally within toggleWindowMode via
notifyWindowSizeChanged (which is already debounced), and again explicitly with
the await this.recalculateXComponentSize() call on line 915. Remove the explicit
recalculateXComponentSize call since toggleWindowMode already handles the size
recalculation internally, eliminating the duplicate computation and potential
visual jitter.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 72737bb6-18f3-432b-80cc-89beebcec90b

📥 Commits

Reviewing files that changed from the base of the PR and between cbc746d and 9b86b1a.

📒 Files selected for processing (3)
  • entry/src/main/ets/pages/StreamPage.ets
  • entry/src/main/ets/service/streaming/StreamLifecycleManager.ets
  • entry/src/main/ets/service/streaming/StreamWindowManager.ets

Comment thread entry/src/main/ets/service/streaming/StreamLifecycleManager.ets
@qiin2333 qiin2333 merged commit 2ddd0d5 into master Jun 23, 2026
1 of 2 checks passed
@qiin2333 qiin2333 deleted the codex/fix-floating-window-viewport branch June 23, 2026 02:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant