Fix macOS Theseus build issue, cleanup platform specific code (#3604)

* chore(theseus): significantly cleanup MacOS-specific code

* fix(labrinth): only use jemalloc allocator for Linux targets

The upstream crate asserts that its tests only pass for Linux targets,
and there's little point in supporting other OS for now since practical
Labrinth deployments run under a Linux environment anyway. This change
made it easier for me to cross-compile Labrinth.

* chore(theseus): tweak traffic lights pos according to c39bb78e38

As far as I understand it, that PR introduced the seemingly ad-hoc
additions of 6 and 12 units to the traffic light position calculations,
not directly modifying the `const` values introduced by
d6a72fbfc4.

* fix: re-enable app window shadows on Linux

* chore: log `window.set_shadow` errors

* chore: trigger CI
This commit is contained in:
Alejandro González 2025-05-05 21:38:10 +02:00 committed by GitHub
parent f71830e0fa
commit 8dd32bbe98
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 146 additions and 691 deletions

161
Cargo.lock generated
View File

@ -513,7 +513,7 @@ dependencies = [
"futures-channel", "futures-channel",
"futures-util", "futures-util",
"rand 0.8.5", "rand 0.8.5",
"raw-window-handle 0.6.2", "raw-window-handle",
"serde", "serde",
"serde_repr", "serde_repr",
"tokio", "tokio",
@ -1043,12 +1043,6 @@ dependencies = [
"digest 0.10.7", "digest 0.10.7",
] ]
[[package]]
name = "block"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
[[package]] [[package]]
name = "block-buffer" name = "block-buffer"
version = "0.9.0" version = "0.9.0"
@ -1523,66 +1517,6 @@ dependencies = [
"cc", "cc",
] ]
[[package]]
name = "cocoa"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c"
dependencies = [
"bitflags 1.3.2",
"block",
"cocoa-foundation 0.1.2",
"core-foundation 0.9.4",
"core-graphics 0.23.2",
"foreign-types 0.5.0",
"libc",
"objc",
]
[[package]]
name = "cocoa"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f79398230a6e2c08f5c9760610eb6924b52aa9e7950a619602baba59dcbbdbb2"
dependencies = [
"bitflags 2.9.0",
"block",
"cocoa-foundation 0.2.0",
"core-foundation 0.10.0",
"core-graphics 0.24.0",
"foreign-types 0.5.0",
"libc",
"objc",
]
[[package]]
name = "cocoa-foundation"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7"
dependencies = [
"bitflags 1.3.2",
"block",
"core-foundation 0.9.4",
"core-graphics-types 0.1.3",
"libc",
"objc",
]
[[package]]
name = "cocoa-foundation"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e14045fb83be07b5acf1c0884b2180461635b433455fa35d1cd6f17f1450679d"
dependencies = [
"bitflags 2.9.0",
"block",
"core-foundation 0.10.0",
"core-graphics-types 0.2.0",
"libc",
"objc",
]
[[package]] [[package]]
name = "color-thief" name = "color-thief"
version = "0.2.2" version = "0.2.2"
@ -1785,19 +1719,6 @@ version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "core-graphics"
version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081"
dependencies = [
"bitflags 1.3.2",
"core-foundation 0.9.4",
"core-graphics-types 0.1.3",
"foreign-types 0.5.0",
"libc",
]
[[package]] [[package]]
name = "core-graphics" name = "core-graphics"
version = "0.24.0" version = "0.24.0"
@ -1806,22 +1727,11 @@ checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1"
dependencies = [ dependencies = [
"bitflags 2.9.0", "bitflags 2.9.0",
"core-foundation 0.10.0", "core-foundation 0.10.0",
"core-graphics-types 0.2.0", "core-graphics-types",
"foreign-types 0.5.0", "foreign-types 0.5.0",
"libc", "libc",
] ]
[[package]]
name = "core-graphics-types"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf"
dependencies = [
"bitflags 1.3.2",
"core-foundation 0.9.4",
"libc",
]
[[package]] [[package]]
name = "core-graphics-types" name = "core-graphics-types"
version = "0.2.0" version = "0.2.0"
@ -4943,15 +4853,6 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4"
[[package]]
name = "malloc_buf"
version = "0.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "mappings" name = "mappings"
version = "0.7.0" version = "0.7.0"
@ -5231,7 +5132,7 @@ dependencies = [
"objc2-core-foundation", "objc2-core-foundation",
"objc2-core-graphics", "objc2-core-graphics",
"objc2-foundation 0.3.1", "objc2-foundation 0.3.1",
"raw-window-handle 0.6.2", "raw-window-handle",
"thiserror 2.0.12", "thiserror 2.0.12",
"versions", "versions",
"wfd", "wfd",
@ -5267,7 +5168,7 @@ dependencies = [
"log", "log",
"ndk-sys", "ndk-sys",
"num_enum", "num_enum",
"raw-window-handle 0.6.2", "raw-window-handle",
"thiserror 1.0.69", "thiserror 1.0.69",
] ]
@ -5539,15 +5440,6 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]]
name = "objc"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
dependencies = [
"malloc_buf",
]
[[package]] [[package]]
name = "objc-sys" name = "objc-sys"
version = "0.3.5" version = "0.3.5"
@ -6948,12 +6840,6 @@ dependencies = [
"rand_core 0.5.1", "rand_core 0.5.1",
] ]
[[package]]
name = "raw-window-handle"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9"
[[package]] [[package]]
name = "raw-window-handle" name = "raw-window-handle"
version = "0.6.2" version = "0.6.2"
@ -7249,7 +7135,7 @@ dependencies = [
"objc2 0.5.2", "objc2 0.5.2",
"objc2-app-kit 0.2.2", "objc2-app-kit 0.2.2",
"objc2-foundation 0.2.2", "objc2-foundation 0.2.2",
"raw-window-handle 0.6.2", "raw-window-handle",
"wasm-bindgen", "wasm-bindgen",
"wasm-bindgen-futures", "wasm-bindgen-futures",
"web-sys", "web-sys",
@ -8360,14 +8246,14 @@ checksum = "18051cdd562e792cad055119e0cdb2cfc137e44e3987532e0f9659a77931bb08"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
"cfg_aliases", "cfg_aliases",
"core-graphics 0.24.0", "core-graphics",
"foreign-types 0.5.0", "foreign-types 0.5.0",
"js-sys", "js-sys",
"log", "log",
"objc2 0.5.2", "objc2 0.5.2",
"objc2-foundation 0.2.2", "objc2-foundation 0.2.2",
"objc2-quartz-core 0.2.2", "objc2-quartz-core 0.2.2",
"raw-window-handle 0.6.2", "raw-window-handle",
"redox_syscall", "redox_syscall",
"wasm-bindgen", "wasm-bindgen",
"web-sys", "web-sys",
@ -8942,7 +8828,7 @@ checksum = "1e59c1f38e657351a2e822eadf40d6a2ad4627b9c25557bc1180ec1b3295ef82"
dependencies = [ dependencies = [
"bitflags 2.9.0", "bitflags 2.9.0",
"core-foundation 0.10.0", "core-foundation 0.10.0",
"core-graphics 0.24.0", "core-graphics",
"crossbeam-channel", "crossbeam-channel",
"dispatch", "dispatch",
"dlopen2", "dlopen2",
@ -8962,7 +8848,7 @@ dependencies = [
"objc2-foundation 0.3.1", "objc2-foundation 0.3.1",
"once_cell", "once_cell",
"parking_lot", "parking_lot",
"raw-window-handle 0.6.2", "raw-window-handle",
"scopeguard", "scopeguard",
"tao-macros", "tao-macros",
"unicode-segmentation", "unicode-segmentation",
@ -9036,7 +8922,7 @@ dependencies = [
"objc2-ui-kit", "objc2-ui-kit",
"percent-encoding", "percent-encoding",
"plist", "plist",
"raw-window-handle 0.6.2", "raw-window-handle",
"reqwest 0.12.15", "reqwest 0.12.15",
"serde", "serde",
"serde_json", "serde_json",
@ -9168,7 +9054,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcaf6e5d6062423a0f711a23c2a573ccba222b6a16a9322d8499928f27e41376" checksum = "bcaf6e5d6062423a0f711a23c2a573ccba222b6a16a9322d8499928f27e41376"
dependencies = [ dependencies = [
"log", "log",
"raw-window-handle 0.6.2", "raw-window-handle",
"rfd", "rfd",
"serde", "serde",
"serde_json", "serde_json",
@ -9317,7 +9203,7 @@ dependencies = [
"jni", "jni",
"objc2 0.6.1", "objc2 0.6.1",
"objc2-ui-kit", "objc2-ui-kit",
"raw-window-handle 0.6.2", "raw-window-handle",
"serde", "serde",
"serde_json", "serde_json",
"tauri-utils", "tauri-utils",
@ -9341,7 +9227,7 @@ dependencies = [
"objc2-foundation 0.3.1", "objc2-foundation 0.3.1",
"once_cell", "once_cell",
"percent-encoding", "percent-encoding",
"raw-window-handle 0.6.2", "raw-window-handle",
"softbuffer", "softbuffer",
"tao", "tao",
"tauri-runtime", "tauri-runtime",
@ -9501,17 +9387,13 @@ name = "theseus_gui"
version = "0.9.5" version = "0.9.5"
dependencies = [ dependencies = [
"chrono", "chrono",
"cocoa 0.26.0",
"daedalus", "daedalus",
"dashmap 6.1.0", "dashmap 6.1.0",
"either", "either",
"enumset", "enumset",
"native-dialog", "native-dialog",
"objc",
"opener", "opener",
"os_info",
"paste", "paste",
"rand 0.9.1",
"serde", "serde",
"serde_json", "serde_json",
"serde_with", "serde_with",
@ -9532,7 +9414,6 @@ dependencies = [
"url", "url",
"urlencoding", "urlencoding",
"uuid 1.16.0", "uuid 1.16.0",
"window-shadows",
] ]
[[package]] [[package]]
@ -10852,18 +10733,6 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "window-shadows"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67ff424735b1ac21293b0492b069394b0a189c8a463fb015a16dea7c2e221c08"
dependencies = [
"cocoa 0.25.0",
"objc",
"raw-window-handle 0.5.2",
"windows-sys 0.48.0",
]
[[package]] [[package]]
name = "window-vibrancy" name = "window-vibrancy"
version = "0.6.0" version = "0.6.0"
@ -10874,7 +10743,7 @@ dependencies = [
"objc2-app-kit 0.3.1", "objc2-app-kit 0.3.1",
"objc2-core-foundation", "objc2-core-foundation",
"objc2-foundation 0.3.1", "objc2-foundation 0.3.1",
"raw-window-handle 0.6.2", "raw-window-handle",
"windows-sys 0.59.0", "windows-sys 0.59.0",
"windows-version", "windows-version",
] ]
@ -11559,7 +11428,7 @@ dependencies = [
"objc2-web-kit", "objc2-web-kit",
"once_cell", "once_cell",
"percent-encoding", "percent-encoding",
"raw-window-handle 0.6.2", "raw-window-handle",
"sha2 0.10.9", "sha2 0.10.9",
"soup3", "soup3",
"tao-macros", "tao-macros",

View File

@ -17,12 +17,12 @@
"@modrinth/utils": "workspace:*", "@modrinth/utils": "workspace:*",
"@sentry/vue": "^8.27.0", "@sentry/vue": "^8.27.0",
"@geometrically/minecraft-motd-parser": "^1.1.4", "@geometrically/minecraft-motd-parser": "^1.1.4",
"@tauri-apps/api": "^2.1.1", "@tauri-apps/api": "^2.5.0",
"@tauri-apps/plugin-dialog": "^2.2.0", "@tauri-apps/plugin-dialog": "^2.2.1",
"@tauri-apps/plugin-os": "^2.2.0", "@tauri-apps/plugin-os": "^2.2.1",
"@tauri-apps/plugin-opener": "^2.2.1", "@tauri-apps/plugin-opener": "^2.2.6",
"@tauri-apps/plugin-updater": "^2.3.0", "@tauri-apps/plugin-updater": "^2.7.1",
"@tauri-apps/plugin-window-state": "^2.2.0", "@tauri-apps/plugin-window-state": "^2.2.2",
"@vintl/vintl": "^4.4.1", "@vintl/vintl": "^4.4.1",
"dayjs": "^1.11.10", "dayjs": "^1.11.10",
"floating-vue": "^5.2.2", "floating-vue": "^5.2.2",

View File

@ -35,7 +35,6 @@ either = "1.15"
url = "2.2" url = "2.2"
urlencoding = "2.1" urlencoding = "2.1"
uuid = { version = "1.1", features = ["serde", "v4"] } uuid = { version = "1.1", features = ["serde", "v4"] }
os_info = "3.7.0"
tracing = "0.1.37" tracing = "0.1.37"
tracing-error = "0.2.0" tracing-error = "0.2.0"
@ -48,14 +47,6 @@ opener = { version = "0.7.2", features = ["reveal", "dbus-vendored"] }
native-dialog = "0.9.0" native-dialog = "0.9.0"
[target.'cfg(not(target_os = "linux"))'.dependencies]
window-shadows = "0.2.1"
[target.'cfg(target_os = "macos")'.dependencies]
cocoa = "0.26.0"
objc = "0.2.7"
rand = "0.9.1"
[target.'cfg(target_os = "linux")'.dependencies] [target.'cfg(target_os = "linux")'.dependencies]
tauri-plugin-updater = { version = "2.3.0", optional = true, features = ["native-tls-vendored", "zip"], default-features = false } tauri-plugin-updater = { version = "2.3.0", optional = true, features = ["native-tls-vendored", "zip"], default-features = false }

View File

@ -9,7 +9,7 @@
"fix": "cargo fmt && cargo clippy --fix" "fix": "cargo fmt && cargo clippy --fix"
}, },
"devDependencies": { "devDependencies": {
"@tauri-apps/cli": "2.1.0" "@tauri-apps/cli": "2.5.0"
}, },
"dependencies": { "dependencies": {
"@modrinth/app-frontend": "workspace:*", "@modrinth/app-frontend": "workspace:*",

View File

@ -53,25 +53,24 @@ pub async fn progress_bars_list()
Ok(res) Ok(res)
} }
// cfg only on mac os
// disables mouseover and fixes a random crash error only fixed by recent versions of macos // disables mouseover and fixes a random crash error only fixed by recent versions of macos
#[cfg(target_os = "macos")]
#[tauri::command] #[tauri::command]
pub async fn should_disable_mouseover() -> bool { pub async fn should_disable_mouseover() -> bool {
if cfg!(target_os = "macos") {
// We try to match version to 12.2 or higher. If unrecognizable to pattern or lower, we default to the css with disabled mouseover for safety // We try to match version to 12.2 or higher. If unrecognizable to pattern or lower, we default to the css with disabled mouseover for safety
let os = os_info::get(); if let tauri_plugin_os::Version::Semantic(major, minor, _) =
if let os_info::Version::Semantic(major, minor, _) = os.version() { tauri_plugin_os::version()
if *major >= 12 && *minor >= 3 { {
if major >= 12 && minor >= 3 {
// Mac os version is 12.3 or higher, we allow mouseover // Mac os version is 12.3 or higher, we allow mouseover
return false; return false;
} }
} }
true true
} } else {
#[cfg(not(target_os = "macos"))] // Not macos, we allow mouseover
#[tauri::command]
pub async fn should_disable_mouseover() -> bool {
false false
}
} }
#[tauri::command] #[tauri::command]

View File

@ -1,2 +1 @@
pub mod deep_link; pub mod deep_link;
pub mod window_ext;

View File

@ -1,412 +0,0 @@
// Stolen from https://gist.github.com/charrondev/43150e940bd2771b1ea88256d491c7a9
use objc::{msg_send, sel, sel_impl};
use rand::{Rng, distributions::Alphanumeric};
use tauri::{
Emitter, Runtime, Window,
plugin::{Builder, TauriPlugin},
}; // 0.8
const WINDOW_CONTROL_PAD_X: f64 = 9.0;
const WINDOW_CONTROL_PAD_Y: f64 = 10.0;
struct UnsafeWindowHandle(*mut std::ffi::c_void);
unsafe impl Send for UnsafeWindowHandle {}
unsafe impl Sync for UnsafeWindowHandle {}
pub fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("traffic_light_positioner")
.on_window_ready(|window| {
#[cfg(target_os = "macos")]
setup_traffic_light_positioner(window);
})
.build()
}
#[cfg(target_os = "macos")]
fn position_traffic_lights(
ns_window_handle: UnsafeWindowHandle,
x: f64,
y: f64,
) {
use cocoa::appkit::{NSView, NSWindow, NSWindowButton};
use cocoa::foundation::NSRect;
let ns_window = ns_window_handle.0 as cocoa::base::id;
unsafe {
let close = ns_window
.standardWindowButton_(NSWindowButton::NSWindowCloseButton);
let miniaturize = ns_window
.standardWindowButton_(NSWindowButton::NSWindowMiniaturizeButton);
let zoom =
ns_window.standardWindowButton_(NSWindowButton::NSWindowZoomButton);
let title_bar_container_view = close.superview().superview();
let close_rect: NSRect = msg_send![close, frame];
let button_height = close_rect.size.height + 12.0;
let title_bar_frame_height = button_height + y;
let mut title_bar_rect = NSView::frame(title_bar_container_view);
title_bar_rect.size.height = title_bar_frame_height;
title_bar_rect.origin.y =
NSView::frame(ns_window).size.height - title_bar_frame_height;
let _: () =
msg_send![title_bar_container_view, setFrame: title_bar_rect];
let window_buttons = vec![close, miniaturize, zoom];
let space_between =
NSView::frame(miniaturize).origin.x - NSView::frame(close).origin.x;
for (i, button) in window_buttons.into_iter().enumerate() {
let mut rect: NSRect = NSView::frame(button);
rect.origin.x = x + (i as f64 * space_between) + 6.0;
button.setFrameOrigin(rect.origin);
}
}
}
#[cfg(target_os = "macos")]
#[derive(Debug)]
struct WindowState<R: Runtime> {
window: Window<R>,
}
#[cfg(target_os = "macos")]
pub fn setup_traffic_light_positioner<R: Runtime>(window: Window<R>) {
use cocoa::appkit::NSWindow;
use cocoa::base::{BOOL, id};
use cocoa::foundation::NSUInteger;
use objc::runtime::{Object, Sel};
use std::ffi::c_void;
// Do the initial positioning
position_traffic_lights(
UnsafeWindowHandle(
window.ns_window().expect("Failed to create window handle"),
),
WINDOW_CONTROL_PAD_X,
WINDOW_CONTROL_PAD_Y,
);
// Ensure they stay in place while resizing the window.
fn with_window_state<R: Runtime, F: FnOnce(&mut WindowState<R>) -> T, T>(
this: &Object,
func: F,
) {
let ptr = unsafe {
let x: *mut c_void = *this.get_ivar("app_box");
&mut *(x as *mut WindowState<R>)
};
func(ptr);
}
unsafe {
let ns_win = window
.ns_window()
.expect("NS Window should exist to mount traffic light delegate.")
as id;
let current_delegate: id = ns_win.delegate();
extern "C" fn on_window_should_close(
this: &Object,
_cmd: Sel,
sender: id,
) -> BOOL {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
msg_send![super_del, windowShouldClose: sender]
}
}
extern "C" fn on_window_will_close(
this: &Object,
_cmd: Sel,
notification: id,
) {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, windowWillClose: notification];
}
}
extern "C" fn on_window_did_resize<R: Runtime>(
this: &Object,
_cmd: Sel,
notification: id,
) {
unsafe {
with_window_state(this, |state: &mut WindowState<R>| {
let id = state.window.ns_window().expect(
"NS window should exist on state to handle resize",
) as id;
#[cfg(target_os = "macos")]
position_traffic_lights(
UnsafeWindowHandle(id as *mut std::ffi::c_void),
WINDOW_CONTROL_PAD_X,
WINDOW_CONTROL_PAD_Y,
);
});
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, windowDidResize: notification];
}
}
extern "C" fn on_window_did_move(
this: &Object,
_cmd: Sel,
notification: id,
) {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, windowDidMove: notification];
}
}
extern "C" fn on_window_did_change_backing_properties(
this: &Object,
_cmd: Sel,
notification: id,
) {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, windowDidChangeBackingProperties: notification];
}
}
extern "C" fn on_window_did_become_key(
this: &Object,
_cmd: Sel,
notification: id,
) {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
let _: () =
msg_send![super_del, windowDidBecomeKey: notification];
}
}
extern "C" fn on_window_did_resign_key(
this: &Object,
_cmd: Sel,
notification: id,
) {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
let _: () =
msg_send![super_del, windowDidResignKey: notification];
}
}
extern "C" fn on_dragging_entered(
this: &Object,
_cmd: Sel,
notification: id,
) -> BOOL {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
msg_send![super_del, draggingEntered: notification]
}
}
extern "C" fn on_prepare_for_drag_operation(
this: &Object,
_cmd: Sel,
notification: id,
) -> BOOL {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
msg_send![super_del, prepareForDragOperation: notification]
}
}
extern "C" fn on_perform_drag_operation(
this: &Object,
_cmd: Sel,
sender: id,
) -> BOOL {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
msg_send![super_del, performDragOperation: sender]
}
}
extern "C" fn on_conclude_drag_operation(
this: &Object,
_cmd: Sel,
notification: id,
) {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
let _: () =
msg_send![super_del, concludeDragOperation: notification];
}
}
extern "C" fn on_dragging_exited(
this: &Object,
_cmd: Sel,
notification: id,
) {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, draggingExited: notification];
}
}
extern "C" fn on_window_will_use_full_screen_presentation_options(
this: &Object,
_cmd: Sel,
window: id,
proposed_options: NSUInteger,
) -> NSUInteger {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
msg_send![super_del, window: window willUseFullScreenPresentationOptions: proposed_options]
}
}
extern "C" fn on_window_did_enter_full_screen<R: Runtime>(
this: &Object,
_cmd: Sel,
notification: id,
) {
unsafe {
with_window_state(this, |state: &mut WindowState<R>| {
state
.window
.emit("did-enter-fullscreen", ())
.expect("Failed to emit event");
});
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, windowDidEnterFullScreen: notification];
}
}
extern "C" fn on_window_will_enter_full_screen<R: Runtime>(
this: &Object,
_cmd: Sel,
notification: id,
) {
unsafe {
with_window_state(this, |state: &mut WindowState<R>| {
state
.window
.emit("will-enter-fullscreen", ())
.expect("Failed to emit event");
});
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, windowWillEnterFullScreen: notification];
}
}
extern "C" fn on_window_did_exit_full_screen<R: Runtime>(
this: &Object,
_cmd: Sel,
notification: id,
) {
unsafe {
with_window_state(this, |state: &mut WindowState<R>| {
state
.window
.emit("did-exit-fullscreen", ())
.expect("Failed to emit event");
let id =
state.window.ns_window().expect("Failed to emit event")
as id;
position_traffic_lights(
UnsafeWindowHandle(id as *mut std::ffi::c_void),
WINDOW_CONTROL_PAD_X,
WINDOW_CONTROL_PAD_Y,
);
});
let super_del: id = *this.get_ivar("super_delegate");
let _: () =
msg_send![super_del, windowDidExitFullScreen: notification];
}
}
extern "C" fn on_window_will_exit_full_screen<R: Runtime>(
this: &Object,
_cmd: Sel,
notification: id,
) {
unsafe {
with_window_state(this, |state: &mut WindowState<R>| {
state
.window
.emit("will-exit-fullscreen", ())
.expect("Failed to emit event");
});
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, windowWillExitFullScreen: notification];
}
}
extern "C" fn on_window_did_fail_to_enter_full_screen(
this: &Object,
_cmd: Sel,
window: id,
) {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, windowDidFailToEnterFullScreen: window];
}
}
extern "C" fn on_effective_appearance_did_change(
this: &Object,
_cmd: Sel,
notification: id,
) {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![super_del, effectiveAppearanceDidChange: notification];
}
}
extern "C" fn on_effective_appearance_did_changed_on_main_thread(
this: &Object,
_cmd: Sel,
notification: id,
) {
unsafe {
let super_del: id = *this.get_ivar("super_delegate");
let _: () = msg_send![
super_del,
effectiveAppearanceDidChangedOnMainThread: notification
];
}
}
// Are we deallocing this properly ? (I miss safe Rust :( )
let window_label = window.label().to_string();
let app_state = WindowState { window };
let app_box = Box::into_raw(Box::new(app_state)) as *mut c_void;
let random_str: String = rand::rng()
.sample_iter(&Alphanumeric)
.take(20)
.map(char::from)
.collect();
// We need to ensure we have a unique delegate name, otherwise we will panic while trying to create a duplicate
// delegate with the same name.
let delegate_name =
format!("windowDelegate_{}_{}", window_label, random_str);
ns_win.setDelegate_(delegate!(&delegate_name, {
window: id = ns_win,
app_box: *mut c_void = app_box,
toolbar: id = cocoa::base::nil,
super_delegate: id = current_delegate,
(windowShouldClose:) => on_window_should_close as extern fn(&Object, Sel, id) -> BOOL,
(windowWillClose:) => on_window_will_close as extern fn(&Object, Sel, id),
(windowDidResize:) => on_window_did_resize::<R> as extern fn(&Object, Sel, id),
(windowDidMove:) => on_window_did_move as extern fn(&Object, Sel, id),
(windowDidChangeBackingProperties:) => on_window_did_change_backing_properties as extern fn(&Object, Sel, id),
(windowDidBecomeKey:) => on_window_did_become_key as extern fn(&Object, Sel, id),
(windowDidResignKey:) => on_window_did_resign_key as extern fn(&Object, Sel, id),
(draggingEntered:) => on_dragging_entered as extern fn(&Object, Sel, id) -> BOOL,
(prepareForDragOperation:) => on_prepare_for_drag_operation as extern fn(&Object, Sel, id) -> BOOL,
(performDragOperation:) => on_perform_drag_operation as extern fn(&Object, Sel, id) -> BOOL,
(concludeDragOperation:) => on_conclude_drag_operation as extern fn(&Object, Sel, id),
(draggingExited:) => on_dragging_exited as extern fn(&Object, Sel, id),
(window:willUseFullScreenPresentationOptions:) => on_window_will_use_full_screen_presentation_options as extern fn(&Object, Sel, id, NSUInteger) -> NSUInteger,
(windowDidEnterFullScreen:) => on_window_did_enter_full_screen::<R> as extern fn(&Object, Sel, id),
(windowWillEnterFullScreen:) => on_window_will_enter_full_screen::<R> as extern fn(&Object, Sel, id),
(windowDidExitFullScreen:) => on_window_did_exit_full_screen::<R> as extern fn(&Object, Sel, id),
(windowWillExitFullScreen:) => on_window_will_exit_full_screen::<R> as extern fn(&Object, Sel, id),
(windowDidFailToEnterFullScreen:) => on_window_did_fail_to_enter_full_screen as extern fn(&Object, Sel, id),
(effectiveAppearanceDidChange:) => on_effective_appearance_did_change as extern fn(&Object, Sel, id),
(effectiveAppearanceDidChangedOnMainThread:) => on_effective_appearance_did_changed_on_main_thread as extern fn(&Object, Sel, id)
}))
}
}

