diff --git a/.changes/webview-focus.md b/.changes/webview-focus.md new file mode 100644 index 000000000..3d881717c --- /dev/null +++ b/.changes/webview-focus.md @@ -0,0 +1,5 @@ +--- +"wry": patch +--- +- Add `focus` method to `Webview` +- Add `WebviewExtWindows` trait with `on_focus` and `on_blur` \ No newline at end of file diff --git a/src/webview/mod.rs b/src/webview/mod.rs index dcac8bf47..3ef8f2cbe 100644 --- a/src/webview/mod.rs +++ b/src/webview/mod.rs @@ -344,6 +344,11 @@ impl WebView { self.webview.resize(self.window.hwnd())?; Ok(()) } + + /// Moves Focus to the Webview control. + pub fn focus(&self) { + self.webview.focus(); + } } // Helper so all platforms handle RPC messages consistently. @@ -458,6 +463,26 @@ pub fn webview_version() -> Result { platform_webview_version() } +#[cfg(target_os = "windows")] +pub trait WebviewExtWindows { + /// Hook into webview2 got_focus event + fn on_focus(&self, f: impl Fn() + 'static); + + /// Hook into webview2 lost_focus event + fn on_blur(&self, f: impl Fn() + 'static); +} + +#[cfg(target_os = "windows")] +impl WebviewExtWindows for WebView { + fn on_focus(&self, f: impl Fn() + 'static) { + self.webview.on_focus(f); + } + + fn on_blur(&self, f: impl Fn() + 'static) { + self.webview.on_blur(f); + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/webview/webkitgtk/mod.rs b/src/webview/webkitgtk/mod.rs index ae86e17f6..d7a6931c1 100644 --- a/src/webview/webkitgtk/mod.rs +++ b/src/webview/webkitgtk/mod.rs @@ -233,6 +233,10 @@ impl InnerWebView { } Ok(()) } + + pub fn focus(&self) { + self.webview.grab_focus(); + } } pub fn platform_webview_version() -> Result { diff --git a/src/webview/webview2/win32/mod.rs b/src/webview/webview2/win32/mod.rs index d790010aa..87c08e1a2 100644 --- a/src/webview/webview2/win32/mod.rs +++ b/src/webview/webview2/win32/mod.rs @@ -212,6 +212,7 @@ impl InnerWebView { } controller.put_is_visible(true)?; + controller.move_focus(webview2::MoveFocusReason::Programmatic)?; let _ = controller_clone.set(controller); if let Some(file_drop_handler) = attributes.file_drop_handler { @@ -275,6 +276,29 @@ impl InnerWebView { Ok(()) } + + pub fn focus(&self) { + if let Some(c) = self.controller.get() { + let _ = c.move_focus(webview2::MoveFocusReason::Programmatic); + } + } + pub fn on_focus(&self, f: impl Fn() + 'static) { + if let Some(c) = self.controller.get() { + let _ = c.add_got_focus(move |_| { + f(); + Ok(()) + }); + } + } + + pub fn on_blur(&self, f: impl Fn() + 'static) { + if let Some(c) = self.controller.get() { + let _ = c.add_lost_focus(move |_| { + f(); + Ok(()) + }); + } + } } pub fn platform_webview_version() -> Result { diff --git a/src/webview/wkwebview/mod.rs b/src/webview/wkwebview/mod.rs index 3a59c710c..b810eca12 100644 --- a/src/webview/wkwebview/mod.rs +++ b/src/webview/wkwebview/mod.rs @@ -391,6 +391,8 @@ impl InnerWebView { let () = msg_send![print_operation, runOperationModalForWindow: self.ns_window delegate: null::<*const c_void>() didRunSelector: null::<*const c_void>() contextInfo: null::<*const c_void>()]; } } + + pub fn focus(&self) {} } pub fn platform_webview_version() -> Result {