فهرست منبع

fix(windows): use webview events on windows (#2277)

Amr Bashir 4 سال پیش
والد
کامیت
d832d575d9
2فایلهای تغییر یافته به همراه75 افزوده شده و 1 حذف شده
  1. 7 0
      .changes/core-webview-events.md
  2. 68 1
      core/tauri-runtime-wry/src/lib.rs

+ 7 - 0
.changes/core-webview-events.md

@@ -0,0 +1,7 @@
+---
+"tauri": patch
+"tauri-runtime": patch
+"tauri-runtime-wry": patch
+---
+
+Fix blur/focus events being incorrect on Windows.

+ 68 - 1
core/tauri-runtime-wry/src/lib.rs

@@ -57,6 +57,9 @@ use wry::{
   },
 };
 
+#[cfg(target_os = "windows")]
+use wry::webview::WebviewExtWindows;
+
 use std::{
   collections::HashMap,
   convert::TryFrom,
@@ -281,7 +284,6 @@ impl<'a> From<&WryWindowEvent<'a>> for WindowEventWrapper {
       }
       WryWindowEvent::CloseRequested => WindowEvent::CloseRequested,
       WryWindowEvent::Destroyed => WindowEvent::Destroyed,
-      WryWindowEvent::Focused(focused) => WindowEvent::Focused(*focused),
       WryWindowEvent::ScaleFactorChanged {
         scale_factor,
         new_inner_size,
@@ -295,6 +297,15 @@ impl<'a> From<&WryWindowEvent<'a>> for WindowEventWrapper {
   }
 }
 
+impl From<&WebviewEvent> for WindowEventWrapper {
+  fn from(event: &WebviewEvent) -> Self {
+    let event = match event {
+      WebviewEvent::Focused(focused) => WindowEvent::Focused(*focused),
+    };
+    Self(Some(event))
+  }
+}
+
 pub struct MonitorHandleWrapper(MonitorHandle);
 
 impl From<MonitorHandleWrapper> for Monitor {
@@ -690,9 +701,17 @@ enum WindowMessage {
 #[derive(Debug, Clone)]
 enum WebviewMessage {
   EvaluateScript(String),
+  #[allow(dead_code)]
+  WebviewEvent(WebviewEvent),
   Print,
 }
 
+#[allow(dead_code)]
+#[derive(Debug, Clone)]
+enum WebviewEvent {
+  Focused(bool),
+}
+
 #[cfg(feature = "system-tray")]
 #[derive(Clone)]
 pub(crate) enum TrayMessage {
@@ -1330,6 +1349,33 @@ impl Runtime for Wry {
       pending,
     )?;
 
+    #[cfg(target_os = "windows")]
+    {
+      let id = webview.inner.window().id();
+      if let Some(controller) = webview.inner.controller() {
+        let proxy = self.event_loop.create_proxy();
+        controller
+          .add_got_focus(move |_| {
+            let _ = proxy.send_event(Message::Webview(
+              id,
+              WebviewMessage::WebviewEvent(WebviewEvent::Focused(true)),
+            ));
+            Ok(())
+          })
+          .unwrap();
+        let proxy = self.event_loop.create_proxy();
+        controller
+          .add_lost_focus(move |_| {
+            let _ = proxy.send_event(Message::Webview(
+              id,
+              WebviewMessage::WebviewEvent(WebviewEvent::Focused(false)),
+            ));
+            Ok(())
+          })
+          .unwrap();
+      };
+    }
+
     let dispatcher = WryDispatcher {
       window_id: webview.inner.window().id(),
       context: DispatcherContext {
@@ -1567,6 +1613,12 @@ fn handle_event_loop(
     Event::WindowEvent {
       event, window_id, ..
     } => {
+      if event == WryWindowEvent::Focused(true) {
+        if let Some(webview) = webviews.get(&window_id) {
+          webview.inner.focus();
+        };
+      }
+
       if let Some(event) = WindowEventWrapper::from(&event).0 {
         for handler in window_event_listeners
           .lock()
@@ -1768,6 +1820,21 @@ fn handle_event_loop(
             WebviewMessage::Print => {
               let _ = webview.inner.print();
             }
+            WebviewMessage::WebviewEvent(event) => {
+              if let Some(event) = WindowEventWrapper::from(&event).0 {
+                for handler in window_event_listeners
+                  .lock()
+                  .unwrap()
+                  .get(&id)
+                  .unwrap()
+                  .lock()
+                  .unwrap()
+                  .values()
+                {
+                  handler(&event);
+                }
+              }
+            }
           }
         }
       }