From ff1035740eb903da28f2358ef7f9650747742fec Mon Sep 17 00:00:00 2001 From: amrbashir Date: Sun, 1 May 2022 13:52:34 +0200 Subject: [PATCH] feat: add the ability to close the new instance --- examples/vanilla/src-tauri/src/main.rs | 9 ++++++--- src/lib.rs | 7 +++++-- src/platform_impl/windows.rs | 26 ++++++++++++++++++-------- 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/examples/vanilla/src-tauri/src/main.rs b/examples/vanilla/src-tauri/src/main.rs index 3ef29d9b..8e3ea564 100644 --- a/examples/vanilla/src-tauri/src/main.rs +++ b/examples/vanilla/src-tauri/src/main.rs @@ -5,9 +5,12 @@ fn main() { tauri::Builder::default() - .plugin(tauri_plugin_single_instance::init(|argv, cwd| { - println!("{argv:?}, {cwd}"); - })) + .plugin(tauri_plugin_single_instance::init( + |argv, cwd, close_new_instance| { + println!("{argv:?}, {cwd}"); + close_new_instance(); + }, + )) .run(tauri::generate_context!()) .expect("error while running tauri application"); } diff --git a/src/lib.rs b/src/lib.rs index dd43d453..eff0740d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,8 +4,11 @@ use tauri::{plugin::TauriPlugin, Runtime}; #[path = "platform_impl/windows.rs"] mod platform_impl; -pub(crate) type SingleInstanceCallback = dyn FnMut(Vec, String) + Send + 'static; +pub(crate) type SingleInstanceCallback = + dyn FnMut(Vec, String, Box) + Send + 'static; -pub fn init, String) + Send + 'static>(f: F) -> TauriPlugin { +pub fn init, String, Box) + Send + 'static>( + f: F, +) -> TauriPlugin { platform_impl::init(Box::new(f)) } diff --git a/src/platform_impl/windows.rs b/src/platform_impl/windows.rs index 2ca11708..36410ed3 100644 --- a/src/platform_impl/windows.rs +++ b/src/platform_impl/windows.rs @@ -1,8 +1,6 @@ #![cfg(target_os = "windows")] -use std::{ - ffi::{CStr}, -}; +use std::{cell::RefCell, ffi::CStr, rc::Rc}; use crate::SingleInstanceCallback; use tauri::{ @@ -61,8 +59,10 @@ pub fn init(f: Box) -> TauriPlugin { cbData: bytes.len() as _, lpData: bytes.as_ptr() as _, }; - SendMessageW(hwnd, WM_COPYDATA, 0, &cds as *const _ as _); - std::process::exit(0); + let ret = SendMessageW(hwnd, WM_COPYDATA, 0, &cds as *const _ as _); + if ret == CLOSE_NEW_INSTANCE { + std::process::exit(0); + } } } } @@ -151,15 +151,25 @@ unsafe extern "system" fn single_instance_window_proc( match msg { WM_COPYDATA => { + let ret = Rc::new(RefCell::new(1)); + let cds_ptr = lparam as *const COPYDATASTRUCT; if (*cds_ptr).dwData == WMCOPYDATA_SINGLE_INSTANCE_DATA { let data = CStr::from_ptr((*cds_ptr).lpData as _).to_string_lossy(); let mut s = data.split("|"); let cwd = s.next().unwrap(); let args = s.into_iter().map(|s| s.to_string()).collect(); - (*callback_ptr)(args, cwd.to_string()); + let ret_c = Rc::clone(&ret); + (*callback_ptr)( + args, + cwd.to_string(), + Box::new(move || { + let mut ret = ret_c.borrow_mut(); + *ret = CLOSE_NEW_INSTANCE; + }), + ); } - 1 + ret.take() } WM_DESTROY => { @@ -172,8 +182,8 @@ unsafe extern "system" fn single_instance_window_proc( struct MutexHandle(isize); struct TargetWindowHandle(isize); -/// Sent to the exisiting instance when a new instance is launched. const WMCOPYDATA_SINGLE_INSTANCE_DATA: usize = 1542; +const CLOSE_NEW_INSTANCE: isize = 1542; pub fn encode_wide(string: impl AsRef) -> Vec { std::os::windows::prelude::OsStrExt::encode_wide(string.as_ref())