pure_live Windows 窗口尺寸持久化与弹窗事务治理:共享尺寸合同、PiP 几何修复与备份迁移
音视频直播【免费下载链接】pure_live纯粹直播:哔哩哔哩/虎牙/斗鱼/快手/抖音/网易cc/YY直播/Twitch直播/SOOP直播/M38自定义源应有尽有。项目地址https://gitcode.com/gh_mirrors/pur/pure_live点击查看免费下载导读本文基于 pure_live 仓库中《WINDOW_SIZE_PERSISTENCE_AND_DIALOG_TRANSACTION_AUDIT_2026_09_13.md》审计文档完整梳理其针对 Windows 桌面端窗口尺寸持久化 PiP 几何 设置弹窗事务三个相邻环节的缺陷根因与修订方案。读者将掌握 pure_live 的启动窗口共享尺寸合同默认 1280×720、最小 400×300、单边上限 16384、窗口事件防抖回写链路、PiP 几何有限性校验以及先应用原生操作、后提交持久化的弹窗事务化改造思路并了解这些能力如何通过备份导入导出与旧版字段迁移保持兼容。审计背景六个相邻缺口本轮审计以b27b4c54为基线、5710da2c为修订提交范围限定在 Windows 启动窗口尺寸、窗口事件回写、PiP 几何、当前/旧版备份、导出与设置弹窗。源码审查确认了六个彼此相邻的缺陷持久值缺启动修复Hive 中存储的启动宽高在控制器初始化后直接进入Size、桌面窗口初始化和设置页toInt()零、负数、非有限值NaN/Infinity或极端大值没有任何启动阶段的修复入口。设置弹窗校验不足弹窗只检查宽高大于零既没有与桌面最小窗口一致的边界也没有上限约束、仅数字输入限制或可见的范围说明。设置已保存但窗口未应用分裂状态弹窗先写入 Hive 和内存再调用windowManager若原生窗口调用失败会出现持久化已提交而窗口实际尺寸未变化的撕裂状态。TextEditingController 生命周期竞态弹窗的两个输入控制器由路由外部创建并在showDialogFuture 完成时释放而 Future 在反向动画结束前就会完成取消或确认退出时可能触发已释放控制器仍被动画子树读取的崩溃。PiP 有效性检查不完备PiP 几何有效性只检查宽高大于零没有检查是否有限损坏的无穷尺寸可能被恢复路径当成有效矩形使用。备份校验宽松当前/旧版备份仅拒绝非有限启动尺寸却保留负数、零值或超大值PiP 显示器 ID 还会把异常标量宽松转成文本导出时可能再次泄漏运行时异常值。共享尺寸合同一个归一化入口修订的核心产物是启动窗口共享尺寸合同定义于 lib/core/config/window_size_controller.dart参数值源码常量默认宽度1280defaultWindowWidth 1280默认高度720defaultWindowHeight 720最小宽度400minWindowWidth 400最小高度300minWindowHeight 300单边最大16384maxWindowDimension 16384合同的关键在于单一归一化入口Hive 持久值、运行时直接写入、窗口事件、当前/旧版备份、导出和桌面首帧全部共用同一组归一化函数而不是各写各的边界判断。归一化的具体规则见normalizeStoredWidth/normalizeStoredHeight与_normalizeStoredDimensionwindow_size_controller.dart非有限值NaN/Infinity→ 回落到对应默认边宽 1280、高 720普通越界值→ 用clamp(min, maxWindowDimension)钳制到合同边界内例如宽度 100 会被钳到 400宽度 20000 会被钳到 16384配套的_isUsableWindowSize有限且 ≥ 最小边与_isSupportedWindowSize有限且在 [最小边, 16384] 区间内分别服务于可用与可持久化两个语义。解析输入时使用tryParseWindowSize(width, height)window_size_controller.dart先int.tryParse两个输入再以_isSupportedWindowSize判定任何一步失败都返回null让调用方走越界反馈分支。控制器启动自愈观察器注册前的修复WindowSizeController.onInit()window_size_controller.dart在任何观察器注册之前先执行两件自愈动作_writeStoredSize(storedSize); // 把 Hive 中的宽高按合同归一化后回写 windowsPip.repairStored(); // 把 PiP 几何按合同归一化后回写_writeStoredSize内部使用_writingStoredSize标志位防止递归触发everAll观察器随后才注册三类 WorkereverAll([storedWidth, storedHeight])→ 任意一边被外部修改时执行_repairStoredSize()再次归一化debounce(windowSize, ..., 500ms)→ 窗口事件连续抖动时合并写回且写回时updateWindowSize: false避免闭环debounce(isTracking, ..., 2s)→ 标题栏尺寸显示[1280 × 720]这类文本在停止拖动 2 秒后自动关闭追踪态。这里的顺序设计是审计的核心结论之一先修复再监听避免启动即读到坏值、观察器被坏值触发后又写回坏值的放大效应。PiP 几何有限性校验与多显示器支持PiP画中画几何由WindowPipGeometry承载window_size_controller.dart横屏与竖屏各保存一套五元组displayId、宽、高、X、Y底层键名例如windows_pip_width、windows_pip_x、windows_pip_portrait_display_id等。修订后的有效性判定补齐了有限性检查bool get hasValidBounds { return windowsPipWidth.v.isFinite windowsPipHeight.v.isFinite windowsPipWidth.v 0 windowsPipHeight.v 0 windowsPipX.v.isFinite windowsPipY.v.isFinite; }完整实现见 window_size_controller.dart要点如下有限性 大于零同时成立才算有效损坏的 NaN/Infinity 矩形不会再被恢复路径当成有效矩形损坏或不完整矩形整体清空_normalizePipRectwindow_size_controller.dart在宽高非有限、≤ 0 时返回全零矩形 空 displayId等价于无记忆合法负坐标继续支持多显示器X/Y 只做isFinite校验不做正负钳制允许负值覆盖主显示器左侧的扩展屏合法超大宽高按共享上限收敛宽高clamp(0.0, maxWindowDimension)与启动窗口合同共用 16384 上限。消费侧在 lib/core/player/presentation/windows_pip_driver.dart 的_readSavedBounds中先检查rememberPipPosition开关再按当前视频方向选择横屏hasValidBounds或竖屏portraitHasValidBounds最后把持久化的 displayId Rect 交给DisplayAwarePipWindow恢复。_writeSavedBounds则按同一方向判定写入对应五元组保证谁恢复、谁写入的读写对称。设置弹窗事务化先原生、后持久化弹窗位于 lib/features/settings/pages/general_settings_page.dart入口是设置页的开机窗口尺寸列表项i18n(window_size)。输入校验与范围提示每个维度输入框使用FilteringTextInputFormatter.digitsOnlyLengthLimitingTextInputFormatter(5)仅允许数字且最多五位general_settings_page.dart弹窗底部常驻提示行ValueKey(window-size-feedback)无错误时显示window_size_range_hint中文文案为宽度 40016384 · 高度 30016384见 assets/translations/zh.json越界时切换为错误色并显示window_size_out_of_range请输入支持范围内的窗口尺寸提供 5 个快捷预设 ActionChip1080×720默认、1280×720720P、1600×900、1920×10801080P、2560×14402K点击仅回填输入框不直接提交。事务顺序修正_apply()的关键改动是调整了操作顺序general_settings_page.dartawait windowManager.setSize(size, animate: true); // 1. 先原生改尺寸 await windowManager.center(); // 2. 居中 SettingsService.to.window.saveWindowSize(size); // 3. 后提交 Hive/内存 SettingsService.to.window.setTracking(true); // 4. 触发标题栏尺寸文本 Navigator.of(context).pop(); // 5. 成功才关闭弹窗即先完成原生尺寸/居中操作再提交规范设置原生调用抛错时进入 catch 分支保留弹窗、恢复按钮态、显示window_size_apply_failed窗口尺寸应用失败请重试。这消除了设置已保存但窗口未应用的分裂状态把原生调用失败变成了用户可见、可重试的反馈而不是静默的持久化残留。控制器生命周期归属_WindowSizeDialog由外部showDialog调用改为路由子树拥有的 StatefulWidget两个TextEditingController在initState创建、在dispose释放general_settings_page.dart释放时机与路由实际卸载绑定而不是与showDialogFuture 完成绑定。连续打开、取消、再打开和越界提交均保持稳定——这正是文档中点名的反向动画竞态Future 在反向动画结束前完成的根治方式。窗口事件回写链路桌面端窗口事件通过DesktopWindowMixin接入lib/core/platform/desktop_manager.dart回写链路为onWindowResize→setTracking(true) 80ms 防抖 TimeronWindowResized→ 取消 Timer、捕获几何、setTracking(false)onWindowMove/onWindowMoved→ 同样进入防抖捕获全屏进入时setTracking(false)暂停标题栏尺寸显示。几何捕获在 Windows 上走captureWindowsWindowGeometrywindows_pip_driver.dartPiP 紧凑窗口直接捕获自身几何不覆盖主窗口的启动尺寸普通窗口则跳过最小化/最大化/全屏态后读取windowManager.getSize()。该值进入updateSize→_normalizeWindowSize→ 防抖 500ms 写回 Hive形成拖动窗口 → 事件 → 归一化 → 持久化 → 下次启动恢复的完整闭环。窗口初始化侧DesktopManager.initializedesktop_manager.dart以SettingsService.to.window.storedSize作为首帧尺寸并以Size(minWindowWidth, minWindowHeight)400×300作为minimumSize保证原生窗口最小尺寸与共享合同一致。持久化值与原生窗口边界从此共用同一套常量不存在弹窗允许 100 宽、原生窗口却强制 400 宽的偏差。备份导出与旧版迁移窗口设置是备份 JSON 的独立分区windowSize在 lib/features/backup/backup_controller.dart 中随exportAllSettings一并导出_sectionKeys中的可识别键集合则直接派生自WindowSizeController.extractConfig(null)backup_controller.dart避免手工维护字段清单。修订后的备份路径有三个严格化点strict 解析parseConfigwindow_size_controller.dart对启动宽高使用_parseStoredDimension非有限值直接抛FormatException_normalizePipRect(strict: true)对 PiP 坐标做字段类型 有限性双重检查非 num 或非有限即抛错见 window_size_controller.dart显示器 ID 只接受字符串displayValue as String? ?? 不再把异常标量宽松转成文本。导入顺序前置校验_importSettings中先validateSectionStructure再用各分区的parseConfig校验全部通过后才逐个fromJson落盘符合验证先于持久化的事务语义backup_controller.dart。旧版迁移extractConfig会从rootConfig[windowSize]与旧rootConfig[player]中回读rememberPipPosition旧版该开关由播放器设置拥有并保留windowsPipDisplayId、windowsPipWidth等旧版平铺别名使旧备份编辑器和降级导入仍能无损保留矩形window_size_controller.dart。导入时fromJson(extractConfig(data))统一走归一化入口旧版平铺字段与rememberPipPosition自动迁移到当前windowsPip/windowsPipPortrait嵌套结构backup_controller.dart。测试门禁与质量证据审计以确定性证据收尾修订前有效红灯local-artifacts/build-records/20260913T050333627Z-quality-focused.json证明共享尺寸合同、安全 getter 和范围提示尚不存在首轮修订门禁20260913T051548103Z-quality-focused.json覆盖 4 个直接相关文件27/27 PASS最终门禁20260913T052330318Z-quality-focused.json覆盖13 个测试文件、98/98 PASS涵盖窗口尺寸边界、窄屏/3.0 倍文字弹窗、PiP 几何与呈现、当前/旧版备份、升级迁移、播放器旧偏好、相邻视频/竖屏设置、基础页面与翻译合同同一最终门禁执行一次全库flutter analyze结果为No issues found仓库静态策略、工具夹具、翻译 JSON、格式检查与git diff --check全部通过结束后活跃重型进程为 0。仓库现有的几何测试可作佐证FloatWindowGeometry一组用例验证了损坏矩形不被记忆如宽高为零、字段为字符串的 payload 解码后均不产生恢复矩形见 test/core/config/float_window_geometry_test.dart与本次 PiP 几何整体清空的策略同源。验收边界与遗留取证本轮完成源码、Widget 与确定性持久化合同修订使验收项 A2-01Windows 设置完整性继续取得证据并保持RUN状态。以下场景仍依赖 Computer Use 原生批次在真实 Windows 候选机上取证五个预设的实际应用、400×300 与 16384×16384 边界、原生应用失败反馈、冷启动恢复、窗口缩放回写、PiP 多显示器迁移与进程重开。宏观账本保持20 PASS / 42 RUN / 0 NR共 42 组未闭环。相关源码索引共享尺寸合同与归一化入口lib/core/config/window_size_controller.dart桌面窗口初始化与事件回写lib/core/platform/desktop_manager.dartPiP 几何读写与方向判定lib/core/player/presentation/windows_pip_driver.dart窗口尺寸设置弹窗lib/features/settings/pages/general_settings_page.dart备份导出/导入与迁移lib/features/backup/backup_controller.dart弹窗范围与错误文案assets/translations/zh.json几何损坏校验参考test/core/config/float_window_geometry_test.dart赞分享音视频直播【免费下载链接】pure_live纯粹直播:哔哩哔哩/虎牙/斗鱼/快手/抖音/网易cc/YY直播/Twitch直播/SOOP直播/M38自定义源应有尽有。项目地址https://gitcode.com/gh_mirrors/pur/pure_live点击查看免费下载相关推荐纯粹直播PureLiveWindows 窗口几何捕获所有权重构普通窗口尺寸与 PiP 矩形的隔离持久化纯粹直播PureLiveWindows 窗口几何捕获所有权重构普通窗口尺寸与 PiP 矩形的隔离持久化 导读 本文基于纯粹直播仓库的审计文档 WINDOW音视频直播pure_live Windows 小窗几何捕获与重置事务审计显示器身份持久化、弹窗事务门禁与回归验证pure_live Windows 小窗几何捕获与重置事务审计显示器身份持久化、弹窗事务门禁与回归验证 本篇技术指南围绕 pure_live纯粹直播Win音视频直播brave/browser-laptop窗口状态持久化尺寸与位置保存实现brave/browser laptop窗口状态持久化尺寸与位置保存实现 窗口状态持久化是提升用户体验的关键功能确保用户重启浏览器后仍能恢复上次关闭时的窗口桌面应用上一篇为什么值得试爪爪 PawWorkselection-first 网页 Agent 的 5 大核心卖点下一篇OpenCompass 快速开始模型评测的配置、推理、评估与可视化全流程指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考