feat: add the ability to close the new instance

pull/72/head
amrbashir 3 years ago
parent aaac569e0c
commit ff1035740e
No known key found for this signature in database
GPG Key ID: BBD7A47A2003FF33

@ -5,9 +5,12 @@
fn main() { fn main() {
tauri::Builder::default() tauri::Builder::default()
.plugin(tauri_plugin_single_instance::init(|argv, cwd| { .plugin(tauri_plugin_single_instance::init(
|argv, cwd, close_new_instance| {
println!("{argv:?}, {cwd}"); println!("{argv:?}, {cwd}");
})) close_new_instance();
},
))
.run(tauri::generate_context!()) .run(tauri::generate_context!())
.expect("error while running tauri application"); .expect("error while running tauri application");
} }

@ -4,8 +4,11 @@ use tauri::{plugin::TauriPlugin, Runtime};
#[path = "platform_impl/windows.rs"] #[path = "platform_impl/windows.rs"]
mod platform_impl; mod platform_impl;
pub(crate) type SingleInstanceCallback = dyn FnMut(Vec<String>, String) + Send + 'static; pub(crate) type SingleInstanceCallback =
dyn FnMut(Vec<String>, String, Box<dyn FnOnce()>) + Send + 'static;
pub fn init<R: Runtime, F: FnMut(Vec<String>, String) + Send + 'static>(f: F) -> TauriPlugin<R> { pub fn init<R: Runtime, F: FnMut(Vec<String>, String, Box<dyn FnOnce()>) + Send + 'static>(
f: F,
) -> TauriPlugin<R> {
platform_impl::init(Box::new(f)) platform_impl::init(Box::new(f))
} }

@ -1,8 +1,6 @@
#![cfg(target_os = "windows")] #![cfg(target_os = "windows")]
use std::{ use std::{cell::RefCell, ffi::CStr, rc::Rc};
ffi::{CStr},
};
use crate::SingleInstanceCallback; use crate::SingleInstanceCallback;
use tauri::{ use tauri::{
@ -61,11 +59,13 @@ pub fn init<R: Runtime>(f: Box<SingleInstanceCallback>) -> TauriPlugin<R> {
cbData: bytes.len() as _, cbData: bytes.len() as _,
lpData: bytes.as_ptr() as _, lpData: bytes.as_ptr() as _,
}; };
SendMessageW(hwnd, WM_COPYDATA, 0, &cds as *const _ as _); let ret = SendMessageW(hwnd, WM_COPYDATA, 0, &cds as *const _ as _);
if ret == CLOSE_NEW_INSTANCE {
std::process::exit(0); std::process::exit(0);
} }
} }
} }
}
app.manage(MutexHandle(hmutex)); app.manage(MutexHandle(hmutex));
@ -151,15 +151,25 @@ unsafe extern "system" fn single_instance_window_proc(
match msg { match msg {
WM_COPYDATA => { WM_COPYDATA => {
let ret = Rc::new(RefCell::new(1));
let cds_ptr = lparam as *const COPYDATASTRUCT; let cds_ptr = lparam as *const COPYDATASTRUCT;
if (*cds_ptr).dwData == WMCOPYDATA_SINGLE_INSTANCE_DATA { if (*cds_ptr).dwData == WMCOPYDATA_SINGLE_INSTANCE_DATA {
let data = CStr::from_ptr((*cds_ptr).lpData as _).to_string_lossy(); let data = CStr::from_ptr((*cds_ptr).lpData as _).to_string_lossy();
let mut s = data.split("|"); let mut s = data.split("|");
let cwd = s.next().unwrap(); let cwd = s.next().unwrap();
let args = s.into_iter().map(|s| s.to_string()).collect(); 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 => { WM_DESTROY => {
@ -172,8 +182,8 @@ unsafe extern "system" fn single_instance_window_proc(
struct MutexHandle(isize); struct MutexHandle(isize);
struct TargetWindowHandle(isize); struct TargetWindowHandle(isize);
/// Sent to the exisiting instance when a new instance is launched.
const WMCOPYDATA_SINGLE_INSTANCE_DATA: usize = 1542; const WMCOPYDATA_SINGLE_INSTANCE_DATA: usize = 1542;
const CLOSE_NEW_INSTANCE: isize = 1542;
pub fn encode_wide(string: impl AsRef<std::ffi::OsStr>) -> Vec<u16> { pub fn encode_wide(string: impl AsRef<std::ffi::OsStr>) -> Vec<u16> {
std::os::windows::prelude::OsStrExt::encode_wide(string.as_ref()) std::os::windows::prelude::OsStrExt::encode_wide(string.as_ref())

Loading…
Cancel
Save