View File

@ -14,14 +14,6 @@ mod error;
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
mod macos; mod macos;
#[cfg(target_os = "macos")]
#[macro_use]
extern crate cocoa;
#[cfg(target_os = "macos")]
#[macro_use]
extern crate objc;
// Should be called in launcher initialization // Should be called in launcher initialization
#[tracing::instrument(skip_all)] #[tracing::instrument(skip_all)]
#[tauri::command] #[tauri::command]
@ -241,9 +233,9 @@ fn main() {
}); });
#[cfg(not(target_os = "linux"))] #[cfg(not(target_os = "linux"))]
{
if let Some(window) = app.get_window("main") { if let Some(window) = app.get_window("main") {
window.set_shadow(true).unwrap(); if let Err(e) = window.set_shadow(true) {
tracing::warn!("Failed to set window shadow: {e}");
} }
} }
@ -276,11 +268,6 @@ fn main() {
restart_app, restart_app,
]); ]);
#[cfg(target_os = "macos")]
{
builder = builder.plugin(macos::window_ext::init());
}
tracing::info!("Initializing app..."); tracing::info!("Initializing app...");
let app = builder.build(tauri::generate_context!()); let app = builder.build(tauri::generate_context!());

View File

@ -1,4 +1,5 @@
{ {
"$schema": "https://schema.tauri.app/config/2",
"build": { "build": {
"beforeDevCommand": "pnpm turbo run dev --filter=@modrinth/app-frontend", "beforeDevCommand": "pnpm turbo run dev --filter=@modrinth/app-frontend",
"beforeBuildCommand": "pnpm turbo run build --filter=@modrinth/app-frontend", "beforeBuildCommand": "pnpm turbo run build --filter=@modrinth/app-frontend",
@ -76,7 +77,14 @@
], ],
"security": { "security": {
"assetProtocol": { "assetProtocol": {
"scope": ["$APPDATA/caches/icons/*", "$APPCONFIG/caches/icons/*", "$CONFIG/caches/icons/*", "$APPDATA/profiles/*/saves/*/icon.png", "$APPCONFIG/profiles/*/saves/*/icon.png", "$CONFIG/profiles/*/saves/*/icon.png"], "scope": [
"$APPDATA/caches/icons/*",
"$APPCONFIG/caches/icons/*",
"$CONFIG/caches/icons/*",
"$APPDATA/profiles/*/saves/*/icon.png",
"$APPCONFIG/profiles/*/saves/*/icon.png",
"$CONFIG/profiles/*/saves/*/icon.png"
],
"enable": true "enable": true
}, },
"capabilities": ["ads", "core", "plugins"], "capabilities": ["ads", "core", "plugins"],

View File

@ -13,7 +13,11 @@
"minWidth": 1100, "minWidth": 1100,
"visible": false, "visible": false,
"zoomHotkeysEnabled": false, "zoomHotkeysEnabled": false,
"decorations": true "decorations": true,
"trafficLightPosition": {
"x": 15.0,
"y": 22.0
}
} }
] ]
} }

