Aug 01, 2025
2 min read
Rust,
Tauri,

Rust Tauri v2 桌面应用开发:非常规窗口与系统权限处理

本文深入探讨了使用 Tauri v2 和 Rust 开发非常规窗口应用(如截图工具、悬浮窗、桌面歌词等)的技术细节,包括多窗口管理、系统权限申请(特别是 macOS 的 ScreenRecording 权限)以及权限与窗口的关联配置。

对于非常规的窗口应用(截图工具、悬浮窗、桌面歌词等),我一直以来都比较好奇是怎么实现的。

以 Tauri 为例子,我们至少要隐藏窗口边缘、窗口阴影、任务栏。最好把最大化最小化以及可拉伸窗口大小功能也禁止掉。然后再把内容透明化(半透明化)。这里有一个示例记录:Tauri 2 实现透明窗口

多窗口

这些非常规的窗口应用必然是多窗口应用,因为总需要提供一个配置或者设置的功能。对于多窗口而言,Tauri 提供 2 种创建方式,一种是静态的,直接在tauri.conf.json 就能配置。不过静态的虽然方便,但是太过于死板了,并不友好。因此还有一种动态的创建方式。

而动态的方式又可以分 2 种: Rust 层创建和 前端层(js) 创建。本质上还是 Rust 在创建,前端层是导出的。

实现也比较简单:

fn create_setting_window(app: &tauri::AppHandle) {
    tauri::WebviewWindowBuilder::new(
        app,
        "setting",
        tauri::WebviewUrl::App("/settings".parse().unwrap()),
    )
    .title("设置")
    .position(100.0, 100.0)
    .build()
    .unwrap();
}

一般我们在某个事件后面直接调用即可,比如点击菜单进入设置,就创建设置窗口:

app.on_menu_event(move |app_handle: &tauri::AppHandle, event| {
	match event.id().0.as_str() {
		"open_settings" => create_setting_window(app_handle),
		"close" => {
			println!("close event");
		}
		_ => {
			println!("unexpected menu event");
		}
	}
});

系统权限

Windows 没有深入地做过开发,所以不太了解。 LInux 总体来说没有什么权限需要申请的。 但是 macOS 情况大有不同。比如以屏幕截图这个功能为例子,除非你只对自身的应用本身以及空桌面进行截图,否则你的应用是拿不到其他应用界面的。

想拿到系统级的截图,必须申请一个叫ScreenRecording 的权限。在用户端里,他的使用流程可能是这样的:

  1. 打开应用
  2. 检测到没有ScreenRecording 的权限3
  3. 点击授权
  4. 跳转打开设置->隐私与安全性->录屏与系统录音->把相关应用的权限那一项打开
  5. 重开应用

如果使用 macOS 官方的框架体系开发这不是什么难事。但是我们这里讨论的是 Tauri 和 Rust。

Tauri 可以用这个插件搞定相关权限:tauri-plugin-macos-permissions。不过这个插件好像有一些 bug,有时候申请不到权限。

权限与多窗口

Tauri 的权限系统和多窗口有一些关联,就是它的权限可以按窗口来分配:

{
"windows": [
    "main",
    "setting"
  ],
  "permissions": [
    "core:default",
    ]
}

上面就定义了 2 个窗口,一个是主窗口 main,一个是 setting窗口。

开发模式

在 macOS 开发模式下,我们也需要快速获取系统权限怎么办? 这分两情况,无 GUI和有 GUI,

无 GUI 的默认是命令行,那么默认运行的是终端,我们只需要按上面的授权步骤把终端 app 添加到授权名单即可。

有 GUI 的要为应用本身添加授权,在开发模式下,Rust 运行cargo run 也是先编译生成目标文件,再运行的,因此我们只需要把目标文件按上面的授权步骤添加到名单即可。