feat: 添加双屏控制功能,支持在第二块屏幕上全屏展示内容;更新相关 UI 和逻辑以适应新功能

This commit is contained in:
Pine
2026-08-19 13:13:54 +08:00
parent 1e63da95ec
commit 5ed396aea4
8 changed files with 123 additions and 16 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "Capability for the main window",
"windows": ["main"],
"windows": ["main", "secondary"],
"permissions": [
"core:default",
"core:window:default",
+49 -4
View File
@@ -4,7 +4,49 @@
use std::fs;
use std::path::PathBuf;
use tauri::{AppHandle, Manager};
use tauri::{AppHandle, Manager, WebviewUrl, WebviewWindowBuilder};
/// 双屏控制:on=true 在第二块屏幕上新建一个全屏窗口(加载前端首页),on=false 关闭它。
/// 用于 admin 端「启动双屏」,让展播内容同时投到电脑的另一块显示器。
#[tauri::command]
fn set_dual_screen(app: AppHandle, on: bool) -> Result<String, String> {
if !on {
if let Some(w) = app.get_webview_window("secondary") {
let _ = w.close();
}
return Ok("off".into());
}
// 已存在则直接显示/全屏/聚焦
if let Some(w) = app.get_webview_window("secondary") {
let _ = w.show();
let _ = w.unminimize();
let _ = w.set_fullscreen(true);
let _ = w.set_focus();
return Ok("on".into());
}
let mut builder = WebviewWindowBuilder::new(&app, "secondary", WebviewUrl::App("/".into()))
.title("OPC 运营中心 · 双屏");
// 定位到第二块屏(非主屏;无第二屏则用第一块)
if let Ok(monitors) = app.available_monitors() {
let primary_pos = app
.primary_monitor()
.ok()
.flatten()
.map(|pm| { let p = pm.position(); (p.x, p.y) });
let target = monitors
.iter()
.find(|m| { let p = m.position(); Some((p.x, p.y)) != primary_pos })
.or_else(|| monitors.first());
if let Some(mon) = target {
let p = mon.position();
let s = mon.size();
builder = builder.position(p.x as f64, p.y as f64).inner_size(s.width as f64, s.height as f64);
}
}
let win = builder.build().map_err(|e| e.to_string())?;
let _ = win.set_fullscreen(true);
Ok("on".into())
}
/// 读取运行时配置(部署用,免重新打包):
/// 1) exe 同目录 config.json / dpm.config.json(最高优先)
@@ -47,11 +89,14 @@ pub fn run() {
tauri_plugin_autostart::MacosLauncher::LaunchAgent,
Some(vec![]),
))
.invoke_handler(tauri::generate_handler![read_runtime_config])
.invoke_handler(tauri::generate_handler![read_runtime_config, set_dual_screen])
.on_window_event(|window, event| {
if let tauri::WindowEvent::CloseRequested { api, .. } = event {
api.prevent_close();
let _ = window.minimize();
// 仅主窗口关闭=最小化(进程常驻);双屏副窗口可正常关闭
if window.label() == "main" {
api.prevent_close();
let _ = window.minimize();
}
}
})
.run(tauri::generate_context!())