View File

@ -128,7 +128,7 @@ ariadne = { path = "../../packages/ariadne" }
clap = { version = "4.5", features = ["derive"] } clap = { version = "4.5", features = ["derive"] }
iana-time-zone = "0.1.61" iana-time-zone = "0.1.61"
[target.'cfg(not(target_env = "msvc"))'.dependencies] [target.'cfg(target_os = "linux")'.dependencies]
tikv-jemallocator = { version = "0.6.0", features = ["profiling", "unprefixed_malloc_on_supported_platforms"] } tikv-jemallocator = { version = "0.6.0", features = ["profiling", "unprefixed_malloc_on_supported_platforms"] }
tikv-jemalloc-ctl = { version = "0.6.0", features = ["stats"] } tikv-jemalloc-ctl = { version = "0.6.0", features = ["stats"] }
jemalloc_pprof = { version = "0.7.0", features = ["flamegraph"] } jemalloc_pprof = { version = "0.7.0", features = ["flamegraph"] }

View File

@ -316,7 +316,7 @@ pub fn app_config(
.configure( .configure(
#[allow(unused_variables)] #[allow(unused_variables)]
|cfg| { |cfg| {
#[cfg(not(target_env = "msvc"))] #[cfg(target_os = "linux")]
routes::debug::config(cfg) routes::debug::config(cfg)
}, },
) )

View File

@ -12,7 +12,7 @@ use std::sync::Arc;
use tracing::{error, info}; use tracing::{error, info};
use tracing_actix_web::TracingLogger; use tracing_actix_web::TracingLogger;
#[cfg(not(target_env = "msvc"))] #[cfg(target_os = "linux")]
#[global_allocator] #[global_allocator]
static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
@ -149,7 +149,7 @@ async fn main() -> std::io::Result<()> {
.await .await
.expect("Failed to register redis metrics"); .expect("Failed to register redis metrics");
#[cfg(not(target_env = "msvc"))] #[cfg(target_os = "linux")]
labrinth::routes::debug::jemalloc_mmeory_stats(&prometheus.registry) labrinth::routes::debug::jemalloc_mmeory_stats(&prometheus.registry)
.expect("Failed to register jemalloc metrics"); .expect("Failed to register jemalloc metrics");

View File

@ -12,7 +12,7 @@ pub mod internal;
pub mod v2; pub mod v2;
pub mod v3; pub mod v3;
#[cfg(not(target_env = "msvc"))] #[cfg(target_os = "linux")]
pub mod debug; pub mod debug;
pub mod v2_reroute; pub mod v2_reroute;

168
pnpm-lock.yaml generated
View File

@ -36,8 +36,8 @@ importers:
version: link:../../packages/daedalus version: link:../../packages/daedalus
devDependencies: devDependencies:
'@tauri-apps/cli': '@tauri-apps/cli':
specifier: 2.1.0 specifier: 2.5.0
version: 2.1.0 version: 2.5.0
apps/app-frontend: apps/app-frontend:
dependencies: dependencies:
@ -57,23 +57,23 @@ importers:
specifier: ^8.27.0 specifier: ^8.27.0
version: 8.27.0(vue@3.5.13(typescript@5.5.4)) version: 8.27.0(vue@3.5.13(typescript@5.5.4))
'@tauri-apps/api': '@tauri-apps/api':
specifier: ^2.1.1 specifier: ^2.5.0
version: 2.1.1 version: 2.5.0
'@tauri-apps/plugin-dialog': '@tauri-apps/plugin-dialog':
specifier: ^2.2.0
version: 2.2.0
'@tauri-apps/plugin-opener':
specifier: ^2.2.1 specifier: ^2.2.1
version: 2.2.1 version: 2.2.1
'@tauri-apps/plugin-opener':
specifier: ^2.2.6
version: 2.2.6
'@tauri-apps/plugin-os': '@tauri-apps/plugin-os':
specifier: ^2.2.0 specifier: ^2.2.1
version: 2.2.0 version: 2.2.1
'@tauri-apps/plugin-updater': '@tauri-apps/plugin-updater':
specifier: ^2.3.0 specifier: ^2.7.1
version: 2.3.0 version: 2.7.1
'@tauri-apps/plugin-window-state': '@tauri-apps/plugin-window-state':
specifier: ^2.2.0 specifier: ^2.2.2
version: 2.2.0 version: 2.2.2
'@vintl/vintl': '@vintl/vintl':
specifier: ^4.4.1 specifier: ^4.4.1
version: 4.4.1(typescript@5.5.4)(vue@3.5.13(typescript@5.5.4)) version: 4.4.1(typescript@5.5.4)(vue@3.5.13(typescript@5.5.4))
@ -2346,88 +2346,94 @@ packages:
peerDependencies: peerDependencies:
vue: ^3.0.0 vue: ^3.0.0
'@tauri-apps/api@2.1.1': '@tauri-apps/api@2.5.0':
resolution: {integrity: sha512-fzUfFFKo4lknXGJq8qrCidkUcKcH2UHhfaaCNt4GzgzGaW2iS26uFOg4tS3H4P8D6ZEeUxtiD5z0nwFF0UN30A==} resolution: {integrity: sha512-Ldux4ip+HGAcPUmuLT8EIkk6yafl5vK0P0c0byzAKzxJh7vxelVtdPONjfgTm96PbN24yjZNESY8CKo8qniluA==}
'@tauri-apps/cli-darwin-arm64@2.1.0': '@tauri-apps/cli-darwin-arm64@2.5.0':
resolution: {integrity: sha512-ESc6J6CE8hl1yKH2vJ+ALF+thq4Be+DM1mvmTyUCQObvezNCNhzfS6abIUd3ou4x5RGH51ouiANeT3wekU6dCw==} resolution: {integrity: sha512-VuVAeTFq86dfpoBDNYAdtQVLbP0+2EKCHIIhkaxjeoPARR0sLpFHz2zs0PcFU76e+KAaxtEtAJAXGNUc8E1PzQ==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [darwin] os: [darwin]
'@tauri-apps/cli-darwin-x64@2.1.0': '@tauri-apps/cli-darwin-x64@2.5.0':
resolution: {integrity: sha512-TasHS442DFs8cSH2eUQzuDBXUST4ECjCd0yyP+zZzvAruiB0Bg+c8A+I/EnqCvBQ2G2yvWLYG8q/LI7c87A5UA==} resolution: {integrity: sha512-hUF01sC06cZVa8+I0/VtsHOk9BbO75rd+YdtHJ48xTdcYaQ5QIwL4yZz9OR1AKBTaUYhBam8UX9Pvd5V2/4Dpw==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [darwin] os: [darwin]
'@tauri-apps/cli-linux-arm-gnueabihf@2.1.0': '@tauri-apps/cli-linux-arm-gnueabihf@2.5.0':
resolution: {integrity: sha512-aP7ZBGNL4ny07Cbb6kKpUOSrmhcIK2KhjviTzYlh+pPhAptxnC78xQGD3zKQkTi2WliJLPmBYbOHWWQa57lQ9w==} resolution: {integrity: sha512-LQKqttsK252LlqYyX8R02MinUsfFcy3+NZiJwHFgi5Y3+ZUIAED9cSxJkyNtuY5KMnR4RlpgWyLv4P6akN1xhg==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm] cpu: [arm]
os: [linux] os: [linux]
'@tauri-apps/cli-linux-arm64-gnu@2.1.0': '@tauri-apps/cli-linux-arm64-gnu@2.5.0':
resolution: {integrity: sha512-ZTdgD5gLeMCzndMT2f358EkoYkZ5T+Qy6zPzU+l5vv5M7dHVN9ZmblNAYYXmoOuw7y+BY4X/rZvHV9pcGrcanQ==} resolution: {integrity: sha512-mTQufsPcpdHg5RW0zypazMo4L55EfeE5snTzrPqbLX4yCK2qalN7+rnP8O8GT06xhp6ElSP/Ku1M2MR297SByQ==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
'@tauri-apps/cli-linux-arm64-musl@2.1.0': '@tauri-apps/cli-linux-arm64-musl@2.5.0':
resolution: {integrity: sha512-NzwqjUCilhnhJzusz3d/0i0F1GFrwCQbkwR6yAHUxItESbsGYkZRJk0yMEWkg3PzFnyK4cWTlQJMEU52TjhEzA==} resolution: {integrity: sha512-rQO1HhRUQqyEaal5dUVOQruTRda/TD36s9kv1hTxZiFuSq3558lsTjAcUEnMAtBcBkps20sbyTJNMT0AwYIk8Q==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [linux] os: [linux]
'@tauri-apps/cli-linux-x64-gnu@2.1.0': '@tauri-apps/cli-linux-riscv64-gnu@2.5.0':
resolution: {integrity: sha512-TyiIpMEtZxNOQmuFyfJwaaYbg3movSthpBJLIdPlKxSAB2BW0VWLY3/ZfIxm/G2YGHyREkjJvimzYE0i37PnMA==} resolution: {integrity: sha512-7oS18FN46yDxyw1zX/AxhLAd7T3GrLj3Ai6s8hZKd9qFVzrAn36ESL7d3G05s8wEtsJf26qjXnVF4qleS3dYsA==}
engines: {node: '>= 10'}
cpu: [riscv64]
os: [linux]
'@tauri-apps/cli-linux-x64-gnu@2.5.0':
resolution: {integrity: sha512-SG5sFNL7VMmDBdIg3nO3EzNRT306HsiEQ0N90ILe3ZABYAVoPDO/ttpCO37ApLInTzrq/DLN+gOlC/mgZvLw1w==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
'@tauri-apps/cli-linux-x64-musl@2.1.0': '@tauri-apps/cli-linux-x64-musl@2.5.0':
resolution: {integrity: sha512-/dQd0TlaxBdJACrR72DhynWftzHDaX32eBtS5WBrNJ+nnNb+znM3gON6nJ9tSE9jgDa6n1v2BkI/oIDtypfUXw==} resolution: {integrity: sha512-QXDM8zp/6v05PNWju5ELsVwF0VH1n6b5pk2E6W/jFbbiwz80Vs1lACl9pv5kEHkrxBj+aWU/03JzGuIj2g3SkQ==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [linux] os: [linux]
'@tauri-apps/cli-win32-arm64-msvc@2.1.0': '@tauri-apps/cli-win32-arm64-msvc@2.5.0':
resolution: {integrity: sha512-NdQJO7SmdYqOcE+JPU7bwg7+odfZMWO6g8xF9SXYCMdUzvM2Gv/AQfikNXz5yS7ralRhNFuW32i5dcHlxh4pDg==} resolution: {integrity: sha512-pFSHFK6b+o9y4Un8w0gGLwVyFTZaC3P0kQ7umRt/BLDkzD5RnQ4vBM7CF8BCU5nkwmEBUCZd7Wt3TWZxe41o6Q==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [arm64] cpu: [arm64]
os: [win32] os: [win32]
'@tauri-apps/cli-win32-ia32-msvc@2.1.0': '@tauri-apps/cli-win32-ia32-msvc@2.5.0':
resolution: {integrity: sha512-f5h8gKT/cB8s1ticFRUpNmHqkmaLutT62oFDB7N//2YTXnxst7EpMIn1w+QimxTvTk2gcx6EcW6bEk/y2hZGzg==} resolution: {integrity: sha512-EArv1IaRlogdLAQyGlKmEqZqm5RfHCUMhJoedWu7GtdbOMUfSAz6FMX2boE1PtEmNO4An+g188flLeVErrxEKg==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [ia32] cpu: [ia32]
os: [win32] os: [win32]
'@tauri-apps/cli-win32-x64-msvc@2.1.0': '@tauri-apps/cli-win32-x64-msvc@2.5.0':
resolution: {integrity: sha512-P/+LrdSSb5Xbho1LRP4haBjFHdyPdjWvGgeopL96OVtrFpYnfC+RctB45z2V2XxqFk3HweDDxk266btjttfjGw==} resolution: {integrity: sha512-lj43EFYbnAta8pd9JnUq87o+xRUR0odz+4rixBtTUwUgdRdwQ2V9CzFtsMu6FQKpFQ6mujRK6P1IEwhL6ADRsQ==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
'@tauri-apps/cli@2.1.0': '@tauri-apps/cli@2.5.0':
resolution: {integrity: sha512-K2VhcKqBhAeS5pNOVdnR/xQRU6jwpgmkSL2ejHXcl0m+kaTggT0WRDQnFtPq6NljA7aE03cvwsbCAoFG7vtkJw==} resolution: {integrity: sha512-rAtHqG0Gh/IWLjN2zTf3nZqYqbo81oMbqop56rGTjrlWk9pTTAjkqOjSL9XQLIMZ3RbeVjveCqqCA0s8RnLdMg==}
engines: {node: '>= 10'} engines: {node: '>= 10'}
hasBin: true hasBin: true
'@tauri-apps/plugin-dialog@2.2.0': '@tauri-apps/plugin-dialog@2.2.1':
resolution: {integrity: sha512-6bLkYK68zyK31418AK5fNccCdVuRnNpbxquCl8IqgFByOgWFivbiIlvb79wpSXi0O+8k8RCSsIpOquebusRVSg==} resolution: {integrity: sha512-wZmCouo4PgTosh/UoejPw9DPs6RllS5Pp3fuOV2JobCu36mR5AXU2MzU9NZiVaFi/5Zfc8RN0IhcZHnksJ1o8A==}
'@tauri-apps/plugin-opener@2.2.1': '@tauri-apps/plugin-opener@2.2.6':
resolution: {integrity: sha512-zloo4xzBqeh363xNA+xYt+7+/cu/lPYuG5PRtxjWAaSyfMqFo6IINdizkDBYylUewLiplXb5+S65GLVkeXTHPg==} resolution: {integrity: sha512-bSdkuP71ZQRepPOn8BOEdBKYJQvl6+jb160QtJX/i2H9BF6ZySY/kYljh76N2Ne5fJMQRge7rlKoStYQY5Jq1w==}
'@tauri-apps/plugin-os@2.2.0': '@tauri-apps/plugin-os@2.2.1':
resolution: {integrity: sha512-HszbCdbisMlu5QhCNAN8YIWyz2v33abAWha6+uvV2CKX8P5VSct/y+kEe22JeyqrxCnWlQ3DRx7s49Byg7/0EA==} resolution: {integrity: sha512-cNYpNri2CCc6BaNeB6G/mOtLvg8dFyFQyCUdf2y0K8PIAKGEWdEcu8DECkydU2B+oj4OJihDPD2de5K6cbVl9A==}
'@tauri-apps/plugin-updater@2.3.0': '@tauri-apps/plugin-updater@2.7.1':
resolution: {integrity: sha512-qdzyZEUN69FZQ/nRx51fBub10tT6wffJl3DLVo9q922Gvw8Wk++rZhoD9eethPlZYbog/7RGgT8JkrfLh5BKAg==} resolution: {integrity: sha512-1OPqEY/z7NDVSeTEMIhD2ss/vXWdpfZ5Th2Mk0KtPR/RA6FKuOTDGZQhxoyYBk0pcZJ+nNZUbl/IujDCLBApjA==}
'@tauri-apps/plugin-window-state@2.2.0': '@tauri-apps/plugin-window-state@2.2.2':
resolution: {integrity: sha512-PFZ/vkZ6UPaRyuggEn8jWc/xwpiEw3Id8i6bin54zUR3vHY0MOK+ovvpvp6SEHKryCJbZMigYJz0OUT2eZ4YmQ==} resolution: {integrity: sha512-7pFwmMtGhhhE/WgmM7PUrj0BSSWVAQMfDdYbRalphIqqF1tWBvxtlxclx8bTutpXHLJTQoCpIeWtBEIXsoAlGw==}
'@trysound/sax@0.2.0': '@trysound/sax@0.2.0':
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
@ -9850,70 +9856,74 @@ snapshots:
dependencies: dependencies:
vue: 3.5.13(typescript@5.5.4) vue: 3.5.13(typescript@5.5.4)
'@tauri-apps/api@2.1.1': {} '@tauri-apps/api@2.5.0': {}
'@tauri-apps/cli-darwin-arm64@2.1.0': '@tauri-apps/cli-darwin-arm64@2.5.0':
optional: true optional: true
'@tauri-apps/cli-darwin-x64@2.1.0': '@tauri-apps/cli-darwin-x64@2.5.0':
optional: true optional: true
'@tauri-apps/cli-linux-arm-gnueabihf@2.1.0': '@tauri-apps/cli-linux-arm-gnueabihf@2.5.0':
optional: true optional: true
'@tauri-apps/cli-linux-arm64-gnu@2.1.0': '@tauri-apps/cli-linux-arm64-gnu@2.5.0':
optional: true optional: true
'@tauri-apps/cli-linux-arm64-musl@2.1.0': '@tauri-apps/cli-linux-arm64-musl@2.5.0':
optional: true optional: true
'@tauri-apps/cli-linux-x64-gnu@2.1.0': '@tauri-apps/cli-linux-riscv64-gnu@2.5.0':
optional: true optional: true
'@tauri-apps/cli-linux-x64-musl@2.1.0': '@tauri-apps/cli-linux-x64-gnu@2.5.0':
optional: true optional: true
'@tauri-apps/cli-win32-arm64-msvc@2.1.0': '@tauri-apps/cli-linux-x64-musl@2.5.0':
optional: true optional: true
'@tauri-apps/cli-win32-ia32-msvc@2.1.0': '@tauri-apps/cli-win32-arm64-msvc@2.5.0':
optional: true optional: true
'@tauri-apps/cli-win32-x64-msvc@2.1.0': '@tauri-apps/cli-win32-ia32-msvc@2.5.0':
optional: true optional: true
'@tauri-apps/cli@2.1.0': '@tauri-apps/cli-win32-x64-msvc@2.5.0':
optional: true
'@tauri-apps/cli@2.5.0':
optionalDependencies: optionalDependencies:
'@tauri-apps/cli-darwin-arm64': 2.1.0 '@tauri-apps/cli-darwin-arm64': 2.5.0
'@tauri-apps/cli-darwin-x64': 2.1.0 '@tauri-apps/cli-darwin-x64': 2.5.0
'@tauri-apps/cli-linux-arm-gnueabihf': 2.1.0 '@tauri-apps/cli-linux-arm-gnueabihf': 2.5.0
'@tauri-apps/cli-linux-arm64-gnu': 2.1.0 '@tauri-apps/cli-linux-arm64-gnu': 2.5.0
'@tauri-apps/cli-linux-arm64-musl': 2.1.0 '@tauri-apps/cli-linux-arm64-musl': 2.5.0
'@tauri-apps/cli-linux-x64-gnu': 2.1.0 '@tauri-apps/cli-linux-riscv64-gnu': 2.5.0
'@tauri-apps/cli-linux-x64-musl': 2.1.0 '@tauri-apps/cli-linux-x64-gnu': 2.5.0
'@tauri-apps/cli-win32-arm64-msvc': 2.1.0 '@tauri-apps/cli-linux-x64-musl': 2.5.0
'@tauri-apps/cli-win32-ia32-msvc': 2.1.0 '@tauri-apps/cli-win32-arm64-msvc': 2.5.0
'@tauri-apps/cli-win32-x64-msvc': 2.1.0 '@tauri-apps/cli-win32-ia32-msvc': 2.5.0
'@tauri-apps/cli-win32-x64-msvc': 2.5.0
'@tauri-apps/plugin-dialog@2.2.0': '@tauri-apps/plugin-dialog@2.2.1':
dependencies: dependencies:
'@tauri-apps/api': 2.1.1 '@tauri-apps/api': 2.5.0
'@tauri-apps/plugin-opener@2.2.1': '@tauri-apps/plugin-opener@2.2.6':
dependencies: dependencies:
'@tauri-apps/api': 2.1.1 '@tauri-apps/api': 2.5.0
'@tauri-apps/plugin-os@2.2.0': '@tauri-apps/plugin-os@2.2.1':
dependencies: dependencies:
'@tauri-apps/api': 2.1.1 '@tauri-apps/api': 2.5.0
'@tauri-apps/plugin-updater@2.3.0': '@tauri-apps/plugin-updater@2.7.1':
dependencies: dependencies:
'@tauri-apps/api': 2.1.1 '@tauri-apps/api': 2.5.0
'@tauri-apps/plugin-window-state@2.2.0': '@tauri-apps/plugin-window-state@2.2.2':
dependencies: dependencies:
'@tauri-apps/api': 2.1.1 '@tauri-apps/api': 2.5.0
'@trysound/sax@0.2.0': {} '@trysound/sax@0.2.0': {}