Skip to content

Commit 253c8db

Browse files
committed
Modularize WebView implementation by refactoring and reorganizing code
- Separate platform-specific logic into dedicated modules (`linux.rs`, `macos.rs`, `windows.rs`) for better maintainability. - Introduce new error types in `error.rs` for consistent error handling across platforms. - Refactor WebView state handling into `state.rs` with a global registry for managing WebView instances. - Add `handle.rs` for cross-platform window handle abstraction and utilities. - Simplify `lib.rs` by extracting logic into modular files and centralizing key operations.
1 parent b58ca72 commit 253c8db

8 files changed

Lines changed: 509 additions & 369 deletions

File tree

wrywebview/src/main/rust/error.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//! Error types for the WebView library.
2+
3+
/// Errors that can occur when working with WebViews.
4+
#[derive(Debug, thiserror::Error, uniffi::Error)]
5+
pub enum WebViewError {
6+
#[error("unsupported platform for native webview")]
7+
UnsupportedPlatform,
8+
9+
#[error("invalid parent window handle")]
10+
InvalidWindowHandle,
11+
12+
#[error("webview {0} not found")]
13+
WebViewNotFound(u64),
14+
15+
#[error("webview {0} must be accessed from the creating thread")]
16+
WrongThread(u64),
17+
18+
#[error("wry error: {0}")]
19+
WryError(String),
20+
21+
#[error("gtk initialization failed: {0}")]
22+
GtkInit(String),
23+
24+
#[error("internal error: {0}")]
25+
Internal(String),
26+
}
27+
28+
impl From<wry::Error> for WebViewError {
29+
fn from(error: wry::Error) -> Self {
30+
WebViewError::WryError(error.to_string())
31+
}
32+
}

wrywebview/src/main/rust/handle.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//! Window handle utilities for cross-platform WebView creation.
2+
3+
use wry::dpi::{LogicalPosition, LogicalSize};
4+
use wry::raw_window_handle::{HandleError, HasWindowHandle, RawWindowHandle, WindowHandle};
5+
use wry::Rect;
6+
7+
#[cfg(target_os = "linux")]
8+
use std::os::raw::c_ulong;
9+
#[cfg(target_os = "linux")]
10+
use wry::raw_window_handle::XlibWindowHandle;
11+
12+
#[cfg(target_os = "macos")]
13+
use wry::raw_window_handle::AppKitWindowHandle;
14+
15+
#[cfg(target_os = "windows")]
16+
use std::num::NonZeroIsize;
17+
#[cfg(target_os = "windows")]
18+
use wry::raw_window_handle::Win32WindowHandle;
19+
20+
use crate::error::WebViewError;
21+
22+
/// Wrapper around a raw window handle for WebView creation.
23+
pub struct RawWindow {
24+
pub raw: RawWindowHandle,
25+
}
26+
27+
impl HasWindowHandle for RawWindow {
28+
fn window_handle(&self) -> Result<WindowHandle<'_>, HandleError> {
29+
unsafe { Ok(WindowHandle::borrow_raw(self.raw)) }
30+
}
31+
}
32+
33+
/// Creates a `Rect` with the given position and size, ensuring minimum dimensions.
34+
pub fn make_bounds(x: i32, y: i32, width: i32, height: i32) -> Rect {
35+
let width = width.max(1);
36+
let height = height.max(1);
37+
Rect {
38+
position: LogicalPosition::new(x, y).into(),
39+
size: LogicalSize::new(width, height).into(),
40+
}
41+
}
42+
43+
/// Converts a platform-specific handle to a `RawWindowHandle`.
44+
pub fn raw_window_handle_from(parent_handle: u64) -> Result<RawWindowHandle, WebViewError> {
45+
if parent_handle == 0 {
46+
return Err(WebViewError::InvalidWindowHandle);
47+
}
48+
49+
#[cfg(target_os = "windows")]
50+
{
51+
let hwnd = NonZeroIsize::new(parent_handle as isize)
52+
.ok_or(WebViewError::InvalidWindowHandle)?;
53+
let handle = RawWindowHandle::Win32(Win32WindowHandle::new(hwnd));
54+
eprintln!("[wrywebview] raw_window_handle Win32=0x{:x}", parent_handle);
55+
return Ok(handle);
56+
}
57+
58+
#[cfg(target_os = "macos")]
59+
{
60+
let ns_view = crate::platform::macos::appkit_ns_view_from_handle(parent_handle)?;
61+
let handle = RawWindowHandle::AppKit(AppKitWindowHandle::new(ns_view));
62+
eprintln!(
63+
"[wrywebview] raw_window_handle AppKit=0x{:x} ns_view=0x{:x}",
64+
parent_handle,
65+
ns_view.as_ptr() as usize
66+
);
67+
return Ok(handle);
68+
}
69+
70+
#[cfg(target_os = "linux")]
71+
{
72+
let handle = RawWindowHandle::Xlib(XlibWindowHandle::new(parent_handle as c_ulong));
73+
eprintln!("[wrywebview] raw_window_handle Xlib=0x{:x}", parent_handle);
74+
return Ok(handle);
75+
}
76+
77+
#[cfg(not(any(target_os = "windows", target_os = "macos", target_os = "linux")))]
78+
{
79+
Err(WebViewError::UnsupportedPlatform)
80+
}
81+
}

0 commit comments

Comments
 (0)