Skip to content

Commit

Permalink
feat: support tray menu screenshot action
Browse files Browse the repository at this point in the history
  • Loading branch information
JunaYa committed Nov 21, 2024
1 parent 8ea099c commit fc369a2
Show file tree
Hide file tree
Showing 15 changed files with 194 additions and 206 deletions.
150 changes: 10 additions & 140 deletions src-tauri/src/cmd/screenshot.rs
Original file line number Diff line number Diff line change
@@ -1,149 +1,19 @@
use std::{
path::PathBuf,
process::Command,
thread,
time::{Duration, Instant},
};

use chrono::Local;
use tauri::{Manager, Runtime};
use tauri_plugin_store::StoreExt;
use crate::platform;

#[tauri::command]
pub async fn capture_screen<R: Runtime>(
app_handle: tauri::AppHandle<R>,
path: String,
) -> Result<String, String> {
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)
pub async fn capture_screen(app_handle: tauri::AppHandle, path: String) -> Result<String, String> {
let filename = platform::capture_screen(&app_handle, path).await?;
Ok(filename)
}

#[tauri::command]
pub async fn capture_select<R: Runtime>(
app_handle: tauri::AppHandle<R>,
path: String,
) -> Result<String, String> {
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)
pub async fn capture_select(app_handle: tauri::AppHandle, path: String) -> Result<String, String> {
let filename = platform::capture_select(&app_handle, path).await?;
Ok(filename)
}

#[tauri::command]
pub async fn capture_window<R: Runtime>(
app_handle: tauri::AppHandle<R>,
path: String,
) -> Result<String, String> {
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<R: Runtime>(
app_handle: tauri::AppHandle<R>,
path: String,
) -> Result<PathBuf, String> {
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<JsonValue>
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)
pub async fn capture_window(app_handle: tauri::AppHandle, path: String) -> Result<String, String> {
let filename = platform::capture_window(&app_handle, path).await?;
Ok(filename)
}
3 changes: 2 additions & 1 deletion src-tauri/src/cmd/window.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use tauri::{AppHandle, Manager};
use tauri::AppHandle;

use crate::window;

Expand All @@ -10,6 +10,7 @@ pub fn show_preview_window(app: AppHandle, path: String) -> Result<String, Strin

#[tauri::command]
pub fn hide_preview_window(app: AppHandle) -> Result<(), String> {
println!("hide_preview_window");
window::hide_preview_window(&app);
Ok(())
}
Expand Down
64 changes: 6 additions & 58 deletions src-tauri/src/cmd/xcreenshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,22 @@ use std::path::PathBuf;

use chrono::Local;
use std::time::Instant;
use tauri::{Manager, Runtime};
use tauri_plugin_store::StoreExt;
use xcap::{Monitor, Window};

use crate::common::get_images_dir;

#[tauri::command]
pub async fn xcap_window<R: Runtime>(
app_handle: tauri::AppHandle<R>,
path: String,
) -> Result<String, String> {
let images_dir = get_images_dir(app_handle, path).unwrap();
pub async fn xcap_window(app_handle: tauri::AppHandle, path: String) -> Result<String, String> {
let images_dir = get_images_dir(&app_handle, path).unwrap();

let filename = window_capture(images_dir)?;

Ok(filename)
}

#[tauri::command]
pub async fn xcap_monitor<R: Runtime>(
app_handle: tauri::AppHandle<R>,
path: String,
) -> Result<String, String> {
let images_dir = get_images_dir(app_handle, path).unwrap();
pub async fn xcap_monitor(app_handle: tauri::AppHandle, path: String) -> Result<String, String> {
let images_dir = get_images_dir(&app_handle, path).unwrap();

let filename = monitor_capture(images_dir)?;

Expand Down Expand Up @@ -104,49 +98,3 @@ fn monitor_capture(path: PathBuf) -> Result<String, String> {

Ok(filename)
}

pub fn get_images_dir<R: Runtime>(
app_handle: tauri::AppHandle<R>,
path: String,
) -> Result<PathBuf, String> {
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<JsonValue>
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)
}
47 changes: 47 additions & 0 deletions src-tauri/src/common.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use std::path::PathBuf;

use tauri::Manager;
use tauri_plugin_store::StoreExt;

pub fn get_images_dir(app_handle: &tauri::AppHandle, path: String) -> Result<PathBuf, String> {
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<JsonValue>
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)
}
1 change: 1 addition & 0 deletions src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use tauri::Manager;
use tauri_plugin_store::StoreExt;

mod cmd;
mod common;
mod constants;
mod menu;
mod platform;
Expand Down
22 changes: 19 additions & 3 deletions src-tauri/src/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use tauri::{
AppHandle, Manager,
};

use crate::window;
use crate::{platform, window};

#[derive(Debug, Display, EnumString)]
#[allow(non_camel_case_types, clippy::upper_case_acronyms)]
Expand Down Expand Up @@ -162,22 +162,38 @@ fn handle_tray_menu_events(app: &AppHandle, event: MenuEvent) {
match menu_id {
MenuID::CAPTURE_SCREEN => {
println!("Capture Screen");
let _ = tauri::async_runtime::block_on(platform::capture_screen(
&app,
"images".to_string(),
));
window::hide_main_window(app);
window::show_preview_window(app);
}
MenuID::CAPTURE_SELECT => {
println!("Capture Select");
let _ = tauri::async_runtime::block_on(platform::capture_select(
&app,
"images".to_string(),
));
window::hide_main_window(app);
window::show_preview_window(app);
}
MenuID::CAPTURE_WINDOW => {
println!("Capture Window");
let _ = tauri::async_runtime::block_on(platform::capture_window(
&app,
"images".to_string(),
));
window::hide_main_window(app);
window::show_preview_window(app);
}
MenuID::SHOW_MAIN_WINDOW => {
println!("Show Home");
window::show_main_window(app);
window::show_main_window(&app);
}
MenuID::SHOW_SETTING_WINDOW => {
println!("Setting Manager");
window::show_setting_window(app);
window::show_setting_window(&app);
}
MenuID::EXIT => {
println!("Exit");
Expand Down
File renamed without changes.
3 changes: 3 additions & 0 deletions src-tauri/src/platform/linux/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
mod linux;

pub use linux::*;
5 changes: 5 additions & 0 deletions src-tauri/src/platform/mac/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
mod screenshot;
mod window;

pub use screenshot::*;
pub use window::*;
Loading

0 comments on commit fc369a2

Please sign in to comment.