桌面应用开发工具【免费下载链接】MooToolHandy tool set for developers项目地址https://gitcode.com/gh_mirrors/mo/MooTool点击查看免费下载导读本文以 MooTool 仓库中已采纳的 ADR-010原生桌面体验与平台差异 为骨架深入解析 MooTool Next Tauri 产品线在 macOS、Windows 与 Linux 上如何统一实现截图后选区、可视化取色、图片剪贴板、拖放导入和防显示器休眠这一套桌面任务闭环。全文结合 Rust 命令层、前端 API 适配层、Tauri 能力清单 与各工具页面实现说明每个决策背后的权限边界、参数约束与批准的平台差异。读完本文你将掌握该产品线原生桌面能力的调用链、校验规则与跨平台降级策略。背景并行产品线中的同一套桌面任务闭环MooTool Next Tauri 与 Java、Next Electron 是并行产品线并非以迁移 Electron 源码为目标。ADR-010 明确了一个关键前提截图、取色、剪贴板、防休眠、拖放和窗口外观应在三个桌面平台上尽量保持相同的用户任务闭环。但由于 Tauri 使用系统 WebView各平台对桌面捕获、透明窗口、全局指针和 Wayland Portal 的支持能力各不相同因此需要以 ADR 形式固定首版行为并把批准差异明确记录下来而不是逐平台即兴实现。从仓库结构看这条边界在工程上被明确落实为两层原生依赖与平台差异全部封装在 Rust/Platform API 层工具页面不直接读取任意文件路径也不调用外部 shell前端仅通过 nativeDesktopApi.ts 暴露的四个命令与 Rust 侧通信captureDisplays、sampleScreenColor、getDisplaySleepStatus、setDisplaySleepPrevention。决策一截图 隐藏窗口 xcap 全显示器捕获ADR-010 的第一项决策是截图由 Rust 先隐藏当前可见的 MooTool 窗口再捕获所有显示器前端显示捕获快照允许切换显示器、按物理像素框选区域、保留整屏或取消保存区域后删除临时整屏资产。首版不创建覆盖全部显示器的透明 Overlay也不支持一次选区跨越两个显示器。命令调用链前端入口在 ImageSurface.tsx 的captureScreen()默认调用nativeDesktopApi.captureDisplays()默认delayMs 350captureScreen → capture_display_images → hide_visible_windows → sleep(delayMs) → capture_all_monitors(xcap) → restore_windows → persist PNG 资产Rust 侧 native_desktop.rs 的实现顺序是通过validate_delay校验延迟参数必须在 100–2000 ms 之间越界直接返回错误借助NativeDesktopManager.capture这把AsyncMutex做单飞保护避免截图与取色并发竞争hide_visible_windows遍历app.webview_windows()只隐藏当前可见的窗口并记录每个被隐藏窗口的 label 与 focus 状态等待delay_ms让窗口真正消失后在spawn_blocking线程中执行capture_all_monitors无论成功失败都会执行restore_windows恢复窗口并重新聚焦保证截图不会丢失应用窗口。显示器捕获的物理像素语义capture_all_monitorsnative_desktop.rs使用xcap::Monitor::all()枚举显示器并按(y, x)排序随后对每个显示器执行monitor.capture_image()把原始 RGBA8 帧通过PngEncoder编码为 PNG。这里有两个值得注意的边界常量常量值作用MAX_MONITORS16显示器数量超出 1–16 范围时直接拒绝MAX_CAPTURED_IMAGE_BYTES20 MiB任一显示器 PNG 超过 20 MiB 即中止与图片库单图上限一致捕获结果按Screenshot-{timestamp}-{display_id}-{index}.png命名通过persist_image_bytes写入图片库images.rs期间任何一个显示器写入失败都会回滚已写入的全部资产。前端随后用imageApi.read逐个读取快照资产交给CaptureEditor完成选区。前端选区交互在 ImageSurface.tsx 的CaptureEditor中多显示器时顶部出现显示器切换按钮capture.monitor并在按钮上直接显示物理分辨率用户在快照上拖拽出选区选区坐标按clientX → asset.width的物理像素比例换算Math.round((event.clientX - rect.left) * asset.width / rect.width)因此选区是按物理像素而非 CSS 像素框选选区宽度或高度小于 2 px 时保存选区按钮被禁用提供保留整屏keepFullCapture与取消cancelCapture两个出口取消时会删除本次生成的全部临时整屏资产。saveCaptureRegion通过cropDataUrl从 dataURL 裁出选区并另存为新的图片资产随后imageApi.delete删除所有整屏快照——这与 ADR保存区域后删除临时整屏资产的决策完全一致。决策二屏幕取色复用快照不依赖 WebView EyeDropperADR-010 的第二项决策是屏幕取色复用隐藏窗口后的显示器快照提供实时色块、HEX/RGB 与像素坐标单击确认、Esc 取消。这样既不需要 WebView 的 EyeDropper 权限也不要求用户在固定倒计时内盲移指针。双路径设计ColorSurface.tsx 的sampleScreen()是典型的分支实现在 Tauri 运行时window.__TAURI_INTERNALS__存在调用nativeDesktopApi.captureDisplays()读取全部显示器快照后进入ScreenColorEditor在纯浏览器预览环境回退到EyeDropperAPI取色结果直接写入颜色输入框。ScreenColorEditor用隐藏 Canvas 承载快照鼠标移动时通过getImageData(x, y, 1, 1)实时读取像素换算为#RRGGBB大写 HEX、RGB 分量和物理像素坐标悬浮色块跟随指针展示单击确认confirmScreenColor把该色写入主面板Esc 键取消onCancel两种出口都会imageApi.delete删除临时快照资产。与 Rust 全局指针采样的关系值得注意的是ADR 中描述的取色复用快照是首版交付路径Rust 侧同时保留了sample_screen_color命令native_desktop.rs它通过mouse_positioncrate 读取全局指针位置用xcap::Monitor::from_point定位所在显示器再capture_region(x, y, 1, 1)采 1×1 像素并格式化为ScreenColorSample。该命令的delayMs校验范围为 500–5000 mscolor_sample的 HEX 格式化与validate_delay均有单测覆盖native_desktop.rs。决策三平台捕获差异封装与可理解的失败语义ADR-010 第三项决策要求macOS、Windows、Linux X11 的捕获通过 Tauri-owned Rust 适配器调用xcap失败必须显示可理解的权限/桌面会话错误。Linux Wayland 在无法取得显示器或全局指针时明确禁用本次操作不返回猜测颜色。Portal Overlay 作为后续平台增强不阻塞产品线。Rust 侧用统一的错误包装兑现了可理解要求。screen_capture_errornative_desktop.rs把任何xcap底层错误改写为native screen capture failed: {error}; verify screen-recording permission and the current desktop session而sample_color_at_pointer在Mouse::get_mouse_position()返回Mouse::Error时直接返回 global pointer position is unavailable; Wayland may require an X11 session这正是 ADR 所说Wayland 明确禁用、不猜测的实现。前端 nativeDesktopApi.ts 还为非 Tauri 环境提供了unavailable抛错与空状态降级浏览器预览不会因为缺少原生能力而崩溃。测试层面native_screen_capture_smokenative_desktop.rs被标注为#[ignore]注释明确要求interactive desktop session and screen-recording permission——它验证所有捕获结果的 PNG 魔数\x89PNG\r\n\x1a\n与取色 HEX 长度为 7是需要真机人工跑的门禁。决策四剪贴板与拖放的最小权限模型剪贴板统一走官方插件ADR 规定图片与文本剪贴板统一使用 Tauri 官方clipboard-manager插件Cargo.toml中tauri-plugin-clipboard-manager 2但权限按最小授权原则拆分到能力清单tool-clipboard-image.json读图/写图权限只开放给tool-image与tool-qrcode两个工具 WebView并附带core:image:allow-new/rgba/size以便把剪贴板位图转换为TauriImage再写回tool-clipboard-text.json只授予clipboard-manager:allow-write-text不授予读文本权限且仅覆盖提供显式复制动作的 17 个工具 WebView颜色、编码、JSON、正则、时间戳、翻译、UA、变量等default.json主工作台仅保留core:default不沾染剪贴板权限。前端封装在 clipboardApi.tsTauri 运行时走readNativeImage/writeNativeImage/writeNativeText浏览器预览回退到navigator.clipboard。在 ImageSurface.tsx 的copyImage()中可以看到实际写入路径dataURL → Canvas →ImageData→TauriImage.new(rgba, width, height)→writeClipboardImage用完即nativeImage.close()。拖放原生路径事件而非 DOM File图片拖放使用 Tauri WebView 原生路径事件。getCurrentWebview().onDragDropEventImageSurface.tsx只在 Tauri 运行时注册drop事件的paths直接交给imageApi.importPaths非 Tauri 环境则退化为 DOMonDropdataTransfer.files。Rust 侧import_image_filesimages.rs把 ADR 的校验逐条落地校验项规则违规处理数量1–50 个路径越界直接拒绝路径必须是绝对路径回滚已导入后报错文件类型必须是非符号链接的常规文件symlink_metadata!is_file判否回滚大小1 字节至 20 MiBMAX_IMAGE_BYTES回滚真实性inspect_image_bytes必须真实解码出 MIME、宽高回滚回滚rollback_imported_images清理本批已导入资产—persist_image_bytes还会二次校验签名与宽高元数据一致性防止文件名看着是 PNG 实际不是的伪装文件入库。导出单张固定扩展名多张避让重名export_image_assetsimages.rs体现了两条 ADR 细节单张导出走原生保存对话框app.dialog().file()add_filter只放行该图片真实的扩展名并通过enforce_image_extension把用户输入的目标路径强制修正为真实图片扩展名如 JPEG →.jpg再校验目标不能是符号链接多张导出走目录选择unique_export_path自动避让目标目录里已有的同名文件某一张失败时只回滚本批已创建的文件for path in exported { fs::remove_file }不动历史文件。决策五防显示器休眠 按 owner 隔离的 tokenADR 第五项决策要求 Rust 维护按 owner 隔离的防休眠 token系统工具和留言板演示模式各自持有 owner一个页面退出不会关闭另一个页面仍需要的防休眠状态。状态模型DisplaySleepStatenative_desktop.rs的核心是一个OptionKeepAwaketoken 加一个HashSetStringownersstruct DisplaySleepState { token: OptionKeepAwake, owners: HashSetString, }set_display_sleep_preventionnative_desktop.rs的逻辑是owner 首次启用时加入集合任一 owner 禁用时从集合移除集合从空变非空时创建KeepAwaketoken从非空变空时释放 token。因此并发持有system-tool与message-board-presentation同时启用时只存在一个底层 token退出互不影响留言板退出演示模式只移除自己的 owner只要系统工具仍持有token 不会被释放。keepawake::Builder的参数在代码中完全可见display(true)idle(true)reason(MooTool display mode)app_name(MooTool Next Tauri)app_reverse_domain(com.rememberber.mootool.next.tauri)与 tauri.conf.json 的 identifier 一致。owner 字符串本身受validate_sleep_owner约束长度 1–64仅允许小写字母、数字与连字符单测里message-board-presentation通过而Other Product被拒native_desktop.rs。两个真实 owner 的调用方SystemSurface.tsx挂载时getDisplaySleepStatus(system-tool)恢复开关状态切换开关时setDisplaySleepPrevention(system-tool, !sleepPrevention)MessageBoardSurface.tsx进入演示模式时启用message-board-presentation退出演示模式的 effect 清理函数里对称地关闭它。两个页面通过不同的 owner 字符串实现了 ADR 要求的隔离语义。决策六macOS 窗口外观——隐藏标题 原生 Overlay不做透明 WebViewADR 规定 macOS 首版使用隐藏标题和原生 Overlay 标题栏保留系统红黄绿窗口按钮不启用macOSPrivateApi也不做完全透明 WebView。与 Electron 毛玻璃强度的差异属于批准差异优先保证直接分发、输入法和工具 WebView 稳定性。窗口配置直接落在 tauri.conf.json 的main窗口定义上{ label: main, title: MooTool Next Tauri, width: 1440, height: 900, minWidth: 760, minHeight: 620, center: true, hiddenTitle: true, titleBarStyle: Overlay }hiddenTitle与titleBarStyle: Overlay即隐藏标题 原生 Overlay 标题栏的声明式表达窗口按钮交给系统绘制同时 CSP 限制了object-src与frame-src均为none为工具 WebView 提供严格的内容边界。窗口恢复、关闭到托盘、托盘菜单与全局快捷键的生命周期由 desktop.rs 的setup/handle_window_event/handle_menu_event维护与原生标题栏决策协同构成 macOS 首发体验。决策七Windows 逻辑坐标与 per-monitor DPI在 Windows 上ADR 要求使用 WebView2/Tauri 的逻辑坐标和 per-monitor DPI 处理图片文件拖放一律走原生物理路径不从 DOMFile推断本地路径——这正是为什么 ImageSurface.tsx 在 Tauri 运行时关闭 DOM 的onDragOver/onDrop只信任onDragDropEvent的paths。真实多缩放显示器混合 DPI场景仍属于发布矩阵的人工验收项即自动化门禁之外需要真机确认的项目。决策八更新、签名与发布通道保持 Tauri 产品线独立ADR 强调自动更新、签名和发布通道继续使用 Tauri 产品线独立实现不与 Electron updater、证书或 Release 标签共用。这在仓库的 ADR 系列中是闭环的ADR-008自动更新清单 采用两层清单根 update-manifest.json 只做产品发现Tauri 客户端固定读取products.next-tauri并校验专属更新 URLnext-tauri-updaterRelease 中的latest.json才是 Tauri Updater 的稳定静态清单含三平台下载 URL 与 updater 签名ADR-009代码签名策略 规定所有可更新包必须使用 Tauri 产品线独占的 updater 私钥签名Java/Electron 不共用密钥macOS 0.x 开发预览允许 ad-hoc 签名、Windows 0.x 允许缺少 Authenticode但必须在 Release Notes 中明确系统信任警告。结果与验收三平台任务闭环、批准差异与工程边界三平台统一的任务闭环根据 ADR 的结果章节用户在三平台获得相同的任务闭环截图后选区隐藏窗口 → 捕获全部显示器 → 物理像素框选 → 保存/保留整屏/取消临时资产自动清理可视化取色基于快照实时显示色块、HEX/RGB 与坐标单击确认、Esc 取消图片剪贴板官方clipboard-manager插件 能力清单按工具最小授权拖放导入原生路径事件 Rust 侧数量/绝对路径/符号链接/大小/真实解码五重校验与批量回滚防显示器休眠按 owner 隔离的 token系统工具与演示模式互不干扰。明确记录的批准差异以下差异不阻塞 1.0 发布但必须在产品文档与错误提示中公开macOS 毛玻璃强度与 Electron 存在差异优先保证直接分发、输入法与工具 WebView 稳定性首版不支持一次选区跨越两个显示器也不创建全屏透明 OverlayLinux Wayland 下显示器/全局指针不可用时直接禁用操作Portal Overlay 留待后续平台增强。工程边界的兑现原生依赖与平台差异封装在 Rust/Platform API工具页面不直接读取任意文件路径或调用外部 shell这条承诺可以从仓库结构直接验证四个原生桌面命令全部集中在 native_desktop.rs前端只经过 nativeDesktopApi.ts 与 nativeDesktop.test.ts 定义的类型化接口访问工具 WebView 的能力由 tool-views.json 统一收口。P0 记录的角色调整ADR 最后特别说明P0 记录继续保留历史实测事实但不再承担 Go/No-Go 立项职责——即历史测量数据仍可作为参考证据但项目的原生桌面能力是否立项、如何立项以本文所述决策以及 ADR-008/009 等相邻决策为准。这一点与 ADR 作为固定首版行为与批准差异的定位一致它不是一份推测性方案而是一份已被仓库代码逐条落地的实施契约。赞分享桌面应用开发工具【免费下载链接】MooToolHandy tool set for developers项目地址https://gitcode.com/gh_mirrors/mo/MooTool点击查看免费下载相关推荐MooTool Next Flutter 桌面能力对齐截图裁剪、屏幕取色与六种风格 Token 的实现与验收MooTool Next Flutter 桌面能力对齐截图裁剪、屏幕取色与六种风格 Token 的实现与验收 本篇指南聚焦 MooTool Next Flut桌面应用开发工具MooTool Next Flutter P6 截图裁剪与取色桌面通道验收报告83 项单元测试全通过的实现细节MooTool Next Flutter P6 截图裁剪与取色桌面通道验收报告83 项单元测试全通过的实现细节 导读 本文是 MooTool 开源仓库中 Mo桌面应用开发工具MooTool Next Flutter 桌面通道实战剪贴板图片、关闭策略、托盘与分离持久化的 macOS 落地MooTool Next Flutter 桌面通道实战剪贴板图片、关闭策略、托盘与分离持久化的 macOS 落地 本文面向希望在 Flutter 桌面应用m桌面应用开发工具上一篇実行プランをハーネスの第一級市民にするrepo-template の PLANS.md 運用ガイド下一篇Proton Native 热重载Hot Reloading完整指南原理、配置与实战创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考