Files
tauri-meeting/src-tauri/src/tray/common_tray.rs
O昵称重要吗O 78af453fe1 chore: 初始化项目基础结构和资源文件
- 添加项目图标文件(app-icon.png、各平台图标)
- 配置开发环境文件(.env、.nvmrc、.npmrc)
- 添加静态资源文件(背景图片、字体、音频)
- 初始化Tauri后端结构(build.rs、main.rs、模块文件)
- 配置前端项目结构(TypeScript、Vue组件、样式)
- 添加Node.js API服务基础结构
- 配置构建和开发工具(vite、prettier、gitignore)
2026-03-13 10:03:05 +08:00

84 lines
3.3 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use crate::audio::play_prompt_tone_imp;
use crate::window::{WindowLabel, create_popup_window::create_popup_window_impl, derive::TargetLocation};
use tauri::{AppHandle, Runtime, tray::TrayIconBuilder};
/// 创建并设置系统托盘图标
///
/// 该函数会检查是否已存在相同ID的托盘图标以避免重复添加
/// 并为托盘图标绑定点击事件处理函数,点击时直接打开弹出框窗口。
pub fn setup_tray<R: Runtime>(app: &AppHandle<R>) -> Result<(), String> {
let tray_id = WindowLabel::MAIN_TRAY.as_ref();
// 检查是否已经存在托盘图标,避免重复添加
if app.tray_by_id(tray_id).is_some() {
return Ok(());
}
// 获取默认窗口图标
let icon = app.default_window_icon().ok_or("获取默认窗口图标失败")?.clone();
// 创建托盘图标(不关联菜单)
use std::sync::Arc;
let app_shared = Arc::new(app.clone());
TrayIconBuilder::with_id(tray_id)
.icon(icon)
.tooltip("智评会议")
.on_tray_icon_event(move |_tray, event| {
// 处理托盘图标点击事件
if let tauri::tray::TrayIconEvent::Click {
button_state: tauri::tray::MouseButtonState::Up,
rect,
..
} = event
{
let app_handle = Arc::clone(&app_shared);
// 如果popup窗口不存在则创建并显示弹出框窗口
tauri::async_runtime::spawn(async move {
// 获取主显示器的缩放因子
let scale_factor = (*app_handle).primary_monitor().ok().flatten().map(|monitor| monitor.scale_factor()).unwrap_or(1.0);
let target = get_target_location(&rect, scale_factor);
// 直接调用后端函数创建弹出框窗口
let _ = create_popup_window_impl(&app_handle, &target, "auto").await;
play_prompt_tone_imp();
});
}
})
.build(app)
.map_err(|e| format!("创建托盘图标失败: {}", e))?;
// 托盘图标创建成功
Ok(())
}
/**
* 获取目标位置信息
*/
fn get_target_location(rect: &tauri::Rect, scale_factor: f64) -> TargetLocation {
// 使用scale_factor将物理坐标转换为逻辑坐标
// 在托盘图标的上下文中默认使用1.0作为scale_factor
// 这样可以确保返回的坐标始终是逻辑坐标
let x = match rect.position {
tauri::Position::Physical(physical_position) => (physical_position.x as f64 / scale_factor) as i32,
tauri::Position::Logical(logical_position) => logical_position.x as i32,
};
let y = match rect.position {
tauri::Position::Physical(physical_position) => (physical_position.y as f64 / scale_factor) as i32,
tauri::Position::Logical(logical_position) => logical_position.y as i32,
};
let width = match rect.size {
tauri::Size::Physical(physical_size) => (physical_size.width as f64 / scale_factor) as u32,
tauri::Size::Logical(logical_size) => logical_size.width as u32,
};
let height = match rect.size {
tauri::Size::Physical(physical_size) => (physical_size.height as f64 / scale_factor) as u32,
tauri::Size::Logical(logical_size) => logical_size.height as u32,
};
TargetLocation { x, y, width, height }
}