Add tauri_plugin_single_instance
This commit is contained in:
46
src-tauri/Cargo.lock
generated
46
src-tauri/Cargo.lock
generated
@@ -127,6 +127,30 @@ dependencies = [
|
|||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-executor"
|
||||||
|
version = "1.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec"
|
||||||
|
dependencies = [
|
||||||
|
"async-task",
|
||||||
|
"concurrent-queue",
|
||||||
|
"fastrand",
|
||||||
|
"futures-lite",
|
||||||
|
"slab",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-fs"
|
||||||
|
version = "2.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a"
|
||||||
|
dependencies = [
|
||||||
|
"async-lock",
|
||||||
|
"blocking",
|
||||||
|
"futures-lite",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-io"
|
name = "async-io"
|
||||||
version = "2.3.4"
|
version = "2.3.4"
|
||||||
@@ -3508,6 +3532,7 @@ dependencies = [
|
|||||||
"tauri-plugin-os",
|
"tauri-plugin-os",
|
||||||
"tauri-plugin-process",
|
"tauri-plugin-process",
|
||||||
"tauri-plugin-shell",
|
"tauri-plugin-shell",
|
||||||
|
"tauri-plugin-single-instance",
|
||||||
"tauri-plugin-updater",
|
"tauri-plugin-updater",
|
||||||
"tiktoken-rs",
|
"tiktoken-rs",
|
||||||
"url",
|
"url",
|
||||||
@@ -4519,6 +4544,21 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tauri-plugin-single-instance"
|
||||||
|
version = "2.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a25ac834491d089699a2bc9266a662faf373c9f779f05a2235bc6e4d9e61769a"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"tauri",
|
||||||
|
"thiserror",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
"zbus",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-plugin-updater"
|
name = "tauri-plugin-updater"
|
||||||
version = "2.0.2"
|
version = "2.0.2"
|
||||||
@@ -5872,9 +5912,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "7b8e3d6ae3342792a6cc2340e4394334c7402f3d793b390d2c5494a4032b3030"
|
checksum = "7b8e3d6ae3342792a6cc2340e4394334c7402f3d793b390d2c5494a4032b3030"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-broadcast",
|
"async-broadcast",
|
||||||
|
"async-executor",
|
||||||
|
"async-fs",
|
||||||
|
"async-io",
|
||||||
|
"async-lock",
|
||||||
"async-process",
|
"async-process",
|
||||||
"async-recursion",
|
"async-recursion",
|
||||||
|
"async-task",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
"blocking",
|
||||||
"derivative",
|
"derivative",
|
||||||
"enumflags2",
|
"enumflags2",
|
||||||
"event-listener",
|
"event-listener",
|
||||||
|
|||||||
@@ -42,4 +42,5 @@ custom-protocol = ["tauri/custom-protocol"]
|
|||||||
# crate-type = ["staticlib", "cdylib", "rlib", "lib"]
|
# crate-type = ["staticlib", "cdylib", "rlib", "lib"]
|
||||||
|
|
||||||
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
||||||
|
tauri-plugin-single-instance = "2"
|
||||||
tauri-plugin-updater = "2"
|
tauri-plugin-updater = "2"
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ use base64::{engine::general_purpose, Engine as _};
|
|||||||
use reqwest::header::{HeaderMap, HeaderName, HeaderValue};
|
use reqwest::header::{HeaderMap, HeaderName, HeaderValue};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use tauri::path::BaseDirectory;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::{path::Path, time::Duration};
|
use std::{path::Path, time::Duration};
|
||||||
|
use tauri::path::BaseDirectory;
|
||||||
use tauri::Manager;
|
use tauri::Manager;
|
||||||
use tauri::{AppHandle, Emitter};
|
use tauri::{AppHandle, Emitter};
|
||||||
|
|
||||||
@@ -305,7 +305,7 @@ fn run_py_server(handle: tauri::AppHandle, py_path: String) {
|
|||||||
let py_exec_path = Path::new(&py_path).join("python").join("python.exe");
|
let py_exec_path = Path::new(&py_path).join("python").join("python.exe");
|
||||||
let server_path = handle
|
let server_path = handle
|
||||||
.path()
|
.path()
|
||||||
.resolve("src-python/run.py", BaseDirectory::Resource)
|
.resolve("src-python/run.py", BaseDirectory::Resource)
|
||||||
.expect("failed to resolve resource");
|
.expect("failed to resolve resource");
|
||||||
|
|
||||||
let mut py_server = Command::new(&py_exec_path);
|
let mut py_server = Command::new(&py_exec_path);
|
||||||
@@ -326,14 +326,13 @@ fn run_py_server(handle: tauri::AppHandle, py_path: String) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn streamed_fetch(
|
async fn streamed_fetch(
|
||||||
id: String,
|
id: String,
|
||||||
url: String,
|
url: String,
|
||||||
headers: String,
|
headers: String,
|
||||||
body: String,
|
body: String,
|
||||||
app: AppHandle
|
app: AppHandle,
|
||||||
) -> String {
|
) -> String {
|
||||||
//parse headers
|
//parse headers
|
||||||
let headers_json: Value = match serde_json::from_str(&headers) {
|
let headers_json: Value = match serde_json::from_str(&headers) {
|
||||||
@@ -419,50 +418,60 @@ async fn streamed_fetch(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
fn handle_file_associations(app: AppHandle, files: Vec<PathBuf>) {
|
fn handle_file_associations(app: AppHandle, files: Vec<PathBuf>) {
|
||||||
// -- Scope handling start --
|
// -- Scope handling start --
|
||||||
|
|
||||||
// You can remove this block if you only want to know about the paths, but not actually "use" them in the frontend.
|
// You can remove this block if you only want to know about the paths, but not actually "use" them in the frontend.
|
||||||
|
|
||||||
// This requires the `fs` tauri plugin and is required to make the plugin's frontend work:
|
// This requires the `fs` tauri plugin and is required to make the plugin's frontend work:
|
||||||
// use tauri_plugin_fs::FsExt;
|
// use tauri_plugin_fs::FsExt;
|
||||||
// let fs_scope = app.fs_scope();
|
// let fs_scope = app.fs_scope();
|
||||||
|
|
||||||
// This is for the `asset:` protocol to work:
|
// This is for the `asset:` protocol to work:
|
||||||
let asset_protocol_scope = app.asset_protocol_scope();
|
let asset_protocol_scope = app.asset_protocol_scope();
|
||||||
|
|
||||||
for file in &files {
|
for file in &files {
|
||||||
// This requires the `fs` plugin:
|
// This requires the `fs` plugin:
|
||||||
// let _ = fs_scope.allow_file(file);
|
// let _ = fs_scope.allow_file(file);
|
||||||
|
|
||||||
// This is for the `asset:` protocol:
|
// This is for the `asset:` protocol:
|
||||||
let _ = asset_protocol_scope.allow_file(file);
|
let _ = asset_protocol_scope.allow_file(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- Scope handling end --
|
// -- Scope handling end --
|
||||||
|
|
||||||
let files = files
|
let files = files
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|f| {
|
.map(|f| {
|
||||||
let file = f.to_string_lossy().replace("\\", "\\\\"); // escape backslash
|
let file = f.to_string_lossy().replace("\\", "\\\\"); // escape backslash
|
||||||
format!("\"{file}\"",) // wrap in quotes for JS array
|
format!("\"{file}\"",) // wrap in quotes for JS array
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(",");
|
.join(",");
|
||||||
|
|
||||||
tauri::WebviewWindowBuilder::new(&app, "main", Default::default())
|
tauri::WebviewWindowBuilder::new(&app, "main", Default::default())
|
||||||
.initialization_script(&format!("window.tauriOpenedFiles = [{files}]"))
|
.initialization_script(&format!("window.tauriOpenedFiles = [{files}]"))
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
tauri::Builder::default()
|
let mut builder = tauri::Builder::default();
|
||||||
|
|
||||||
|
#[cfg(desktop)]
|
||||||
|
{
|
||||||
|
builder = builder.plugin(tauri_plugin_single_instance::init(|app, args, cwd| {
|
||||||
|
let _ = app.get_webview_window("main")
|
||||||
|
.expect("no main window")
|
||||||
|
.set_focus();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
builder
|
||||||
.plugin(tauri_plugin_http::init())
|
.plugin(tauri_plugin_http::init())
|
||||||
.plugin(tauri_plugin_shell::init())
|
.plugin(tauri_plugin_shell::init())
|
||||||
.plugin(tauri_plugin_process::init())
|
.plugin(tauri_plugin_process::init())
|
||||||
@@ -474,29 +483,29 @@ fn main() {
|
|||||||
#[cfg(any(windows, target_os = "linux"))]
|
#[cfg(any(windows, target_os = "linux"))]
|
||||||
{
|
{
|
||||||
let mut files = Vec::new();
|
let mut files = Vec::new();
|
||||||
|
|
||||||
// NOTICE: `args` may include URL protocol (`your-app-protocol://`)
|
// NOTICE: `args` may include URL protocol (`your-app-protocol://`)
|
||||||
// or arguments (`--`) if your app supports them.
|
// or arguments (`--`) if your app supports them.
|
||||||
// files may aslo be passed as `file://path/to/file`
|
// files may aslo be passed as `file://path/to/file`
|
||||||
for maybe_file in std::env::args().skip(1) {
|
for maybe_file in std::env::args().skip(1) {
|
||||||
// skip flags like -f or --flag
|
// skip flags like -f or --flag
|
||||||
if maybe_file.starts_with("-") {
|
if maybe_file.starts_with("-") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle `file://` path urls and skip other urls
|
// handle `file://` path urls and skip other urls
|
||||||
if let Ok(url) = url::Url::parse(&maybe_file) {
|
if let Ok(url) = url::Url::parse(&maybe_file) {
|
||||||
if let Ok(path) = url.to_file_path() {
|
if let Ok(path) = url.to_file_path() {
|
||||||
files.push(path);
|
files.push(path);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
files.push(PathBuf::from(maybe_file))
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
files.push(PathBuf::from(maybe_file))
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
handle_file_associations(app.handle().clone(), files);
|
handle_file_associations(app.handle().clone(), files);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
@@ -519,18 +528,17 @@ fn main() {
|
|||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
|app, event| {
|
|app, event| {
|
||||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||||
if let tauri::RunEvent::Opened { urls } = event {
|
if let tauri::RunEvent::Opened { urls } = event {
|
||||||
let files = urls
|
let files = urls
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|url| url.to_file_path().ok())
|
.filter_map(|url| url.to_file_path().ok())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
handle_file_associations(app.clone(), files);
|
handle_file_associations(app.clone(), files);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn header_map_to_json(header_map: &HeaderMap) -> serde_json::Value {
|
fn header_map_to_json(header_map: &HeaderMap) -> serde_json::Value {
|
||||||
|
|||||||
Reference in New Issue
Block a user