Tauri + Wake Lock 实战:双端状态机、重获锁与发布一致性
ScreenAwake 最初只想解决一个很小的问题演示、照着教程操作或等待任务时不要让屏幕先熄灭。真正开始实现后我发现“保持常亮”不是一个按钮而是两套不同的系统契约网页只能申请浏览器提供的 Screen Wake Lock桌面端则要持有操作系统级的电源抑制资源。它们可以共用界面却不能共用对生命周期的承诺。这篇复盘不讲“几小时做完一个小工具”只拆四个工程问题用户意图与资源状态为什么要分开、网页锁为何必须重获、桌面端如何确定性清理以及双端发布物怎样避免版本身份漂移。先定义两种产品承诺ScreenAwake 同时提供网页临时模式和 Tauri 桌面模式。两端看起来都只有“开启常亮”背后的约束完全不同。维度网页模式桌面模式核心能力navigator.wakeLock.request(screen)macOScaffeinate、WindowsSetThreadExecutionState、Linuxsystemd-inhibit可见性只有可见、活跃文档能可靠申请主窗口隐藏后仍可由进程持有资源资源句柄WakeLockSentinel可能被浏览器或系统释放子进程或系统电源状态必须由应用主动清理用户预期临时使用标签页需保持可见托盘、倒计时、开机启动、关闭窗口后继续主要失败面浏览器不支持、页面隐藏、低电量或系统策略权限、平台 API、进程残留、退出清理、安装签名MDN 明确说明Screen Wake Lock 只面向可见的活跃文档系统可以因为页面不可见、电量或平台设置释放锁。W3C 草案还把底层获取描述为 advisory-only调用成功不等于应用获得了绕过所有系统策略的保证。所以网页端的产品文案必须是“在支持的浏览器和允许条件下保持屏幕常亮”不能写成“永久阻止休眠”。桌面端能力更强也不能绕过企业 MDM、手动锁屏或组织安全策略。用户意图不等于资源状态网页端最容易写出的实现是拿state.active同时表示两件事用户想继续保持常亮以及当前 Wake Lock 仍然有效。问题是浏览器释放锁时active会变成false当标签页再次可见程序已经不知道用户是主动点了“停止”还是资源被系统暂时收走。ScreenAwake 后来把这两个状态拆开letwebWakeLock:WakeLockSentinel|undefined;letwebKeepAwakeRequestedfalse;asyncfunctionstart(){webKeepAwakeRequestedtrue;webWakeLockawaitnavigator.wakeLock.request(screen);}asyncfunctionstop(){webKeepAwakeRequestedfalse;awaitwebWakeLock?.release();webWakeLockundefined;}webKeepAwakeRequested是用户意图webWakeLock是当前资源句柄。前者只有用户操作才能取消后者可以被浏览器、系统或代码释放。这个拆分不只适用于 Wake Lock。WebSocket、麦克风流、蓝牙连接、文件句柄和长任务也应该区分“用户仍然需要”与“资源此刻可用”。否则一次短暂断开就会被误判为用户取消。被释放的 Sentinel 不能复用WakeLockSentinel被释放后不能重新激活如果用户意图仍然存在应用必须申请一个新对象。ScreenAwake 在release事件中先确认回调对应的仍是当前句柄再清理状态页面重新可见时只在用户仍有意图且句柄不存在或已释放时重获锁acquiredWakeLock.addEventListener(release,(){if(webWakeLockacquiredWakeLock)webWakeLockundefined;state.activefalse;state.powerGuardActivefalse;render();});document.addEventListener(visibilitychange,(){constshouldReacquiredocument.visibilityStatevisiblewebKeepAwakeRequested(!webWakeLock||webWakeLock.released);if(shouldReacquire)voidstart();});这里保留acquiredWakeLock局部引用是为了防止旧对象的延迟release事件把新句柄清掉。它和网络请求里的 request ID、搜索建议里的 sequence number 是同一类并发防线旧事件不能覆盖新状态。桌面端先持有主资源再叠加可选兜底桌面端没有把鼠标微动当成主方案。主路径是操作系统电源抑制锁macOS 启动caffeinate -d -iWindows 调用SetThreadExecutionStateLinux 启动systemd-inhibit。鼠标微动、Shift 短按和隐藏窗口 ping 都是可选策略。鼠标微动在 macOS 上还要先检查辅助功能权限键盘兜底默认关闭。这个顺序很重要能用系统提供的电源 API就不应先模拟用户输入。桌面状态机每次开始前先停止旧控制器再创建新资源和截止时间pubfnstart(self,options:AwakeOptions)-ResultAppStatus,String{self.stop();letmutcontrollerself.controller.lock().map_err(|_|状态锁不可用.to_string())?;controller.power_guardSome(PowerGuard::start()?);controller.deadlineoptions.duration_seconds.filter(|seconds|*seconds0).map(|seconds|Instant::now()Duration::from_secs(seconds));Ok(Self::status_locked(controller))}start()先调用stop()可以避免重复点击后残留两份caffeinate子进程、输入线程或倒计时。停止时再依次翻转原子标志、结束输入线程、停止窗口 ping、释放电源锁并清空截止时间。这是一条适合小工具的简单不变量任意时刻最多只有一组持有资源的控制器。关闭窗口不等于停止任务桌面端另一个容易混淆的状态是“窗口关闭”和“应用退出”。ScreenAwake 拦截主窗口关闭把窗口隐藏到托盘只有托盘退出或进程退出时才停止电源防护。.on_window_event(|window,event|{iflettauri::WindowEvent::CloseRequested{api,..}event{api.prevent_close();let_window.hide();}}).run(|app,event|{ifletRunEvent::ExitRequested{..}event{app.state::AppState().stop();}});如果产品把“关窗口”定义成“停止常亮”就不该隐藏到托盘如果定义成后台继续界面必须明确提示托盘也必须提供停止和退出入口。生命周期不是框架默认行为而是产品契约。双端发布要记录两种构建身份ScreenAwake 的网页端在main推送后自动部署 GitHub Pages桌面端则在v*标签上构建 Release。两条流水线本身没有问题但它们会让“当前版本”出现两种身份。本次核验时发布面核验身份结果GitHub Pages /main1802fa2922ac1ddaebb748b9649f9636cdbaae10包含返回可见时重获 Wake Lock 的修复桌面 Releasev0.1.2b6e5e8f7c8e6291553e9656cc8ed27f13c661cc4早于上述网页修复package.json/ Tauri 配置0.1.2两端仍显示同一语义版本号这意味着“版本号都是 0.1.2”不能证明网页与桌面包含同一提交。更稳妥的做法是让两个界面显示version short commit发布记录同时保存 Pages 提交、Release tag 和资产校验值。最小检查可以写成gitrev-parse HEADgitrev-parsev0.1.2^{commit}gitlog--onelinev0.1.2..HEAD如果网页修复也应该进入桌面包就应发布新 tag如果只影响网页也要在发布记录中明确两个分发面的能力差异。本次验证通过了什么我在 2026-08-02 对公开仓库和页面做了重新核验npm ci成功npm run build成功Vite 生产构建生成distcargo check --manifest-path src-tauri/Cargo.toml成功cargo test --manifest-path src-tauri/Cargo.toml命令成功但实际运行0 个单元测试、0 个文档测试Ego 真实浏览器打开公开网页页面标题、四档时长和navigator.wakeLock支持回读正常GitHub Releases 公开页显示v0.1.2为 Latest并能追溯到 tag 提交源码共 9 个主要前后端文件仓库内未发现 JavaScript / TypeScript 测试文件或 Rust#[test]。所以当前能说的是“源码可以完成前端生产构建和本机 Rust 静态检查”不能说“桌面端已被自动化测试覆盖”也不能说 Windows x64、macOS ARM64、托盘、开机启动、快捷键、倒计时和退出清理都已经完成本轮端到端回归。下一版最该补的三道门第一道是状态机测试。至少覆盖用户主动停止、页面隐藏自动释放、返回可见重获、旧 Sentinel 延迟事件、重复开始、倒计时到期和退出清理。第二道是发布物身份。网页和桌面都显示提交短 SHARelease 记录资产 SHA-256面向 macOS 公开分发前补齐 Developer ID 签名和公证而不是把临时签名写成完整分发能力。第三道是真机矩阵。网页端验证支持与不支持 Wake Lock 的浏览器、页面切后台、低电量和手动锁屏桌面端分别在 macOS ARM64、Windows x64 和计划支持的 Linux 环境验证系统 API 与退出清理。可复用检查表用户意图与当前资源句柄分开保存资源被系统释放时不误判为用户取消旧资源的延迟事件不能覆盖新资源重获资源前重新检查可见性、权限和系统条件重复开始前确定性停止上一组资源关闭窗口、停止任务和退出应用有明确区分主能力优先使用平台 API模拟输入只做可选兜底网页部署提交与桌面 Release tag 分别记录“测试命令成功”与“实际测试数量”分开报告未签名、公证、真机回归的能力不写成已完成。小工具真正难的地方通常不是把按钮点亮而是把“用户还想要什么”“系统现在给了什么”“资源何时必须收回”三件事分清楚。生命周期和发布身份一旦清楚网页与桌面才能共享产品体验而不是共享一组含糊承诺。来源与验证边界ScreenAwake 仓库网页端实现核验提交桌面状态机核验提交系统电源防护实现核验提交GitHub ReleasesMDN Screen Wake Lock APIW3C Screen Wake Lock 工作草案验证边界本文验证了公开网页、源码提交、前端生产构建、本机 Rustcheck与 Release 身份没有执行 Windows / macOS 安装包真机端到端回归也没有把cargo test的 0 个测试写成测试覆盖。

