diff --git a/Cargo.lock b/Cargo.lock index 4a21b25..3401a30 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1405,10 +1405,12 @@ version = "0.1.0" dependencies = [ "arboard", "base64", - "cocoa", "env_logger", "log", "muda", + "objc2 0.6.4", + "objc2-app-kit 0.3.2", + "objc2-foundation 0.3.2", "png 0.18.1", "rfd", "serde", @@ -2556,10 +2558,10 @@ dependencies = [ "block2 0.5.1", "libc", "objc2 0.5.2", - "objc2-core-data", - "objc2-core-image", + "objc2-core-data 0.2.2", + "objc2-core-image 0.2.2", "objc2-foundation 0.2.2", - "objc2-quartz-core", + "objc2-quartz-core 0.2.2", ] [[package]] @@ -2570,10 +2572,17 @@ checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" dependencies = [ "bitflags 2.13.1", "block2 0.6.2", + "libc", "objc2 0.6.4", + "objc2-cloud-kit 0.3.2", + "objc2-core-data 0.3.2", "objc2-core-foundation", "objc2-core-graphics", + "objc2-core-image 0.3.2", + "objc2-core-text", + "objc2-core-video", "objc2-foundation 0.3.2", + "objc2-quartz-core 0.3.2", ] [[package]] @@ -2589,6 +2598,17 @@ dependencies = [ "objc2-foundation 0.2.2", ] +[[package]] +name = "objc2-cloud-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" +dependencies = [ + "bitflags 2.13.1", + "objc2 0.6.4", + "objc2-foundation 0.3.2", +] + [[package]] name = "objc2-contacts" version = "0.2.2" @@ -2612,6 +2632,17 @@ dependencies = [ "objc2-foundation 0.2.2", ] +[[package]] +name = "objc2-core-data" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa" +dependencies = [ + "bitflags 2.13.1", + "objc2 0.6.4", + "objc2-foundation 0.3.2", +] + [[package]] name = "objc2-core-foundation" version = "0.3.2" @@ -2648,6 +2679,16 @@ dependencies = [ "objc2-metal", ] +[[package]] +name = "objc2-core-image" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006" +dependencies = [ + "objc2 0.6.4", + "objc2-foundation 0.3.2", +] + [[package]] name = "objc2-core-location" version = "0.2.2" @@ -2660,6 +2701,31 @@ dependencies = [ "objc2-foundation 0.2.2", ] +[[package]] +name = "objc2-core-text" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" +dependencies = [ + "bitflags 2.13.1", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-core-graphics", +] + +[[package]] +name = "objc2-core-video" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6" +dependencies = [ + "bitflags 2.13.1", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-io-surface", +] + [[package]] name = "objc2-encode" version = "4.1.0" @@ -2740,6 +2806,17 @@ dependencies = [ "objc2-metal", ] +[[package]] +name = "objc2-quartz-core" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" +dependencies = [ + "bitflags 2.13.1", + "objc2 0.6.4", + "objc2-foundation 0.3.2", +] + [[package]] name = "objc2-symbols" version = "0.2.2" @@ -2759,13 +2836,13 @@ dependencies = [ "bitflags 2.13.1", "block2 0.5.1", "objc2 0.5.2", - "objc2-cloud-kit", - "objc2-core-data", - "objc2-core-image", + "objc2-cloud-kit 0.2.2", + "objc2-core-data 0.2.2", + "objc2-core-image 0.2.2", "objc2-core-location", "objc2-foundation 0.2.2", "objc2-link-presentation", - "objc2-quartz-core", + "objc2-quartz-core 0.2.2", "objc2-symbols", "objc2-uniform-type-identifiers", "objc2-user-notifications", diff --git a/crates/gelectron-app/Cargo.toml b/crates/gelectron-app/Cargo.toml index 986e77a..34dd644 100644 --- a/crates/gelectron-app/Cargo.toml +++ b/crates/gelectron-app/Cargo.toml @@ -25,4 +25,6 @@ base64 = "0.22" url = { workspace = true } [target.'cfg(target_os = "macos")'.dependencies] -cocoa = "0.26" +objc2 = "0.6" +objc2-app-kit = "0.3" +objc2-foundation = "0.3" diff --git a/crates/gelectron-app/src/main.rs b/crates/gelectron-app/src/main.rs index 3e8b78e..d5d79f1 100644 --- a/crates/gelectron-app/src/main.rs +++ b/crates/gelectron-app/src/main.rs @@ -951,24 +951,21 @@ fn find_app_icon_file(app_path: &std::path::Path) -> Option { fn apply_dock_icon(icon: &DecodedIcon) { #[cfg(target_os = "macos")] { - use cocoa::appkit::{NSApplication, NSImage}; - use cocoa::base::{id, nil}; - use cocoa::foundation::NSData; + use objc2::AnyThread; + use objc2_app_kit::{NSApplication, NSImage}; + use objc2_foundation::{MainThreadMarker, NSData}; let img_bytes = if !icon.rgba.is_empty() { rgba_to_png(&icon.rgba, icon.width, icon.height).unwrap_or_else(|| icon.raw.clone()) } else { icon.raw.clone() }; - unsafe { - let data = NSData::dataWithBytes_length_( - nil, - img_bytes.as_ptr() as *const std::ffi::c_void, - img_bytes.len() as u64, - ); - let image: id = NSImage::initWithData_(NSImage::alloc(nil), data); - if image != nil { - let app = NSApplication::sharedApplication(nil); - let _: () = app.setApplicationIconImage_(image); + if let Some(mtm) = MainThreadMarker::new() { + let data = NSData::with_bytes(&img_bytes); + if let Some(image) = NSImage::initWithData(NSImage::alloc(), &data) { + let app = NSApplication::sharedApplication(mtm); + unsafe { + app.setApplicationIconImage(Some(&image)); + } } } } @@ -1035,15 +1032,16 @@ fn detect_and_apply_icon(app_path: &std::path::Path, st: &mut AppState) { #[cfg(target_os = "macos")] fn apply_dock_icon_from_path(path: &std::path::Path) { - use cocoa::appkit::{NSApplication, NSImage}; - use cocoa::base::{id, nil}; - use cocoa::foundation::NSString; - unsafe { - let ns_path = NSString::alloc(nil).init_str(&path.display().to_string()); - let image: id = NSImage::initWithContentsOfFile_(NSImage::alloc(nil), ns_path); - if image != nil { - let app = NSApplication::sharedApplication(nil); - let _: () = app.setApplicationIconImage_(image); + use objc2::AnyThread; + use objc2_app_kit::{NSApplication, NSImage}; + use objc2_foundation::{MainThreadMarker, NSString}; + if let Some(mtm) = MainThreadMarker::new() { + let ns_path = NSString::from_str(&path.display().to_string()); + if let Some(image) = NSImage::initWithContentsOfFile(NSImage::alloc(), &ns_path) { + let app = NSApplication::sharedApplication(mtm); + unsafe { + app.setApplicationIconImage(Some(&image)); + } } } } @@ -1291,7 +1289,6 @@ fn handle_to_rust( if let Ok(mut c) = arboard::Clipboard::new() { use base64::Engine; if let Ok(bytes) = base64::engine::general_purpose::STANDARD.decode(&data) { - use std::io::Read; let cursor = std::io::Cursor::new(&bytes[..]); let decoder = png::Decoder::new(cursor); if let Ok(mut reader) = decoder.read_info() { @@ -1589,7 +1586,6 @@ fn handle_to_rust( pair.window.set_maximized(true); } } - _ => {} } } @@ -1625,7 +1621,7 @@ mod tests { bmp[8..12].copy_from_slice(&(w as i32).to_le_bytes()); bmp[14..16].copy_from_slice(&32u16.to_le_bytes()); for y in (0..w).rev() { - for x in 0..w { + for _x in 0..w { let p = pixels[y]; bmp.extend_from_slice(&[p[2], p[1], p[0], p[3]]); } diff --git a/crates/gelectron-core/src/ipc.rs b/crates/gelectron-core/src/ipc.rs index 0af53d3..9f80f79 100644 --- a/crates/gelectron-core/src/ipc.rs +++ b/crates/gelectron-core/src/ipc.rs @@ -12,7 +12,6 @@ static IPC_LISTENERS: once_cell::sync::Lazy Result { listeners .entry(channel.clone()) .or_insert_with(Vec::new) - .push(IpcListener { id, channel }); + .push(IpcListener { id }); Ok(id as i64) } @@ -146,10 +145,7 @@ pub fn ipc_renderer_on(channel: String, _callback: JsFunction) -> Result { listeners .entry(format!("renderer:{}", channel)) .or_insert_with(Vec::new) - .push(IpcListener { - id, - channel: channel.clone(), - }); + .push(IpcListener { id }); log::debug!("ipcRenderer.on registered for channel: {}", &channel); Ok(id as i64) } diff --git a/crates/gelectron-core/src/tray.rs b/crates/gelectron-core/src/tray.rs index b37d540..58e65d4 100644 --- a/crates/gelectron-core/src/tray.rs +++ b/crates/gelectron-core/src/tray.rs @@ -62,6 +62,7 @@ pub fn tray_set_pressed_image(_tray_id: u32, _image_json: Option) -> Res } #[napi] +#[allow(non_snake_case)] pub fn tray_setContextMenu(tray_id: u32, menu_id: Option) -> Result<()> { log::info!("Tray {} context menu set to {:?}", tray_id, menu_id); Ok(()) diff --git a/crates/gelectron-core/src/web_contents.rs b/crates/gelectron-core/src/web_contents.rs index 16299ec..dce0e36 100644 --- a/crates/gelectron-core/src/web_contents.rs +++ b/crates/gelectron-core/src/web_contents.rs @@ -111,12 +111,14 @@ pub fn web_contents_get_session_id(window_id: u32) -> Result { } #[napi] +#[allow(non_snake_case)] pub fn web_contents_set_windowOpenHandler(window_id: u32) -> Result<()> { log::debug!("Window {} set window open handler", window_id); Ok(()) } #[napi] +#[allow(non_snake_case)] pub fn web_contents_set_permissionRequestHandler(window_id: u32) -> Result<()> { log::debug!("Window {} set permission request handler", window_id); Ok(()) @@ -146,6 +148,7 @@ pub fn web_contents_set_ignore_menu_shortcuts(window_id: u32, ignore: bool) -> R } #[napi] +#[allow(non_snake_case)] pub fn web_contents_setAudioMuted(window_id: u32, muted: bool) -> Result<()> { log::debug!("Window {} audio muted={}", window_id, muted); Ok(()) diff --git a/vendor/wry/src/android/mod.rs b/vendor/wry/src/android/mod.rs index e284f38..c76f7bd 100644 --- a/vendor/wry/src/android/mod.rs +++ b/vendor/wry/src/android/mod.rs @@ -335,7 +335,7 @@ impl InnerWebView { Ok(()) } - pub fn id(&self) -> crate::WebViewId { + pub fn id(&self) -> crate::WebViewId<'_> { &self.id } diff --git a/vendor/wry/src/lib.rs b/vendor/wry/src/lib.rs index eb98f3d..c28b855 100644 --- a/vendor/wry/src/lib.rs +++ b/vendor/wry/src/lib.rs @@ -1558,7 +1558,7 @@ impl WebView { } /// Returns the id of this webview. - pub fn id(&self) -> WebViewId { + pub fn id(&self) -> WebViewId<'_> { self.webview.id() } diff --git a/vendor/wry/src/webkitgtk/mod.rs b/vendor/wry/src/webkitgtk/mod.rs index 2c04bf7..f240dde 100644 --- a/vendor/wry/src/webkitgtk/mod.rs +++ b/vendor/wry/src/webkitgtk/mod.rs @@ -568,7 +568,7 @@ impl InnerWebView { is_inspector_open } - pub fn id(&self) -> crate::WebViewId { + pub fn id(&self) -> crate::WebViewId<'_> { &self.id } diff --git a/vendor/wry/src/webview2/mod.rs b/vendor/wry/src/webview2/mod.rs index 05c79b2..bcefce2 100644 --- a/vendor/wry/src/webview2/mod.rs +++ b/vendor/wry/src/webview2/mod.rs @@ -1263,7 +1263,7 @@ impl InnerWebView { /// Public APIs impl InnerWebView { - pub fn id(&self) -> crate::WebViewId { + pub fn id(&self) -> crate::WebViewId<'_> { &self.id } diff --git a/vendor/wry/src/wkwebview/download.rs b/vendor/wry/src/wkwebview/download.rs index 0f6724a..529e965 100644 --- a/vendor/wry/src/wkwebview/download.rs +++ b/vendor/wry/src/wkwebview/download.rs @@ -87,13 +87,13 @@ pub(crate) fn download_did_finish(this: &WryDownloadDelegate, download: &WKDownl pub(crate) fn download_did_fail( this: &WryDownloadDelegate, download: &WKDownload, - error: &NSError, + _error: &NSError, _resume_data: &NSData, ) { unsafe { #[cfg(debug_assertions)] { - let description = error.localizedDescription().to_string(); + let description = _error.localizedDescription().to_string(); eprintln!("Download failed with error: {}", description); } diff --git a/vendor/wry/src/wkwebview/mod.rs b/vendor/wry/src/wkwebview/mod.rs index 147db93..07a8403 100644 --- a/vendor/wry/src/wkwebview/mod.rs +++ b/vendor/wry/src/wkwebview/mod.rs @@ -34,7 +34,7 @@ use dpi::{LogicalPosition, LogicalSize}; use objc2::runtime::Bool; use objc2::{ rc::Retained, - runtime::{AnyObject, NSObject, ProtocolObject}, + runtime::{AnyObject, ProtocolObject}, ClassType, DeclaredClass, }; #[cfg(target_os = "macos")] @@ -387,7 +387,7 @@ impl InnerWebView { #[cfg(any(debug_assertions, feature = "devtools"))] if attributes.devtools { let has_inspectable_property: bool = - NSObject::respondsToSelector(&webview, objc2::sel!(setInspectable:)); + objc2::runtime::NSObject::respondsToSelector(&webview, objc2::sel!(setInspectable:)); if has_inspectable_property { webview.setInspectable(true); } @@ -538,7 +538,7 @@ r#"Object.defineProperty(window, 'ipc', { } } - pub fn id(&self) -> crate::WebViewId { + pub fn id(&self) -> crate::WebViewId<'_> { &self.id }