对于非常规的窗口应用(截图工具、悬浮窗、桌面歌词等),我一直以来都比较好奇是怎么实现的。
以 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 的权限。在用户端里,他的使用流程可能是这样的:
- 打开应用
- 检测到没有
ScreenRecording的权限3 - 点击授权
- 跳转打开设置->隐私与安全性->录屏与系统录音->把相关应用的权限那一项打开
- 重开应用
如果使用 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 也是先编译生成目标文件,再运行的,因此我们只需要把目标文件按上面的授权步骤添加到名单即可。