相关新闻

逻辑回归实战:从乳腺癌数据集到完整机器学习工作流

逻辑回归实战:从乳腺癌数据集到完整机器学习工作流

1. 项目概述:从数据到诊断的逻辑回归之旅 在机器学习的入门与实战领域,有一个数据集的地位堪比“Hello World”,那就是威斯康星州乳腺癌诊断数据集。它不像鸢尾花数据集那样简单,也不像MNIST那样庞大,但它完美地融合了…

2026/8/4 21:15:07 阅读更多 →
Python多线程编程:从基础到高级应用

Python多线程编程:从基础到高级应用

1. Python线程基础概念解析 在Python编程中,线程是最小的执行单元,也是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。理解线程对于编写高效、响应迅速的Python程序至关重要。 Python标准库中的 thread…

2026/8/5 19:18:47 阅读更多 →
虚拟电厂随机优化调度:蒙特卡洛与CPLEX实战

虚拟电厂随机优化调度:蒙特卡洛与CPLEX实战

1. 项目概述:虚拟电厂与随机优化调度虚拟电厂(Virtual Power Plant, VPP)作为能源互联网的核心技术之一,通过聚合分布式能源资源(DERs)实现与传统电厂等效的调度功能。这个MATLAB项目针对源(发电…

2026/8/5 19:19:16 阅读更多 →

最新新闻

GRBL-Plotter终极指南:如何用这款免费开源软件掌控你的CNC创作之旅

GRBL-Plotter终极指南:如何用这款免费开源软件掌控你的CNC创作之旅

GRBL-Plotter终极指南:如何用这款免费开源软件掌控你的CNC创作之旅 【免费下载链接】GRBL-Plotter A GCode sender (not only for lasers or plotters) for up to two GRBL controller. SVG, DXF, HPGL import. 6 axis DRO. 项目地址: https://gitcode.com/gh_mi…

2026/8/5 20:51:13 阅读更多 →
如何用微信小程序为情侣打造专属任务与商城系统?Rainbow-Cats-Personal-WeChat-MiniProgram深度解析

如何用微信小程序为情侣打造专属任务与商城系统?Rainbow-Cats-Personal-WeChat-MiniProgram深度解析

如何用微信小程序为情侣打造专属任务与商城系统?Rainbow-Cats-Personal-WeChat-MiniProgram深度解析 【免费下载链接】Rainbow-Cats-Personal-WeChat-MiniProgram 给女朋友做的微信小程序!情侣自己的任务和商城系统! 项目地址: https://git…

2026/8/5 20:51:13 阅读更多 →
OpenTX遥控器固件:3分钟快速上手,释放你的遥控器全部潜能

OpenTX遥控器固件:3分钟快速上手,释放你的遥控器全部潜能

OpenTX遥控器固件:3分钟快速上手,释放你的遥控器全部潜能 【免费下载链接】opentx OpenTX custom firmware for Transmitters 项目地址: https://gitcode.com/gh_mirrors/op/opentx OpenTX是一款革命性的开源遥控器固件,能够让你的普通…

2026/8/5 20:51:13 阅读更多 →
Android自动化从未如此简单:PageEyes Agent零代码操作指南

Android自动化从未如此简单:PageEyes Agent零代码操作指南

Android自动化从未如此简单:PageEyes Agent零代码操作指南 【免费下载链接】page-eyes-agent PageEyes Agent 是一个轻量级 UI Agent,通过自然语言指令驱动,无需编写脚本既可实现Web、Android平台的UI自动化任务。 项目地址: https://gitco…

2026/8/5 20:51:13 阅读更多 →
终极指南:如何用iptv-checker轻松管理你的IPTV播放列表

终极指南:如何用iptv-checker轻松管理你的IPTV播放列表

终极指南:如何用iptv-checker轻松管理你的IPTV播放列表 【免费下载链接】iptv-checker IPTV checker tool for Docker && CMD, check your playlist is available 项目地址: https://gitcode.com/GitHub_Trending/ip/iptv-checker 还在为IPTV播放列表…

2026/8/5 20:51:13 阅读更多 →
2026从零搭建外贸拓客矩阵全指南:海关数据/社媒/邮件工具特性梳理,主流拓客系统评测及合规服务商避坑攻略

2026从零搭建外贸拓客矩阵全指南:海关数据/社媒/邮件工具特性梳理,主流拓客系统评测及合规服务商避坑攻略

2026从零搭建外贸拓客矩阵全指南:海关数据/社媒/邮件工具特性梳理,主流拓客系统评测及合规服务商避坑攻略2026年,外贸行业数字化转型进入深度落地阶段,传统线下展会的获客成本持续高企,海外市场竞争格局也在随地缘、合…

2026/8/5 20:50:13 阅读更多 →

日新闻

Java缓存框架:JetCache

Java缓存框架:JetCache

TOC 一、简介 JetCache 是一个 Java 缓存抽象框架,为不同的缓存解决方案提供了统一的使用方式。 它提供的注解比 Spring Cache 更加强大。 JetCache 的注解支持原生 TTL、两级缓存以及在分布式环境中的自动刷新功能,同时你也可以通过代码直接操作 Cach…

2026/8/5 0:00:43 阅读更多 →
AD 铺铜设置十字连接,过孔全连接,新版AD的简单设置

AD 铺铜设置十字连接,过孔全连接,新版AD的简单设置

需求:通孔焊盘 十字花;过孔 Via 实心直连;贴片焊盘按需设置 AD 测试版本AD24 很多工程师踩坑:全部统一十字,导致接地过孔阻抗高、大电流发热! 一、快捷键打开规则 PCB 界面按下:D R 展开…

2026/8/5 0:00:43 阅读更多 →
AI素描转换技术深度拆解(2024最新论文+工业级落地代码):从Stable Diffusion ControlNet到LoRA微调全链路解析

AI素描转换技术深度拆解(2024最新论文+工业级落地代码):从Stable Diffusion ControlNet到LoRA微调全链路解析

更多请点击: https://kaifayun.com 第一章:AI生成素描效果 AI生成素描效果是计算机视觉与风格迁移技术融合的典型应用,其核心在于将彩色照片或RGB图像转换为具有手绘质感、明暗对比强烈、边缘清晰的单色素描图像。该过程通常依赖于深度学习模…

2026/8/5 0:00:43 阅读更多 →

周新闻

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

最大流算法详解:从水管网络到Ford-Fulkerson与Dinic实战

1. 从水管网络到最大流:一个核心问题的诞生想象一下,你是一个城市供水系统的总工程师。你的城市有多个水源(水库),需要通过一个复杂的地下管道网络,将水输送到各个居民区。每条管道都有其最大通水能力&…

2026/8/5 15:00:43 阅读更多 →
基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

基于Springboot的企业门户网站(源码+LW+调试文档+讲解)

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/8/5 13:13:56 阅读更多 →
MATLAB xcorr函数详解:从互相关原理到四大实战应用

MATLAB xcorr函数详解:从互相关原理到四大实战应用

1. 从一次信号“找茬”说起:为什么我们需要互相关几年前,我在处理一组声学传感器数据时遇到了一个棘手的问题。我有两个麦克风记录了一段相同的音频信号,理论上它们接收到的声音波形应该非常相似,只是由于麦克风位置不同&#xff…

2026/8/5 10:20:36 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/4 13:38:24 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/4 11:09:16 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/4 13:38:40 阅读更多 →