Merge remote-tracking branch 'origin/v2' into v3

This commit is contained in:
Lucas Nogueira
2026-09-12 13:28:21 -03:00
205 changed files with 5215 additions and 2580 deletions
+12
View File
@@ -1,5 +1,17 @@
# Changelog
## [2.4.4]
- [`f8053e65`](https://github.com/tauri-apps/plugins-workspace/commit/f8053e659e4ccd85c1f52833411ff8417cbc5e69) ([#3527](https://github.com/tauri-apps/plugins-workspace/pull/3527) by [@Legend-Master](https://github.com/tauri-apps/plugins-workspace/../../Legend-Master)) Documented Cargo feature flags in each plugin's crate-level documentation.
### Dependencies
- Upgraded to `deep-link@2.4.10`
## \[2.4.3]
- [`d1573877`](https://github.com/tauri-apps/plugins-workspace/commit/d1573877226e609461761aa538cd0ca4f24d22be) ([#3466](https://github.com/tauri-apps/plugins-workspace/pull/3466) by [@bajoca05](https://github.com/tauri-apps/plugins-workspace/../../bajoca05)) Fix blocked thread on the single-instance plugin for MacOS: replace standard `UnixListener` with `tokio::net::UnixListener`, so the task can yield.
## \[2.4.2]
### Dependencies
+4 -3
View File
@@ -1,13 +1,13 @@
[package]
name = "tauri-plugin-single-instance"
version = "2.4.2"
version = "2.4.4"
description = "Ensure a single instance of your tauri app is running."
authors = { workspace = true }
license = { workspace = true }
edition = { workspace = true }
rust-version = { workspace = true }
repository = { workspace = true }
exclude = ["/examples"]
exclude = ["/banner.png", "/examples"]
[package.metadata.platforms.support]
windows = { level = "full", notes = "" }
@@ -22,8 +22,9 @@ serde_json = { workspace = true }
tauri = { workspace = true }
tracing = { workspace = true }
thiserror = { workspace = true }
tauri-plugin-deep-link = { path = "../deep-link", version = "2.4.9", optional = true }
tauri-plugin-deep-link = { path = "../deep-link", version = "2.4.10", optional = true }
semver = { version = "1", optional = true }
tokio = { version = "1", features = ["net"] }
[target."cfg(target_os = \"windows\")".dependencies.windows-sys]
version = "0.60"
@@ -27,4 +27,3 @@ tauri-build = { workspace = true }
default = ["wry"]
wry = ["dep:tauri-runtime-wry"]
cef = ["dep:tauri-runtime-cef"]
prod = ["tauri/custom-protocol"]
+5
View File
@@ -3,6 +3,11 @@
// SPDX-License-Identifier: MIT
//! Ensure a single instance of your tauri app is running.
//!
//! ## Cargo features
//!
//! - **semver**: Allows the app with SemVer incompatible versions to run alongside each other.
//! - **deep-link**: Trigger [`tauri-plugin-deep-link`](https://crates.io/crates/tauri-plugin-deep-link) event before invoking the single-instance callback.
#![doc(
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/app-icon.png",
@@ -3,8 +3,8 @@
// SPDX-License-Identifier: MIT
use std::{
io::{BufWriter, Error, ErrorKind, Read, Write},
os::unix::net::{UnixListener, UnixStream},
io::{BufWriter, Error, ErrorKind, Write},
os::unix::net::UnixStream,
path::PathBuf,
};
@@ -15,6 +15,7 @@ use tauri::{
plugin::{self, TauriPlugin},
AppHandle, Config, Manager, RunEvent, Runtime,
};
use tokio::io::AsyncReadExt;
pub fn init<R: Runtime>(cb: Box<SingleInstanceCallback<R>>) -> TauriPlugin<R> {
plugin::Builder::new("single-instance")
@@ -31,7 +32,7 @@ pub fn init<R: Runtime>(cb: Box<SingleInstanceCallback<R>>) -> TauriPlugin<R> {
ErrorKind::NotFound | ErrorKind::ConnectionRefused => {
// This process claims itself as singleton as likely none exists
socket_cleanup(&socket);
listen_for_other_instances(&socket, app.clone(), cb);
listen_for_other_instances(socket, app.clone(), cb);
}
_ => {
tracing::debug!(
@@ -92,42 +93,40 @@ fn notify_singleton(socket: &PathBuf) -> Result<(), Error> {
}
fn listen_for_other_instances<A: Runtime>(
socket: &PathBuf,
socket: PathBuf,
app: AppHandle<A>,
mut cb: Box<SingleInstanceCallback<A>>,
) {
match UnixListener::bind(socket) {
Ok(listener) => {
tauri::async_runtime::spawn(async move {
for stream in listener.incoming() {
match stream {
Ok(mut stream) => {
let mut s = String::new();
match stream.read_to_string(&mut s) {
Ok(_) => {
let (cwd, args) = s.split_once("\0\0").unwrap_or_default();
let args: Vec<String> =
args.split('\0').map(String::from).collect();
cb(app.app_handle(), args, cwd.to_string());
}
Err(e) => {
tracing::debug!("single_instance failed to be notified: {e}")
}
tauri::async_runtime::spawn(async move {
match tokio::net::UnixListener::bind(socket) {
Ok(listener) => loop {
match listener.accept().await {
Ok((mut stream, _addr)) => {
let mut s = String::new();
match stream.read_to_string(&mut s).await {
Ok(_) => {
let (cwd, args) = s.split_once("\0\0").unwrap_or_default();
let args: Vec<String> =
args.split('\0').map(String::from).collect();
cb(app.app_handle(), args, cwd.to_string());
}
Err(e) => {
tracing::debug!("single_instance failed to be notified: {e}")
}
}
Err(err) => {
tracing::debug!("single_instance failed to be notified: {}", err);
continue;
}
}
Err(err) => {
tracing::debug!("single_instance failed to be notified: {}", err);
continue;
}
}
});
},
Err(err) => {
tracing::error!(
"single_instance failed to listen to other processes - launching normally: {}",
err
);
}
}
Err(err) => {
tracing::error!(
"single_instance failed to listen to other processes - launching normally: {}",
err
);
}
}
});
}