diff --git a/wrywebview/src/main/kotlin/io/github/kdroidfilter/webview/wry/WryWebViewPanel.kt b/wrywebview/src/main/kotlin/io/github/kdroidfilter/webview/wry/WryWebViewPanel.kt index 8038f34..5dd9c1a 100644 --- a/wrywebview/src/main/kotlin/io/github/kdroidfilter/webview/wry/WryWebViewPanel.kt +++ b/wrywebview/src/main/kotlin/io/github/kdroidfilter/webview/wry/WryWebViewPanel.kt @@ -685,6 +685,16 @@ class WryWebViewPanel( } private object NativeBindings { + init { + setNativeLogger( + object : NativeLogger { + override fun handleLog(data: String) { + println(data) + } + } + ) + } + fun createWebview(parentHandle: ULong, width: Int, height: Int, url: String, handler: NavigationHandler): ULong { return io.github.kdroidfilter.webview.wry.createWebview(parentHandle, width, height, url, handler) } diff --git a/wrywebview/src/main/rust/handle.rs b/wrywebview/src/main/rust/handle.rs index 2e48add..6c67c9c 100644 --- a/wrywebview/src/main/rust/handle.rs +++ b/wrywebview/src/main/rust/handle.rs @@ -18,7 +18,7 @@ use std::num::NonZeroIsize; use wry::raw_window_handle::Win32WindowHandle; use crate::error::WebViewError; -use crate::log_enabled; +use crate::wry_log; /// Wrapper around a raw window handle for WebView creation. pub struct RawWindow { @@ -49,12 +49,13 @@ pub fn raw_window_handle_from(parent_handle: u64) -> Result Result>>> = OnceLock::new(); + +fn get_logger_registry() -> &'static RwLock>> { + GLOBAL_LOGGER.get_or_init(|| RwLock::new(None)) +} + +#[uniffi::export] +pub fn set_native_logger(logger: Box) { + let mut lock = get_logger_registry().write().unwrap(); + *lock = Some(logger); +} + +#[macro_export] macro_rules! wry_log { ($($arg:tt)*) => { - if log_enabled() { - eprintln!($($arg)*); - } + $crate::do_internal_log(format_args!($($arg)*)); }; } +#[doc(hidden)] +pub fn do_internal_log(args: std::fmt::Arguments) { + if !log_enabled() { + return; + } + let log_string = args.to_string(); + + if let Ok(lock) = crate::get_logger_registry().read() { + if let Some(ref logger) = *lock { + logger.handle_log(log_string); + return; + } + } + eprintln!("{}", log_string); +} + // ============================================================================ // WebView Creation // ============================================================================ @@ -364,12 +396,10 @@ pub fn create_webview_with_user_agent( // ============================================================================ fn set_bounds_inner(id: u64, x: i32, y: i32, width: i32, height: i32) -> Result<(), WebViewError> { - if log_enabled() { - wry_log!( - "[wrywebview] set_bounds id={} pos=({}, {}) size={}x{}", - id, x, y, width, height - ); - } + wry_log!( + "[wrywebview] set_bounds id={} pos=({}, {}) size={}x{}", + id, x, y, width, height + ); let bounds = make_bounds(x, y, width, height); with_webview(id, |webview| webview.set_bounds(bounds).map_err(WebViewError::from)) } diff --git a/wrywebview/src/main/rust/platform/macos.rs b/wrywebview/src/main/rust/platform/macos.rs index 226bbda..5df6300 100644 --- a/wrywebview/src/main/rust/platform/macos.rs +++ b/wrywebview/src/main/rust/platform/macos.rs @@ -5,13 +5,13 @@ use std::ffi::CStr; use std::ptr::NonNull; use dispatch2::run_on_main; +pub use dispatch2::DispatchQueue; use objc2::msg_send; use objc2::runtime::{AnyClass, AnyObject}; pub use objc2::MainThreadMarker; -pub use dispatch2::DispatchQueue; use crate::error::WebViewError; -use crate::log_enabled; +use crate::wry_log; /// Runs a closure on the main thread using GCD. pub fn run_on_main_thread(f: F) -> Result @@ -30,9 +30,10 @@ pub fn appkit_ns_view_from_handle(parent_handle: u64) -> Result, .ok_or(WebViewError::InvalidWindowHandle)?; let obj = unsafe { &*(ptr.as_ptr() as *mut AnyObject) }; let class_name = obj.class().name().to_string_lossy(); - if log_enabled() { - eprintln!("[wrywebview] appkit handle class={}", class_name); - } + // if log_enabled() { + // eprintln!("[wrywebview] appkit handle class={}", class_name); + // } + wry_log!("[wrywebview] appkit handle class={}", class_name); let nswindow_name = unsafe { CStr::from_bytes_with_nul_unchecked(b"NSWindow\0") }; let nsview_name = unsafe { CStr::from_bytes_with_nul_unchecked(b"NSView\0") }; @@ -43,12 +44,16 @@ pub fn appkit_ns_view_from_handle(parent_handle: u64) -> Result, if msg_send![obj, isKindOfClass: nswindow_cls] { let view: *mut AnyObject = msg_send![obj, contentView]; let view = NonNull::new(view).ok_or(WebViewError::InvalidWindowHandle)?; - if log_enabled() { - eprintln!( - "[wrywebview] appkit handle is NSWindow, contentView=0x{:x}", - view.as_ptr() as usize - ); - } + // if log_enabled() { + // eprintln!( + // "[wrywebview] appkit handle is NSWindow, contentView=0x{:x}", + // view.as_ptr() as usize + // ); + // } + wry_log!( + "[wrywebview] appkit handle is NSWindow, contentView=0x{:x}", + view.as_ptr() as usize + ); return Ok(view.cast()); } if msg_send![obj, isKindOfClass: nsview_cls] {