From fd39956d1d04614942556d205ece3231af8a1828 Mon Sep 17 00:00:00 2001 From: JunaYa Date: Wed, 20 Nov 2024 23:18:19 +0800 Subject: [PATCH 1/9] feat: add preview window pop --- preview.html | 14 ++ src-tauri/src/cmd/mod.rs | 5 + src-tauri/src/cmd/screenshot.rs | 149 ++++++++++++++++++ .../src/{scrapshot.rs => cmd/xcreenshot.rs} | 0 src-tauri/src/constants.rs | 3 + src-tauri/src/lib.rs | 19 +-- src-tauri/src/menu.rs | 8 +- src-tauri/src/platform/linux.rs | 14 ++ src-tauri/src/platform/mac.rs | 27 ++++ src-tauri/src/platform/mod.rs | 14 ++ src-tauri/src/platform/window.rs | 27 ++++ src-tauri/src/screenshot.rs | 149 ------------------ src-tauri/src/window.rs | 147 +++++++++++++++++ src-tauri/src/{windows.rs => xcap_utils.rs} | 32 +--- src/pages/preview/App.vue | 8 + src/pages/preview/main.ts | 10 ++ vite.config.ts | 1 + 17 files changed, 436 insertions(+), 191 deletions(-) create mode 100644 preview.html create mode 100644 src-tauri/src/cmd/mod.rs create mode 100644 src-tauri/src/cmd/screenshot.rs rename src-tauri/src/{scrapshot.rs => cmd/xcreenshot.rs} (100%) create mode 100644 src-tauri/src/constants.rs create mode 100644 src-tauri/src/platform/linux.rs create mode 100644 src-tauri/src/platform/mac.rs create mode 100644 src-tauri/src/platform/mod.rs create mode 100644 src-tauri/src/platform/window.rs delete mode 100644 src-tauri/src/screenshot.rs create mode 100644 src-tauri/src/window.rs rename src-tauri/src/{windows.rs => xcap_utils.rs} (65%) create mode 100644 src/pages/preview/App.vue create mode 100644 src/pages/preview/main.ts diff --git a/preview.html b/preview.html new file mode 100644 index 0000000..b43d739 --- /dev/null +++ b/preview.html @@ -0,0 +1,14 @@ + + + + + + + Setting + + + +
+ + + diff --git a/src-tauri/src/cmd/mod.rs b/src-tauri/src/cmd/mod.rs new file mode 100644 index 0000000..623817d --- /dev/null +++ b/src-tauri/src/cmd/mod.rs @@ -0,0 +1,5 @@ +mod screenshot; +mod xcreenshot; + +pub use self::screenshot::*; +pub use self::xcreenshot::*; diff --git a/src-tauri/src/cmd/screenshot.rs b/src-tauri/src/cmd/screenshot.rs new file mode 100644 index 0000000..117261f --- /dev/null +++ b/src-tauri/src/cmd/screenshot.rs @@ -0,0 +1,149 @@ +use std::{ + path::PathBuf, + process::Command, + thread, + time::{Duration, Instant}, +}; + +use chrono::Local; +use tauri::{Manager, Runtime}; +use tauri_plugin_store::StoreExt; + +#[tauri::command] +pub async fn capture_screen( + app_handle: tauri::AppHandle, + path: String, +) -> Result { + let start = Instant::now(); + + let images_dir = get_images_dir(app_handle, path)?; + + println!("images_dir: {:?}", images_dir); + std::fs::create_dir_all(&images_dir).map_err(|e| e.to_string())?; + + let filename = format!("screenshot_{}.png", Local::now().format("%Y%m%d_%H%M%S")); + let output_path = images_dir.join(&filename); + + Command::new("screencapture") + .arg("-x") + .arg(output_path.to_str().unwrap()) + .output() + .map_err(|e| e.to_string())?; + + println!("capture_screen 运行耗时: {:?}", start.elapsed()); + Ok(filename) +} + +#[tauri::command] +pub async fn capture_select( + app_handle: tauri::AppHandle, + path: String, +) -> Result { + let start = Instant::now(); + + let images_dir = get_images_dir(app_handle, path)?; + + let filename = format!("screenshot_{}.png", Local::now().format("%Y%m%d_%H%M%S")); + let output_path = images_dir.join(&filename); + + Command::new("screencapture") + .arg("-i") + .arg("-x") + .arg(output_path.to_str().unwrap()) + .output() + .map_err(|e| e.to_string())?; + + println!("capture_select 运行耗时: {:?}", start.elapsed()); + Ok(filename) +} + +#[tauri::command] +pub async fn capture_window( + app_handle: tauri::AppHandle, + path: String, +) -> Result { + let start = Instant::now(); + + let images_dir = get_images_dir(app_handle, path)?; + + let filename = format!("screenshot_{}.png", Local::now().format("%Y%m%d_%H%M%S")); + let output_path = images_dir.join(&filename); + + Command::new("osascript") + .args([ + "-e", + "tell application \"System Events\" to key code 48 using {command down}", + ]) // Cmd+Tab + .output() + .map_err(|e| e.to_string())?; + + thread::sleep(Duration::from_secs(1)); + + let output = Command::new("screencapture") + .args([ + "-iw", // 交互式窗口选择 + "-t", + "png", // 明确指定 PNG 格式 + "-C", // 捕获鼠标光标 + "-o", // 不包含窗口阴影 + "-T", + "0", // 没有延迟 + output_path.to_str().unwrap(), + ]) + .output() + .map_err(|e| e.to_string())?; + + if !output.status.success() { + println!("screencapture -wx 失败: {:?}", output.status); + } + + println!("capture_window 运行耗时: {:?}", start.elapsed()); + + Ok(filename) +} + +pub fn get_images_dir( + app_handle: tauri::AppHandle, + path: String, +) -> Result { + let store = app_handle + .get_store("settings.json") + .ok_or_else(|| "Could not get settings store".to_string())?; + + let screenshot_path = store + .get("screenshot_path") + .ok_or_else(|| "Screenshot path not found in settings".to_string())?; + println!("screenshot_path: {:?}", screenshot_path); + + // get value from Option + let screenshot_path = screenshot_path + .as_object() + .and_then(|obj| obj.get("value")) + .and_then(|value| value.as_str()) + .unwrap(); + + // 获取 AppLocalData 路径 + // 如果 screenshot_path 为空,则使用 app_local_data + let app_local_data = if screenshot_path.is_empty() { + app_handle.path().app_local_data_dir().unwrap() + } else { + PathBuf::from(screenshot_path) + }; + println!("app_local_data: {:?}", app_local_data); + + // 创建 images 文件夹 + // path 如果为空,则使用 app_local_data + let images_dir = if path.is_empty() { + app_local_data + } else { + app_local_data.join(path) + }; + + println!("images_dir: {:?}", images_dir); + std::fs::create_dir_all(&images_dir).map_err(|e| e.to_string())?; + + // let filename = format!("screenshot_{}.png", Local::now().format("%Y%m%d_%H%M%S")); + // let output_path = images_dir.join(&filename); + + Ok(images_dir) +} diff --git a/src-tauri/src/scrapshot.rs b/src-tauri/src/cmd/xcreenshot.rs similarity index 100% rename from src-tauri/src/scrapshot.rs rename to src-tauri/src/cmd/xcreenshot.rs diff --git a/src-tauri/src/constants.rs b/src-tauri/src/constants.rs new file mode 100644 index 0000000..b957cce --- /dev/null +++ b/src-tauri/src/constants.rs @@ -0,0 +1,3 @@ +pub const MAIN_WINDOW: &str = "main"; + +pub const PREVIEW_WINDOW: &str = "preview"; diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index c1dd507..c18fb34 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -2,10 +2,11 @@ use serde_json::json; use tauri::Manager; use tauri_plugin_store::StoreExt; +mod cmd; +mod constants; mod menu; -mod scrapshot; -mod screenshot; -mod windows; +mod platform; +mod window; #[tauri::command] fn greet(name: &str) -> String { @@ -20,7 +21,7 @@ pub fn run() { #[cfg(desktop)] configure_autostart(app); - windows::create_window(app)?; + window::create_window(app)?; menu::create_tray(app)?; @@ -43,11 +44,11 @@ pub fn run() { .plugin(tauri_plugin_shell::init()) .invoke_handler(tauri::generate_handler![ greet, - screenshot::capture_screen, - screenshot::capture_select, - screenshot::capture_window, - scrapshot::xcap_window, - scrapshot::xcap_monitor, + cmd::capture_screen, + cmd::capture_select, + cmd::capture_window, + cmd::xcap_window, + cmd::xcap_monitor, ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src-tauri/src/menu.rs b/src-tauri/src/menu.rs index 0d56fa7..643fc92 100644 --- a/src-tauri/src/menu.rs +++ b/src-tauri/src/menu.rs @@ -7,7 +7,7 @@ use tauri::{ AppHandle, Manager, }; -use crate::windows; +use crate::window; #[derive(Debug, Display, EnumString)] #[allow(non_camel_case_types, clippy::upper_case_acronyms)] @@ -153,14 +153,16 @@ fn handle_tray_menu_events(app: &AppHandle, event: MenuEvent) { match menu_id { MenuID::CAPTURE_SCREEN => { println!("Capture Screen"); + window::show_main_window(app); } MenuID::CAPTURE_SELECT => { println!("Capture Select"); - windows::display_monitors(); + window::hide_main_window(app); + let window = window::get_preview_window(app); + window::show_preview_window(&window); } MenuID::CAPTURE_WINDOW => { println!("Capture Window"); - windows::display_windows(); } MenuID::SETTING_MANAGER => { println!("Setting Manager"); diff --git a/src-tauri/src/platform/linux.rs b/src-tauri/src/platform/linux.rs new file mode 100644 index 0000000..2419479 --- /dev/null +++ b/src-tauri/src/platform/linux.rs @@ -0,0 +1,14 @@ +use tauri::{Emitter, WebviewWindow}; + +pub fn show_search_bar(window: &WebviewWindow) { + let _ = window.show(); + let _ = window.unminimize(); + window::center_search_bar(window); + let _ = window.set_focus(); + let _ = window.set_always_on_top(true); +} + +pub fn hide_search_bar(window: &WebviewWindow) { + let _ = window.minimize(); + let _ = window.emit(ClientEvent::ClearSearch.as_ref(), true); +} diff --git a/src-tauri/src/platform/mac.rs b/src-tauri/src/platform/mac.rs new file mode 100644 index 0000000..0638561 --- /dev/null +++ b/src-tauri/src/platform/mac.rs @@ -0,0 +1,27 @@ +use crate::window; +use tauri::WebviewWindow; + +pub fn is_visible(window: &WebviewWindow) -> bool { + window.is_visible().unwrap_or_default() +} + +pub fn show_preview_window(window: &WebviewWindow) { + let _ = window.show(); + let _ = window.unminimize(); + window::bottom_right_preview(window); + let _ = window.set_focus(); + let _ = window.set_always_on_top(true); +} + +pub fn hide_preview_window(window: &WebviewWindow) { + let _ = window.minimize(); +} + +pub fn show_main_window(window: &WebviewWindow) { + let _ = window.show(); + let _ = window.unminimize(); +} + +pub fn hide_main_window(window: &WebviewWindow) { + let _ = window.minimize(); +} diff --git a/src-tauri/src/platform/mod.rs b/src-tauri/src/platform/mod.rs new file mode 100644 index 0000000..91f9802 --- /dev/null +++ b/src-tauri/src/platform/mod.rs @@ -0,0 +1,14 @@ +#[cfg(target_os = "macos")] +pub mod mac; +#[cfg(target_os = "macos")] +pub use self::mac::*; + +#[cfg(target_os = "linux")] +pub mod linux; +#[cfg(target_os = "linux")] +pub use self::linux::*; + +#[cfg(target_os = "windows")] +pub mod windows; +#[cfg(target_os = "windows")] +pub use self::windows::*; diff --git a/src-tauri/src/platform/window.rs b/src-tauri/src/platform/window.rs new file mode 100644 index 0000000..b06b8c8 --- /dev/null +++ b/src-tauri/src/platform/window.rs @@ -0,0 +1,27 @@ +use tauri::{Emitter, WebviewWindow}; + +pub fn is_visible(window: &WebviewWindow) -> bool { + if let Ok(handle) = window.hwnd() { + let mut lpwndpl = WINDOWPLACEMENT::default(); + unsafe { + let _ = GetWindowPlacement::(handle, &mut lpwndpl); + // SHOW_WINDOW_CMD(2) == minimized + + return lpwndpl.showCmd != 2; + } + } + + false +} + +pub fn show_search_bar(window: &WebviewWindow) { + let _ = window.show(); + let _ = window.unminimize(); + window::center_search_bar(window); + let _ = window.set_focus(); +} + +pub fn hide_search_bar(window: &WebviewWindow) { + let _ = window.minimize(); + let _ = window.emit(ClientEvent::ClearSearch.as_ref(), true); +} diff --git a/src-tauri/src/screenshot.rs b/src-tauri/src/screenshot.rs deleted file mode 100644 index 86056fc..0000000 --- a/src-tauri/src/screenshot.rs +++ /dev/null @@ -1,149 +0,0 @@ -use std::{ - path::PathBuf, - process::Command, - thread, - time::{Duration, Instant}, -}; - -use chrono::Local; -use tauri::{Manager, Runtime}; -use tauri_plugin_store::StoreExt; - -#[tauri::command] -pub async fn capture_screen( - app_handle: tauri::AppHandle, - path: String, -) -> Result { - let start = Instant::now(); - - let images_dir = get_images_dir(app_handle, path)?; - - println!("images_dir: {:?}", images_dir); - std::fs::create_dir_all(&images_dir).map_err(|e| e.to_string())?; - - let filename = format!("screenshot_{}.png", Local::now().format("%Y%m%d_%H%M%S")); - let output_path = images_dir.join(&filename); - - Command::new("screencapture") - .arg("-x") - .arg(output_path.to_str().unwrap()) - .output() - .map_err(|e| e.to_string())?; - - println!("capture_screen 运行耗时: {:?}", start.elapsed()); - Ok(filename) -} - -#[tauri::command] -pub async fn capture_select( - app_handle: tauri::AppHandle, - path: String, -) -> Result { - let start = Instant::now(); - - let images_dir = get_images_dir(app_handle, path)?; - - let filename = format!("screenshot_{}.png", Local::now().format("%Y%m%d_%H%M%S")); - let output_path = images_dir.join(&filename); - - Command::new("screencapture") - .arg("-i") - .arg("-x") - .arg(output_path.to_str().unwrap()) - .output() - .map_err(|e| e.to_string())?; - - println!("capture_select 运行耗时: {:?}", start.elapsed()); - Ok(filename) -} - -#[tauri::command] -pub async fn capture_window( - app_handle: tauri::AppHandle, - path: String, -) -> Result { - let start = Instant::now(); - - let images_dir = get_images_dir(app_handle, path)?; - - let filename = format!("screenshot_{}.png", Local::now().format("%Y%m%d_%H%M%S")); - let output_path = images_dir.join(&filename); - - Command::new("osascript") - .args([ - "-e", - "tell application \"System Events\" to key code 48 using {command down}", - ]) // Cmd+Tab - .output() - .map_err(|e| e.to_string())?; - - thread::sleep(Duration::from_secs(1)); - - let output = Command::new("screencapture") - .args([ - "-iw", // 交互式窗口选择 - "-t", - "png", // 明确指定 PNG 格式 - "-C", // 捕获鼠标光标 - "-o", // 不包含窗口阴影 - "-T", - "0", // 没有延迟 - output_path.to_str().unwrap(), - ]) - .output() - .map_err(|e| e.to_string())?; - - if !output.status.success() { - println!("screencapture -wx 失败: {:?}", output.status); - } - - println!("capture_window 运行耗时: {:?}", start.elapsed()); - - Ok(filename) -} - -pub fn get_images_dir( - app_handle: tauri::AppHandle, - path: String, -) -> Result { - let store = app_handle - .get_store("settings.json") - .ok_or_else(|| "Could not get settings store".to_string())?; - - let screenshot_path = store - .get("screenshot_path") - .ok_or_else(|| "Screenshot path not found in settings".to_string())?; - println!("screenshot_path: {:?}", screenshot_path); - - // get value from Option - let screenshot_path = screenshot_path - .as_object() - .and_then(|obj| obj.get("value")) - .and_then(|value| value.as_str()) - .unwrap(); - - // 获取 AppLocalData 路径 - // 如果 screenshot_path 为空,则使用 app_local_data - let app_local_data = if screenshot_path.is_empty() { - app_handle.path().app_local_data_dir().unwrap() - } else { - PathBuf::from(screenshot_path) - }; - println!("app_local_data: {:?}", app_local_data); - - // 创建 images 文件夹 - // path 如果为空,则使用 app_local_data - let images_dir = if path.is_empty() { - app_local_data - } else { - app_local_data.join(path) - }; - - println!("images_dir: {:?}", images_dir); - std::fs::create_dir_all(&images_dir).map_err(|e| e.to_string())?; - - // let filename = format!("screenshot_{}.png", Local::now().format("%Y%m%d_%H%M%S")); - // let output_path = images_dir.join(&filename); - - Ok(images_dir) -} diff --git a/src-tauri/src/window.rs b/src-tauri/src/window.rs new file mode 100644 index 0000000..6d1f7a4 --- /dev/null +++ b/src-tauri/src/window.rs @@ -0,0 +1,147 @@ +use tauri::{window::Color, TitleBarStyle, WebviewUrl, WebviewWindowBuilder}; +use tauri::{AppHandle, Manager, Monitor, PhysicalPosition, WebviewWindow}; + +use crate::constants::{MAIN_WINDOW, PREVIEW_WINDOW}; +use crate::platform; + +pub fn create_window(app: &mut tauri::App) -> Result<(), tauri::Error> { + let win_builder = WebviewWindowBuilder::new(app, "main", WebviewUrl::default()) + .title("ddu") + .title_bar_style(TitleBarStyle::Transparent) + .background_color(Color(10, 100, 100, 1)) + .inner_size(800.0, 600.0); + + let window = win_builder.build().unwrap(); + + // set background color only when building for macOS + #[cfg(target_os = "macos")] + { + use cocoa::appkit::{NSColor, NSWindow}; + use cocoa::base::{id, nil}; + + let ns_window = window.ns_window().unwrap() as id; + unsafe { + let bg_color = NSColor::colorWithRed_green_blue_alpha_( + nil, + 50.0 / 255.0, + 158.0 / 255.0, + 163.5 / 255.0, + 0.5, + ); + ns_window.setBackgroundColor_(bg_color); + } + } + + Ok(()) +} + +pub fn get_preview_window(app: &AppHandle) -> WebviewWindow { + if let Some(window) = app.get_webview_window(PREVIEW_WINDOW) { + window + } else { + let window = + WebviewWindowBuilder::new(app, PREVIEW_WINDOW, WebviewUrl::App("/preview".into())) + .title("Spyglass") + .decorations(false) + .transparent(true) + .visible(true) + .shadow(false) + // .disable_file_drop_handler() + .resizable(false) + .inner_size(640.0, 108.0); + + let window = window.build().expect("Unable to build startup window"); + #[cfg(target_os = "macos")] + { + use cocoa::appkit::NSWindow; + use cocoa::base::id; + + let ns_window = window.ns_window().unwrap() as id; + unsafe { + // macOS: Handle multiple spaces correctly + ns_window.setCollectionBehavior_(cocoa::appkit::NSWindowCollectionBehavior::NSWindowCollectionBehaviorMoveToActiveSpace); + } + } + + window + } +} + +fn find_monitor(window: &WebviewWindow) -> Option { + if let Ok(Some(mon)) = window.primary_monitor() { + Some(mon) + } else if let Ok(Some(mon)) = window.current_monitor() { + Some(mon) + } else if let Ok(mut monitors) = window.available_monitors() { + if monitors.is_empty() { + None + } else { + monitors.pop() + } + } else { + None + } +} + +pub fn bottom_right_preview(window: &WebviewWindow) { + let window_size = match window.inner_size() { + Ok(size) => size, + // Nothing to do if the window is not created yet. + Err(_) => return, + }; + + if let Some(monitor) = find_monitor(window) { + let screen_position = monitor.position(); + let screen_size = monitor.size(); + + let y = (120f64 * monitor.scale_factor()) as i32; + let new_position = PhysicalPosition { + x: screen_position.x + + ((screen_size.width as i32 / 2) - (window_size.width as i32 / 2)), + y, + }; + + let _ = window.set_position(tauri::Position::Physical(new_position)); + } else { + println!("Unable to detect any monitors."); + } +} + +pub fn show_preview_window(window: &WebviewWindow) { + platform::show_preview_window(window); + + // let window = window.clone(); + // tauri::async_runtime::spawn(async move { + // tokio::time::sleep(tokio::time::Duration::from_millis(256)).await; + // let _ = window.emit(ClientEvent::FocusWindow.as_ref(), true); + // }); +} + +pub fn hide_preview_window(window: &WebviewWindow) { + let handle = window.app_handle(); + // don't hide if the settings window is open + if let Some(preview_window) = handle.get_webview_window(PREVIEW_WINDOW) { + if preview_window.is_visible().unwrap_or_default() { + return; + } + } + + platform::hide_preview_window(window); +} + +pub fn show_main_window(app: &AppHandle) { + if let Some(window) = app.get_webview_window(MAIN_WINDOW) { + platform::show_main_window(&window); + } else { + return; + }; +} + +pub fn hide_main_window(app: &AppHandle) { + if let Some(main_window) = app.get_webview_window(MAIN_WINDOW) { + if main_window.is_visible().unwrap_or_default() { + platform::hide_main_window(&main_window); + return; + } + } +} diff --git a/src-tauri/src/windows.rs b/src-tauri/src/xcap_utils.rs similarity index 65% rename from src-tauri/src/windows.rs rename to src-tauri/src/xcap_utils.rs index c100184..4456c7c 100644 --- a/src-tauri/src/windows.rs +++ b/src-tauri/src/xcap_utils.rs @@ -1,38 +1,9 @@ use std::time::Instant; use tauri::{window::Color, TitleBarStyle, WebviewUrl, WebviewWindowBuilder}; +use tauri::{AppHandle, PhysicalPosition, WebviewWindow}; use xcap::Monitor; use xcap::Window; -pub fn create_window(app: &mut tauri::App) -> Result<(), tauri::Error> { - let win_builder = WebviewWindowBuilder::new(app, "main", WebviewUrl::default()) - .title("ddu") - .title_bar_style(TitleBarStyle::Transparent) - .background_color(Color(10, 100, 100, 1)) - .inner_size(800.0, 600.0); - - let window = win_builder.build().unwrap(); - - // set background color only when building for macOS - #[cfg(target_os = "macos")] - { - use cocoa::appkit::{NSColor, NSWindow}; - use cocoa::base::{id, nil}; - - let ns_window = window.ns_window().unwrap() as id; - unsafe { - let bg_color = NSColor::colorWithRed_green_blue_alpha_( - nil, - 50.0 / 255.0, - 158.0 / 255.0, - 163.5 / 255.0, - 0.5, - ); - ns_window.setBackgroundColor_(bg_color); - } - } - - Ok(()) -} pub fn display_windows() { let start = Instant::now(); @@ -86,3 +57,4 @@ pub fn display_monitors() { println!("运行耗时: {:?}", start.elapsed()); } + diff --git a/src/pages/preview/App.vue b/src/pages/preview/App.vue new file mode 100644 index 0000000..5ac5af1 --- /dev/null +++ b/src/pages/preview/App.vue @@ -0,0 +1,8 @@ + + + diff --git a/src/pages/preview/main.ts b/src/pages/preview/main.ts new file mode 100644 index 0000000..b7a5ac5 --- /dev/null +++ b/src/pages/preview/main.ts @@ -0,0 +1,10 @@ +import { createApp } from 'vue' +import App from './App.vue' +import '~/styles/default-theme.css' +import '~/styles/vars.css' +import '~/styles/global.css' +// macos remove scrollbar +// import '~/styles/scrollbars.css' +import 'virtual:uno.css' + +createApp(App).mount('#app') diff --git a/vite.config.ts b/vite.config.ts index 021a4ff..38259d0 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -44,6 +44,7 @@ export default defineConfig(async () => ({ input: { main: path.resolve(__dirname, 'index.html'), setting: path.resolve(__dirname, 'setting.html'), + preview: path.resolve(__dirname, 'preview.html'), }, }, }, From df4027fd28e10667fe4137c78570a82f0f4ae4ff Mon Sep 17 00:00:00 2001 From: JunaYa Date: Thu, 21 Nov 2024 00:33:51 +0800 Subject: [PATCH 2/9] chore: update preview window ui --- src-tauri/capabilities/window.json | 3 ++- src-tauri/src/cmd/common.rs | 4 +++ src-tauri/src/cmd/mod.rs | 4 +++ src-tauri/src/cmd/preview.rs | 12 +++++++++ src-tauri/src/lib.rs | 8 ++---- src-tauri/src/window.rs | 17 ++++++++++--- src/components/Screenshot.vue | 10 +++++++- src/components/SnapVaultItem.vue | 3 +-- src/pages/preview/App.vue | 40 ++++++++++++++++++++++++++++-- 9 files changed, 85 insertions(+), 16 deletions(-) create mode 100644 src-tauri/src/cmd/common.rs create mode 100644 src-tauri/src/cmd/preview.rs diff --git a/src-tauri/capabilities/window.json b/src-tauri/capabilities/window.json index 1e6ac71..78d3f60 100644 --- a/src-tauri/capabilities/window.json +++ b/src-tauri/capabilities/window.json @@ -1,13 +1,14 @@ { "identifier": "window-capability", "description": "Capability for the main window", - "windows": ["main"], + "windows": ["main", "preview"], "permissions": [ "core:window:default", "core:window:allow-close", "core:window:allow-start-dragging", "core:window:allow-minimize", "core:window:allow-toggle-maximize", + "core:window:allow-toggle-maximize", "core:window:allow-internal-toggle-maximize" ] } \ No newline at end of file diff --git a/src-tauri/src/cmd/common.rs b/src-tauri/src/cmd/common.rs new file mode 100644 index 0000000..a2d2fc5 --- /dev/null +++ b/src-tauri/src/cmd/common.rs @@ -0,0 +1,4 @@ +#[tauri::command] +pub fn greet(name: &str) -> String { + format!("Hello, {}! You've been greeted from Rust!", name) +} diff --git a/src-tauri/src/cmd/mod.rs b/src-tauri/src/cmd/mod.rs index 623817d..d9adffd 100644 --- a/src-tauri/src/cmd/mod.rs +++ b/src-tauri/src/cmd/mod.rs @@ -1,5 +1,9 @@ +mod common; +mod preview; mod screenshot; mod xcreenshot; +pub use self::common::*; +pub use self::preview::*; pub use self::screenshot::*; pub use self::xcreenshot::*; diff --git a/src-tauri/src/cmd/preview.rs b/src-tauri/src/cmd/preview.rs new file mode 100644 index 0000000..d2d209d --- /dev/null +++ b/src-tauri/src/cmd/preview.rs @@ -0,0 +1,12 @@ +use tauri::{AppHandle, Manager, Runtime}; + +use crate::{constants::PREVIEW_WINDOW, window}; + +#[tauri::command] +pub fn show_preview_window(app: AppHandle, path: String) -> Result { + if let Some(window) = app.get_webview_window(PREVIEW_WINDOW) { + window::show_preview_window(&window); + } + window::hide_main_window(&app); + Ok(path) +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index c18fb34..dd842cc 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -8,11 +8,6 @@ mod menu; mod platform; mod window; -#[tauri::command] -fn greet(name: &str) -> String { - format!("Hello, {}! You've been greeted from Rust!", name) -} - #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { tauri::Builder::default() @@ -43,12 +38,13 @@ pub fn run() { .plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_shell::init()) .invoke_handler(tauri::generate_handler![ - greet, + cmd::greet, cmd::capture_screen, cmd::capture_select, cmd::capture_window, cmd::xcap_window, cmd::xcap_monitor, + cmd::show_preview_window, ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src-tauri/src/window.rs b/src-tauri/src/window.rs index 6d1f7a4..dd69c26 100644 --- a/src-tauri/src/window.rs +++ b/src-tauri/src/window.rs @@ -46,20 +46,29 @@ pub fn get_preview_window(app: &AppHandle) -> WebviewWindow { .transparent(true) .visible(true) .shadow(false) - // .disable_file_drop_handler() .resizable(false) - .inner_size(640.0, 108.0); + .inner_size(240.0, 240.0) + .position(100.0, 100.0); let window = window.build().expect("Unable to build startup window"); #[cfg(target_os = "macos")] { - use cocoa::appkit::NSWindow; - use cocoa::base::id; + use cocoa::appkit::{NSColor, NSWindow}; + use cocoa::base::{id, nil}; let ns_window = window.ns_window().unwrap() as id; unsafe { // macOS: Handle multiple spaces correctly ns_window.setCollectionBehavior_(cocoa::appkit::NSWindowCollectionBehavior::NSWindowCollectionBehaviorMoveToActiveSpace); + + let bg_color = NSColor::colorWithRed_green_blue_alpha_( + nil, + 50.0 / 255.0, + 158.0 / 255.0, + 163.5 / 255.0, + 0.5, + ); + ns_window.setBackgroundColor_(bg_color); } } diff --git a/src/components/Screenshot.vue b/src/components/Screenshot.vue index 9f14bf2..6395222 100644 --- a/src/components/Screenshot.vue +++ b/src/components/Screenshot.vue @@ -19,6 +19,7 @@ async function capture_screen() { }) const val = await store.get<{ value: string }>('screenshot_path') screenshotPath.value = `${val?.value}/` + `images/${result}` + await showPreviewWindow() } // capture select @@ -28,6 +29,7 @@ async function capture_select() { }) const val = await store.get<{ value: string }>('screenshot_path') screenshotPath.value = `${val?.value}/` + `images/${result}` + await showPreviewWindow() } // capture window @@ -37,7 +39,7 @@ async function capture_window() { }) const val = await store.get<{ value: string }>('screenshot_path') screenshotPath.value = `${val?.value}/` + `images/${result}` - + await showPreviewWindow() } // take_capture_screen @@ -48,6 +50,7 @@ async function take_capture_screen() { }) const val = await store.get<{ value: string }>('screenshot_path') screenshotPath.value = `${val?.value}/` + `images/${result}` + await showPreviewWindow() } catch (error) { console.error('take_capture_screen error:', error) @@ -62,6 +65,7 @@ async function take_capture_monitor() { }) const val = await store.get<{ value: string }>('screenshot_path') screenshotPath.value = `${val?.value}/` + `images/${result}` + await showPreviewWindow() } catch (error) { console.error('take_capture_screen error:', error) @@ -79,6 +83,10 @@ async function create_dir() { } } +async function showPreviewWindow() { + await invoke('show_preview_window') +} + onMounted(async () => { await create_dir() }) diff --git a/src/components/SnapVaultItem.vue b/src/components/SnapVaultItem.vue index 0e9c4ff..810521c 100644 --- a/src/components/SnapVaultItem.vue +++ b/src/components/SnapVaultItem.vue @@ -21,7 +21,6 @@ const isHovered = useElementHover(snapHoverableElement) const deleteLoading = ref(false) async function handleDelete(path: string) { - console.log(path) deleteLoading.value = true const confirmation = await confirm( '是否确认删除该文件?', @@ -39,7 +38,7 @@ async function handleDelete(path: string) {
- - +
-
diff --git a/src/components/SnapVaultItem.vue b/src/components/SnapVaultItem.vue index 810521c..7e08752 100644 --- a/src/components/SnapVaultItem.vue +++ b/src/components/SnapVaultItem.vue @@ -35,10 +35,10 @@ async function handleDelete(path: string) {