mirror of
https://github.com/0PandaDEV/Qopy.git
synced 2025-04-21 21:24:05 +02:00
restructure
This commit is contained in:
parent
96f9f475df
commit
266b6ff3e1
12 changed files with 158 additions and 103 deletions
1
src-tauri/Cargo.lock
generated
1
src-tauri/Cargo.lock
generated
|
@ -3625,6 +3625,7 @@ dependencies = [
|
||||||
"tauri-plugin-prevent-default",
|
"tauri-plugin-prevent-default",
|
||||||
"tauri-plugin-sql",
|
"tauri-plugin-sql",
|
||||||
"tauri-plugin-updater",
|
"tauri-plugin-updater",
|
||||||
|
"time",
|
||||||
"tokio",
|
"tokio",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
|
@ -10,7 +10,7 @@ rust-version = "1.70"
|
||||||
tauri-build = { version = "2.0.0-rc.6", features = [] }
|
tauri-build = { version = "2.0.0-rc.6", features = [] }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tauri = { version = "2.0.0-rc.6", features = ["tray-icon", "image-png"] }
|
tauri = { version = "2.0.0-rc.6", features = [ "macos-private-api", "tray-icon", "image-png"] }
|
||||||
tauri-plugin-sql = {version = "2.0.0-rc.0", features = ["sqlite"] }
|
tauri-plugin-sql = {version = "2.0.0-rc.0", features = ["sqlite"] }
|
||||||
tauri-plugin-autostart = "2.0.0-rc.0"
|
tauri-plugin-autostart = "2.0.0-rc.0"
|
||||||
tauri-plugin-os = "2.0.0-rc.0"
|
tauri-plugin-os = "2.0.0-rc.0"
|
||||||
|
@ -31,6 +31,7 @@ url = "2.5.2"
|
||||||
regex = "1"
|
regex = "1"
|
||||||
sha2 = "0.10.6"
|
sha2 = "0.10.6"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
|
time = "0.3"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
custom-protocol = ["tauri/custom-protocol"]
|
custom-protocol = ["tauri/custom-protocol"]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use base64::engine::general_purpose::STANDARD;
|
use base64::engine::general_purpose::STANDARD;
|
||||||
use tauri::{AppHandle, Manager, Runtime, Emitter, Listener};
|
use tauri::{AppHandle, Manager, Emitter, Listener};
|
||||||
use tauri_plugin_clipboard::Clipboard;
|
use tauri_plugin_clipboard::Clipboard;
|
||||||
use tokio::runtime::Runtime as TokioRuntime;
|
use tokio::runtime::Runtime as TokioRuntime;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
@ -16,14 +16,20 @@ use sha2::{Sha256, Digest};
|
||||||
use rdev::{simulate, Key, EventType};
|
use rdev::{simulate, Key, EventType};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use image::ImageFormat;
|
use image::ImageFormat;
|
||||||
|
use tauri::plugin::TauriPlugin;
|
||||||
|
|
||||||
lazy_static! {
|
pub fn init() -> TauriPlugin<tauri::Wry> {
|
||||||
static ref APP_DATA_DIR: Mutex<Option<std::path::PathBuf>> = Mutex::new(None);
|
tauri::plugin::Builder::new("clipboard")
|
||||||
}
|
.invoke_handler(tauri::generate_handler![
|
||||||
|
read_image,
|
||||||
pub fn set_app_data_dir(path: std::path::PathBuf) {
|
simulate_paste,
|
||||||
let mut dir = APP_DATA_DIR.lock().unwrap();
|
get_image_path
|
||||||
*dir = Some(path);
|
])
|
||||||
|
.setup(|app_handle, _api| {
|
||||||
|
setup(app_handle.clone());
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
@ -58,7 +64,15 @@ pub fn get_image_path(app_handle: tauri::AppHandle, filename: String) -> String
|
||||||
image_path.to_str().unwrap_or("").to_string()
|
image_path.to_str().unwrap_or("").to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup<R: Runtime>(app: &AppHandle<R>) {
|
#[tauri::command]
|
||||||
|
pub fn start_monitor(app_handle: tauri::AppHandle) -> Result<(), String> {
|
||||||
|
let clipboard = app_handle.state::<Clipboard>();
|
||||||
|
clipboard.start_monitor(app_handle.clone()).map_err(|e| e.to_string())?;
|
||||||
|
app_handle.emit("plugin:clipboard://clipboard-monitor/status", true).map_err(|e| e.to_string())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup<R: tauri::Runtime>(app: AppHandle<R>) {
|
||||||
let app = app.clone();
|
let app = app.clone();
|
||||||
let runtime = TokioRuntime::new().expect("Failed to create Tokio runtime");
|
let runtime = TokioRuntime::new().expect("Failed to create Tokio runtime");
|
||||||
|
|
||||||
|
@ -110,14 +124,14 @@ pub fn setup<R: Runtime>(app: &AppHandle<R>) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_pool<R: Runtime>(app_handle: &AppHandle<R>) -> Result<SqlitePool, Box<dyn std::error::Error + Send + Sync>> {
|
async fn get_pool<R: tauri::Runtime>(app_handle: &tauri::AppHandle<R>) -> Result<SqlitePool, Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let app_data_dir = app_handle.path().app_data_dir().expect("Failed to get app data directory");
|
let app_data_dir = app_handle.path().app_data_dir().expect("Failed to get app data directory");
|
||||||
let db_path = app_data_dir.join("data.db");
|
let db_path = app_data_dir.join("data.db");
|
||||||
let database_url = format!("sqlite:{}", db_path.to_str().unwrap());
|
let database_url = format!("sqlite:{}", db_path.to_str().unwrap());
|
||||||
SqlitePool::connect(&database_url).await.map_err(|e| Box::new(e) as Box<dyn std::error::Error + Send + Sync>)
|
SqlitePool::connect(&database_url).await.map_err(|e| Box::new(e) as Box<dyn std::error::Error + Send + Sync>)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn insert_content_if_not_exists<R: Runtime>(app_handle: AppHandle<R>, pool: SqlitePool, content_type: &str, content: String) {
|
async fn insert_content_if_not_exists<R: tauri::Runtime>(app_handle: tauri::AppHandle<R>, pool: SqlitePool, content_type: &str, content: String) {
|
||||||
let last_content: Option<String> = sqlx::query_scalar(
|
let last_content: Option<String> = sqlx::query_scalar(
|
||||||
"SELECT content FROM history WHERE content_type = ? ORDER BY timestamp DESC LIMIT 1",
|
"SELECT content FROM history WHERE content_type = ? ORDER BY timestamp DESC LIMIT 1",
|
||||||
)
|
)
|
||||||
|
@ -177,7 +191,7 @@ async fn insert_content_if_not_exists<R: Runtime>(app_handle: AppHandle<R>, pool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn save_image<R: Runtime>(app_handle: &AppHandle<R>, base64_image: &str) -> Result<String, Box<dyn std::error::Error>> {
|
async fn save_image<R: tauri::Runtime>(app_handle: &tauri::AppHandle<R>, base64_image: &str) -> Result<String, Box<dyn std::error::Error>> {
|
||||||
let image_data = STANDARD.decode(base64_image)?;
|
let image_data = STANDARD.decode(base64_image)?;
|
||||||
let mut hasher = Sha256::new();
|
let mut hasher = Sha256::new();
|
||||||
hasher.update(&image_data);
|
hasher.update(&image_data);
|
||||||
|
@ -212,10 +226,11 @@ async fn fetch_favicon_as_base64(url: url::Url) -> Result<Option<String>, Box<dy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
lazy_static! {
|
||||||
pub fn start_monitor(app_handle: AppHandle) -> Result<(), String> {
|
static ref APP_DATA_DIR: Mutex<Option<std::path::PathBuf>> = Mutex::new(None);
|
||||||
let clipboard = app_handle.state::<Clipboard>();
|
}
|
||||||
clipboard.start_monitor(app_handle.clone()).map_err(|e| e.to_string())?;
|
|
||||||
app_handle.emit("plugin:clipboard://clipboard-monitor/status", true).map_err(|e| e.to_string())?;
|
pub fn set_app_data_dir(path: std::path::PathBuf) {
|
||||||
Ok(())
|
let mut dir = APP_DATA_DIR.lock().unwrap();
|
||||||
|
*dir = Some(path);
|
||||||
}
|
}
|
|
@ -1,11 +1,21 @@
|
||||||
|
use tauri::plugin::TauriPlugin;
|
||||||
|
use tauri::{AppHandle, Manager, Emitter};
|
||||||
use sqlx::sqlite::SqlitePoolOptions;
|
use sqlx::sqlite::SqlitePoolOptions;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use tokio::runtime::Runtime;
|
use tokio::runtime::Runtime;
|
||||||
use tauri::Manager;
|
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
use rand::distributions::Alphanumeric;
|
use rand::distributions::Alphanumeric;
|
||||||
|
|
||||||
pub fn setup(app: &mut tauri::App) -> Result<(), Box<dyn std::error::Error>> {
|
pub fn init() -> TauriPlugin<tauri::Wry> {
|
||||||
|
tauri::plugin::Builder::new("database")
|
||||||
|
.setup(|app_handle: &AppHandle, _api| {
|
||||||
|
setup(app_handle)?;
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup(app: &AppHandle) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let rt = Runtime::new().expect("Failed to create Tokio runtime");
|
let rt = Runtime::new().expect("Failed to create Tokio runtime");
|
||||||
|
|
||||||
let app_data_dir = app.path().app_data_dir().unwrap();
|
let app_data_dir = app.path().app_data_dir().unwrap();
|
||||||
|
@ -66,5 +76,7 @@ pub fn setup(app: &mut tauri::App) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
app.manage(pool);
|
app.manage(pool);
|
||||||
app.manage(rt);
|
app.manage(rt);
|
||||||
|
|
||||||
|
app.emit("database_initialized", ()).expect("Failed to emit database_initialized event");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
|
@ -1,9 +1,18 @@
|
||||||
use rdev::{listen, EventType, Key};
|
use tauri::plugin::TauriPlugin;
|
||||||
use tauri::Manager;
|
use tauri::Manager;
|
||||||
|
use rdev::{listen, EventType, Key};
|
||||||
|
use crate::utils::commands;
|
||||||
|
|
||||||
use crate::center_window_on_current_monitor;
|
pub fn init() -> TauriPlugin<tauri::Wry> {
|
||||||
|
tauri::plugin::Builder::new("hotkeys")
|
||||||
|
.setup(|app, _| {
|
||||||
|
setup(app.app_handle().clone());
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn setup(app_handle: tauri::AppHandle) {
|
fn setup(app_handle: tauri::AppHandle) {
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
let mut meta_pressed = false;
|
let mut meta_pressed = false;
|
||||||
listen(move |event| {
|
listen(move |event| {
|
||||||
|
@ -20,7 +29,7 @@ pub fn setup(app_handle: tauri::AppHandle) {
|
||||||
let window = app_handle.get_webview_window("main").unwrap();
|
let window = app_handle.get_webview_window("main").unwrap();
|
||||||
window.show().unwrap();
|
window.show().unwrap();
|
||||||
window.set_focus().unwrap();
|
window.set_focus().unwrap();
|
||||||
center_window_on_current_monitor(&window);
|
commands::center_window_on_current_monitor(&window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
5
src-tauri/src/api/mod.rs
Normal file
5
src-tauri/src/api/mod.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
pub mod updater;
|
||||||
|
pub mod clipboard;
|
||||||
|
pub mod database;
|
||||||
|
pub mod tray;
|
||||||
|
pub mod hotkeys;
|
|
@ -1,15 +1,24 @@
|
||||||
use tauri::{
|
use tauri::AppHandle;
|
||||||
Manager,
|
use tauri::plugin::TauriPlugin;
|
||||||
menu::{MenuBuilder, MenuItemBuilder},
|
use tauri::Manager;
|
||||||
tray::{MouseButton, TrayIconBuilder, TrayIconEvent},
|
use tauri::menu::{MenuBuilder, MenuItemBuilder};
|
||||||
};
|
use tauri::tray::{MouseButton, TrayIconBuilder, TrayIconEvent};
|
||||||
|
|
||||||
pub fn setup(app: &mut tauri::App) -> Result<(), Box<dyn std::error::Error>> {
|
pub fn init() -> TauriPlugin<tauri::Wry> {
|
||||||
|
tauri::plugin::Builder::new("tray")
|
||||||
|
.setup(|app, _api| {
|
||||||
|
setup(app)?;
|
||||||
|
Ok(())
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup(app: &AppHandle) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let window = app.get_webview_window("main").unwrap();
|
let window = app.get_webview_window("main").unwrap();
|
||||||
let window_clone_for_tray = window.clone();
|
let window_clone_for_tray = window.clone();
|
||||||
let window_clone_for_click = window.clone();
|
let window_clone_for_click = window.clone();
|
||||||
|
|
||||||
let icon_bytes = include_bytes!("../icons/Square71x71Logo.png");
|
let icon_bytes = include_bytes!("../../icons/Square71x71Logo.png");
|
||||||
let icon = tauri::image::Image::from_bytes(icon_bytes).unwrap();
|
let icon = tauri::image::Image::from_bytes(icon_bytes).unwrap();
|
||||||
|
|
||||||
let _tray = TrayIconBuilder::new()
|
let _tray = TrayIconBuilder::new()
|
|
@ -1,8 +1,16 @@
|
||||||
use tauri::{AppHandle, async_runtime};
|
use tauri::plugin::TauriPlugin;
|
||||||
|
use tauri::AppHandle;
|
||||||
use tauri_plugin_dialog::{DialogExt, MessageDialogKind};
|
use tauri_plugin_dialog::{DialogExt, MessageDialogKind};
|
||||||
use tauri_plugin_updater::UpdaterExt;
|
use tauri_plugin_updater::UpdaterExt;
|
||||||
|
use tokio;
|
||||||
|
|
||||||
|
pub fn init() -> TauriPlugin<tauri::Wry> {
|
||||||
|
tauri::plugin::Builder::new("updater")
|
||||||
|
.invoke_handler(tauri::generate_handler![check_for_updates])
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
pub async fn check_for_updates(app: AppHandle) {
|
pub async fn check_for_updates(app: AppHandle) {
|
||||||
println!("Checking for updates...");
|
println!("Checking for updates...");
|
||||||
|
|
||||||
|
@ -28,7 +36,7 @@ pub async fn check_for_updates(app: AppHandle) {
|
||||||
if !response {
|
if !response {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
async_runtime::spawn(async move {
|
tokio::spawn(async move {
|
||||||
if let Err(e) = update.download_and_install(|_, _| {}, || {}).await {
|
if let Err(e) = update.download_and_install(|_, _| {}, || {}).await {
|
||||||
println!("Error installing new update: {:?}", e);
|
println!("Error installing new update: {:?}", e);
|
||||||
app.dialog().message(
|
app.dialog().message(
|
|
@ -3,46 +3,13 @@
|
||||||
windows_subsystem = "windows"
|
windows_subsystem = "windows"
|
||||||
)]
|
)]
|
||||||
|
|
||||||
mod clipboard;
|
mod api;
|
||||||
mod database;
|
mod utils;
|
||||||
mod hotkeys;
|
|
||||||
mod tray;
|
|
||||||
mod updater;
|
|
||||||
|
|
||||||
use tauri::Manager;
|
use tauri::{Manager, Listener};
|
||||||
use tauri::PhysicalPosition;
|
|
||||||
use tauri_plugin_autostart::MacosLauncher;
|
use tauri_plugin_autostart::MacosLauncher;
|
||||||
use tauri_plugin_prevent_default::Flags;
|
use tauri_plugin_prevent_default::Flags;
|
||||||
|
|
||||||
pub fn center_window_on_current_monitor(window: &tauri::WebviewWindow) {
|
|
||||||
if let Some(monitor) = window.available_monitors().unwrap().iter().find(|m| {
|
|
||||||
let primary_monitor = window
|
|
||||||
.primary_monitor()
|
|
||||||
.unwrap()
|
|
||||||
.expect("Failed to get primary monitor");
|
|
||||||
let mouse_position = primary_monitor.position();
|
|
||||||
let monitor_position = m.position();
|
|
||||||
let monitor_size = m.size();
|
|
||||||
mouse_position.x >= monitor_position.x
|
|
||||||
&& mouse_position.x < monitor_position.x + monitor_size.width as i32
|
|
||||||
&& mouse_position.y >= monitor_position.y
|
|
||||||
&& mouse_position.y < monitor_position.y + monitor_size.height as i32
|
|
||||||
}) {
|
|
||||||
let monitor_size = monitor.size();
|
|
||||||
let window_size = window.outer_size().unwrap();
|
|
||||||
|
|
||||||
let x = (monitor_size.width as i32 - window_size.width as i32) / 2;
|
|
||||||
let y = (monitor_size.height as i32 - window_size.height as i32) / 2;
|
|
||||||
|
|
||||||
window
|
|
||||||
.set_position(PhysicalPosition::new(
|
|
||||||
monitor.position().x + x,
|
|
||||||
monitor.position().y + y,
|
|
||||||
))
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
.plugin(tauri_plugin_clipboard::init())
|
.plugin(tauri_plugin_clipboard::init())
|
||||||
|
@ -54,6 +21,11 @@ fn main() {
|
||||||
MacosLauncher::LaunchAgent,
|
MacosLauncher::LaunchAgent,
|
||||||
Some(vec![]),
|
Some(vec![]),
|
||||||
))
|
))
|
||||||
|
.plugin(api::updater::init())
|
||||||
|
.plugin(api::database::init())
|
||||||
|
.plugin(api::tray::init())
|
||||||
|
.plugin(api::hotkeys::init())
|
||||||
|
.plugin(api::clipboard::init())
|
||||||
.plugin(
|
.plugin(
|
||||||
tauri_plugin_prevent_default::Builder::new()
|
tauri_plugin_prevent_default::Builder::new()
|
||||||
.with_flags(Flags::all().difference(Flags::CONTEXT_MENU))
|
.with_flags(Flags::all().difference(Flags::CONTEXT_MENU))
|
||||||
|
@ -62,49 +34,41 @@ fn main() {
|
||||||
.setup(|app| {
|
.setup(|app| {
|
||||||
let app_handle = app.handle().clone();
|
let app_handle = app.handle().clone();
|
||||||
|
|
||||||
hotkeys::setup(app_handle.clone());
|
|
||||||
tray::setup(app)?;
|
|
||||||
database::setup(app)?;
|
|
||||||
clipboard::setup(app.handle());
|
|
||||||
let _ = clipboard::start_monitor(app_handle.clone());
|
|
||||||
|
|
||||||
if let Some(window) = app.get_webview_window("main") {
|
|
||||||
center_window_on_current_monitor(&window);
|
|
||||||
window.hide().unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
// #[cfg(dev)]
|
|
||||||
// {
|
|
||||||
// let window = app.get_webview_window("main").unwrap();
|
|
||||||
// window.open_devtools();
|
|
||||||
// window.close_devtools();
|
|
||||||
// }
|
|
||||||
|
|
||||||
let app_data_dir = app
|
let app_data_dir = app
|
||||||
.path()
|
.path()
|
||||||
.app_data_dir()
|
.app_data_dir()
|
||||||
.expect("Failed to get app data directory");
|
.expect("Failed to get app data directory");
|
||||||
clipboard::set_app_data_dir(app_data_dir);
|
api::clipboard::set_app_data_dir(app_data_dir);
|
||||||
|
|
||||||
|
if let Some(window) = app.get_webview_window("main") {
|
||||||
|
utils::commands::center_window_on_current_monitor(&window);
|
||||||
|
window.hide().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let update_handle = app_handle.clone();
|
||||||
tauri::async_runtime::spawn(async move {
|
tauri::async_runtime::spawn(async move {
|
||||||
updater::check_for_updates(app_handle).await;
|
api::updater::check_for_updates(update_handle).await;
|
||||||
|
});
|
||||||
|
|
||||||
|
let monitor_handle = app_handle.clone();
|
||||||
|
app_handle.listen("database_initialized", move |_| {
|
||||||
|
let _ = api::clipboard::start_monitor(monitor_handle.clone());
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.on_window_event(|app, event| match event {
|
.on_window_event(|app, event| {
|
||||||
#[cfg(not(dev))]
|
#[cfg(not(dev))]
|
||||||
tauri::WindowEvent::Focused(false) => {
|
if let WindowEvent::Focused(false) = event {
|
||||||
if let Some(window) = app.get_webview_window("main") {
|
if let Some(window) = app.get_webview_window("main") {
|
||||||
window.hide().unwrap();
|
let _ = window.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
})
|
})
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
clipboard::simulate_paste,
|
api::clipboard::simulate_paste,
|
||||||
clipboard::get_image_path,
|
api::clipboard::get_image_path,
|
||||||
clipboard::read_image
|
api::clipboard::read_image
|
||||||
])
|
])
|
||||||
.run(tauri::generate_context!())
|
.run(tauri::generate_context!())
|
||||||
.expect("error while running tauri application");
|
.expect("error while running tauri application");
|
||||||
|
|
30
src-tauri/src/utils/commands.rs
Normal file
30
src-tauri/src/utils/commands.rs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
use tauri::PhysicalPosition;
|
||||||
|
|
||||||
|
pub fn center_window_on_current_monitor(window: &tauri::WebviewWindow) {
|
||||||
|
if let Some(monitor) = window.available_monitors().unwrap().iter().find(|m| {
|
||||||
|
let primary_monitor = window
|
||||||
|
.primary_monitor()
|
||||||
|
.unwrap()
|
||||||
|
.expect("Failed to get primary monitor");
|
||||||
|
let mouse_position = primary_monitor.position();
|
||||||
|
let monitor_position = m.position();
|
||||||
|
let monitor_size = m.size();
|
||||||
|
mouse_position.x >= monitor_position.x
|
||||||
|
&& mouse_position.x < monitor_position.x + monitor_size.width as i32
|
||||||
|
&& mouse_position.y >= monitor_position.y
|
||||||
|
&& mouse_position.y < monitor_position.y + monitor_size.height as i32
|
||||||
|
}) {
|
||||||
|
let monitor_size = monitor.size();
|
||||||
|
let window_size = window.outer_size().unwrap();
|
||||||
|
|
||||||
|
let x = (monitor_size.width as i32 - window_size.width as i32) / 2;
|
||||||
|
let y = (monitor_size.height as i32 - window_size.height as i32) / 2;
|
||||||
|
|
||||||
|
window
|
||||||
|
.set_position(PhysicalPosition::new(
|
||||||
|
monitor.position().x + x,
|
||||||
|
monitor.position().y + y,
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
1
src-tauri/src/utils/mod.rs
Normal file
1
src-tauri/src/utils/mod.rs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pub mod commands;
|
|
@ -31,7 +31,8 @@
|
||||||
"security": {
|
"security": {
|
||||||
"csp": null
|
"csp": null
|
||||||
},
|
},
|
||||||
"withGlobalTauri": true
|
"withGlobalTauri": true,
|
||||||
|
"macOSPrivateApi": true
|
||||||
},
|
},
|
||||||
"bundle": {
|
"bundle": {
|
||||||
"createUpdaterArtifacts": true,
|
"createUpdaterArtifacts": true,
|
||||||
|
@ -49,8 +50,7 @@
|
||||||
"updater": {
|
"updater": {
|
||||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDExNDIzNjA1QjE0NjU1OTkKUldTWlZVYXhCVFpDRWNvNmt0UE5lQmZkblEyZGZiZ2tHelJvT2YvNVpLU1RIM1RKZFQrb2tzWWwK",
|
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDExNDIzNjA1QjE0NjU1OTkKUldTWlZVYXhCVFpDRWNvNmt0UE5lQmZkblEyZGZiZ2tHelJvT2YvNVpLU1RIM1RKZFQrb2tzWWwK",
|
||||||
"endpoints": [
|
"endpoints": [
|
||||||
"https://qopy-updater-server.pandadev.workers.dev/",
|
"https://qopy.pandadev.net/"
|
||||||
"https://qopy.pandadev.net/updater"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue