浏览代码

feat(webview): add reparent API (#8939)

* feat(webview): add reparent API

* fix build

* fix import

* remove cfg

* fix windows

* clone

* clone value

* ()
Lucas Fernandes Nogueira 1 年之前
父节点
当前提交
fdcaf935fa

+ 8 - 0
.changes/reparent.md

@@ -0,0 +1,8 @@
+---
+"@tauri-apps/api": patch:feat
+"tauri": patch:feat
+"tauri-runtime": patch:feat
+"tauri-runtime-wry": patch:feat
+---
+
+Added the `reparent` function to the webview API.

+ 242 - 162
core/tauri-runtime-wry/src/lib.rs

@@ -170,7 +170,11 @@ macro_rules! webview_getter {
     getter!(
     getter!(
       $self,
       $self,
       rx,
       rx,
-      Message::Webview($self.window_id, $self.webview_id, $message(tx))
+      Message::Webview(
+        *$self.window_id.lock().unwrap(),
+        $self.webview_id,
+        $message(tx)
+      )
     )
     )
   }};
   }};
 }
 }
@@ -280,7 +284,7 @@ impl<T: UserEvent> Context<T> {
     let detached_webview = webview_id.map(|id| DetachedWebview {
     let detached_webview = webview_id.map(|id| DetachedWebview {
       label: label.clone(),
       label: label.clone(),
       dispatcher: WryWebviewDispatcher {
       dispatcher: WryWebviewDispatcher {
-        window_id,
+        window_id: Arc::new(Mutex::new(window_id)),
         webview_id: id,
         webview_id: id,
         context: self.clone(),
         context: self.clone(),
       },
       },
@@ -304,6 +308,9 @@ impl<T: UserEvent> Context<T> {
 
 
     let webview_id = self.next_webview_id();
     let webview_id = self.next_webview_id();
 
 
+    let window_id_wrapper = Arc::new(Mutex::new(window_id));
+    let window_id_wrapper_ = window_id_wrapper.clone();
+
     send_user_message(
     send_user_message(
       self,
       self,
       Message::CreateWebview(
       Message::CreateWebview(
@@ -312,7 +319,7 @@ impl<T: UserEvent> Context<T> {
           create_webview(
           create_webview(
             WebviewKind::WindowChild,
             WebviewKind::WindowChild,
             window,
             window,
-            window_id,
+            window_id_wrapper_,
             webview_id,
             webview_id,
             &context,
             &context,
             pending,
             pending,
@@ -322,7 +329,7 @@ impl<T: UserEvent> Context<T> {
     )?;
     )?;
 
 
     let dispatcher = WryWebviewDispatcher {
     let dispatcher = WryWebviewDispatcher {
-      window_id,
+      window_id: window_id_wrapper,
       webview_id,
       webview_id,
       context: self.clone(),
       context: self.clone(),
     };
     };
@@ -1170,6 +1177,7 @@ pub enum WebviewMessage {
   SetPosition(Position),
   SetPosition(Position),
   SetSize(Size),
   SetSize(Size),
   SetFocus,
   SetFocus,
+  Reparent(WindowId),
   // Getters
   // Getters
   Url(Sender<Url>),
   Url(Sender<Url>),
   Position(Sender<PhysicalPosition<i32>>),
   Position(Sender<PhysicalPosition<i32>>),
@@ -1220,7 +1228,7 @@ impl<T: UserEvent> Clone for Message<T> {
 /// The Tauri [`WebviewDispatch`] for [`Wry`].
 /// The Tauri [`WebviewDispatch`] for [`Wry`].
 #[derive(Debug, Clone)]
 #[derive(Debug, Clone)]
 pub struct WryWebviewDispatcher<T: UserEvent> {
 pub struct WryWebviewDispatcher<T: UserEvent> {
-  window_id: WindowId,
+  window_id: Arc<Mutex<WindowId>>,
   webview_id: WebviewId,
   webview_id: WebviewId,
   context: Context<T>,
   context: Context<T>,
 }
 }
@@ -1235,7 +1243,7 @@ impl<T: UserEvent> WebviewDispatch<T> for WryWebviewDispatcher<T> {
   fn on_webview_event<F: Fn(&WebviewEvent) + Send + 'static>(&self, f: F) -> WindowEventId {
   fn on_webview_event<F: Fn(&WebviewEvent) + Send + 'static>(&self, f: F) -> WindowEventId {
     let id = self.context.next_webview_event_id();
     let id = self.context.next_webview_event_id();
     let _ = self.context.proxy.send_event(Message::Webview(
     let _ = self.context.proxy.send_event(Message::Webview(
-      self.window_id,
+      *self.window_id.lock().unwrap(),
       self.webview_id,
       self.webview_id,
       WebviewMessage::AddEventListener(id, Box::new(f)),
       WebviewMessage::AddEventListener(id, Box::new(f)),
     ));
     ));
@@ -1246,7 +1254,7 @@ impl<T: UserEvent> WebviewDispatch<T> for WryWebviewDispatcher<T> {
     send_user_message(
     send_user_message(
       &self.context,
       &self.context,
       Message::Webview(
       Message::Webview(
-        self.window_id,
+        *self.window_id.lock().unwrap(),
         self.webview_id,
         self.webview_id,
         WebviewMessage::WithWebview(Box::new(move |webview| f(Box::new(webview)))),
         WebviewMessage::WithWebview(Box::new(move |webview| f(Box::new(webview)))),
       ),
       ),
@@ -1258,7 +1266,7 @@ impl<T: UserEvent> WebviewDispatch<T> for WryWebviewDispatcher<T> {
     let _ = send_user_message(
     let _ = send_user_message(
       &self.context,
       &self.context,
       Message::Webview(
       Message::Webview(
-        self.window_id,
+        *self.window_id.lock().unwrap(),
         self.webview_id,
         self.webview_id,
         WebviewMessage::OpenDevTools,
         WebviewMessage::OpenDevTools,
       ),
       ),
@@ -1270,7 +1278,7 @@ impl<T: UserEvent> WebviewDispatch<T> for WryWebviewDispatcher<T> {
     let _ = send_user_message(
     let _ = send_user_message(
       &self.context,
       &self.context,
       Message::Webview(
       Message::Webview(
-        self.window_id,
+        *self.window_id.lock().unwrap(),
         self.webview_id,
         self.webview_id,
         WebviewMessage::CloseDevTools,
         WebviewMessage::CloseDevTools,
       ),
       ),
@@ -1303,7 +1311,7 @@ impl<T: UserEvent> WebviewDispatch<T> for WryWebviewDispatcher<T> {
     send_user_message(
     send_user_message(
       &self.context,
       &self.context,
       Message::Webview(
       Message::Webview(
-        self.window_id,
+        *self.window_id.lock().unwrap(),
         self.webview_id,
         self.webview_id,
         WebviewMessage::Navigate(url),
         WebviewMessage::Navigate(url),
       ),
       ),
@@ -1313,14 +1321,22 @@ impl<T: UserEvent> WebviewDispatch<T> for WryWebviewDispatcher<T> {
   fn print(&self) -> Result<()> {
   fn print(&self) -> Result<()> {
     send_user_message(
     send_user_message(
       &self.context,
       &self.context,
-      Message::Webview(self.window_id, self.webview_id, WebviewMessage::Print),
+      Message::Webview(
+        *self.window_id.lock().unwrap(),
+        self.webview_id,
+        WebviewMessage::Print,
+      ),
     )
     )
   }
   }
 
 
   fn close(&self) -> Result<()> {
   fn close(&self) -> Result<()> {
     send_user_message(
     send_user_message(
       &self.context,
       &self.context,
-      Message::Webview(self.window_id, self.webview_id, WebviewMessage::Close),
+      Message::Webview(
+        *self.window_id.lock().unwrap(),
+        self.webview_id,
+        WebviewMessage::Close,
+      ),
     )
     )
   }
   }
 
 
@@ -1328,7 +1344,7 @@ impl<T: UserEvent> WebviewDispatch<T> for WryWebviewDispatcher<T> {
     send_user_message(
     send_user_message(
       &self.context,
       &self.context,
       Message::Webview(
       Message::Webview(
-        self.window_id,
+        *self.window_id.lock().unwrap(),
         self.webview_id,
         self.webview_id,
         WebviewMessage::SetSize(size),
         WebviewMessage::SetSize(size),
       ),
       ),
@@ -1339,7 +1355,7 @@ impl<T: UserEvent> WebviewDispatch<T> for WryWebviewDispatcher<T> {
     send_user_message(
     send_user_message(
       &self.context,
       &self.context,
       Message::Webview(
       Message::Webview(
-        self.window_id,
+        *self.window_id.lock().unwrap(),
         self.webview_id,
         self.webview_id,
         WebviewMessage::SetPosition(position),
         WebviewMessage::SetPosition(position),
       ),
       ),
@@ -1349,10 +1365,29 @@ impl<T: UserEvent> WebviewDispatch<T> for WryWebviewDispatcher<T> {
   fn set_focus(&self) -> Result<()> {
   fn set_focus(&self) -> Result<()> {
     send_user_message(
     send_user_message(
       &self.context,
       &self.context,
-      Message::Webview(self.window_id, self.webview_id, WebviewMessage::SetFocus),
+      Message::Webview(
+        *self.window_id.lock().unwrap(),
+        self.webview_id,
+        WebviewMessage::SetFocus,
+      ),
     )
     )
   }
   }
 
 
+  fn reparent(&self, window_id: WindowId) -> Result<()> {
+    let mut current_window_id = self.window_id.lock().unwrap();
+    send_user_message(
+      &self.context,
+      Message::Webview(
+        *current_window_id,
+        self.webview_id,
+        WebviewMessage::Reparent(window_id),
+      ),
+    )?;
+
+    *current_window_id = window_id;
+    Ok(())
+  }
+
   #[cfg(all(feature = "tracing", not(target_os = "android")))]
   #[cfg(all(feature = "tracing", not(target_os = "android")))]
   fn eval_script<S: Into<String>>(&self, script: S) -> Result<()> {
   fn eval_script<S: Into<String>>(&self, script: S) -> Result<()> {
     // use a channel so the EvaluateScript task uses the current span as parent
     // use a channel so the EvaluateScript task uses the current span as parent
@@ -1361,7 +1396,7 @@ impl<T: UserEvent> WebviewDispatch<T> for WryWebviewDispatcher<T> {
       self,
       self,
       rx,
       rx,
       Message::Webview(
       Message::Webview(
-        self.window_id,
+        *self.window_id.lock().unwrap(),
         self.webview_id,
         self.webview_id,
         WebviewMessage::EvaluateScript(script.into(), tx, tracing::Span::current()),
         WebviewMessage::EvaluateScript(script.into(), tx, tracing::Span::current()),
       )
       )
@@ -1373,7 +1408,7 @@ impl<T: UserEvent> WebviewDispatch<T> for WryWebviewDispatcher<T> {
     send_user_message(
     send_user_message(
       &self.context,
       &self.context,
       Message::Webview(
       Message::Webview(
-        self.window_id,
+        *self.window_id.lock().unwrap(),
         self.webview_id,
         self.webview_id,
         WebviewMessage::EvaluateScript(script.into()),
         WebviewMessage::EvaluateScript(script.into()),
       ),
       ),
@@ -2235,7 +2270,7 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
     let detached_webview = webview_id.map(|id| DetachedWebview {
     let detached_webview = webview_id.map(|id| DetachedWebview {
       label: label.clone(),
       label: label.clone(),
       dispatcher: WryWebviewDispatcher {
       dispatcher: WryWebviewDispatcher {
-        window_id,
+        window_id: Arc::new(Mutex::new(window_id)),
         webview_id: id,
         webview_id: id,
         context: self.context.clone(),
         context: self.context.clone(),
       },
       },
@@ -2265,12 +2300,14 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
       .get(&window_id)
       .get(&window_id)
       .and_then(|w| w.inner.clone());
       .and_then(|w| w.inner.clone());
     if let Some(window) = window {
     if let Some(window) = window {
+      let window_id_wrapper = Arc::new(Mutex::new(window_id));
+
       let webview_id = self.context.next_webview_id();
       let webview_id = self.context.next_webview_id();
 
 
       let webview = create_webview(
       let webview = create_webview(
         WebviewKind::WindowChild,
         WebviewKind::WindowChild,
         &window,
         &window,
-        window_id,
+        window_id_wrapper.clone(),
         webview_id,
         webview_id,
         &self.context,
         &self.context,
         pending,
         pending,
@@ -2290,7 +2327,7 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
         });
         });
 
 
       let dispatcher = WryWebviewDispatcher {
       let dispatcher = WryWebviewDispatcher {
-        window_id,
+        window_id: window_id_wrapper,
         webview_id,
         webview_id,
         context: self.context.clone(),
         context: self.context.clone(),
       };
       };
@@ -2685,87 +2722,33 @@ fn handle_user_message<T: UserEvent>(
         }
         }
       }
       }
     }
     }
-
     Message::Webview(window_id, webview_id, webview_message) => {
     Message::Webview(window_id, webview_id, webview_message) => {
-      let webview_handle = windows.0.borrow().get(&window_id).map(|w| {
-        (
-          w.inner.clone(),
-          w.webviews.iter().find(|w| w.id == webview_id).cloned(),
-        )
-      });
-      if let Some((Some(window), Some(webview))) = webview_handle {
-        match webview_message {
-          WebviewMessage::WebviewEvent(_) => { /* already handled */ }
-          WebviewMessage::SynthesizedWindowEvent(_) => { /* already handled */ }
-
-          WebviewMessage::AddEventListener(id, listener) => {
-            webview
-              .webview_event_listeners
-              .lock()
-              .unwrap()
-              .insert(id, listener);
-          }
+      if let WebviewMessage::Reparent(new_parent_window_id) = webview_message {
+        let webview_handle = windows.0.borrow_mut().get_mut(&window_id).and_then(|w| {
+          w.webviews
+            .iter()
+            .position(|w| w.id == webview_id)
+            .map(|webview_index| w.webviews.remove(webview_index))
+        });
 
 
-          #[cfg(all(feature = "tracing", not(target_os = "android")))]
-          WebviewMessage::EvaluateScript(script, tx, span) => {
-            let _span = span.entered();
-            if let Err(e) = webview.evaluate_script(&script) {
-              debug_eprintln!("{}", e);
-            }
-            tx.send(()).unwrap();
-          }
-          #[cfg(not(all(feature = "tracing", not(target_os = "android"))))]
-          WebviewMessage::EvaluateScript(script) => {
-            if let Err(e) = webview.evaluate_script(&script) {
-              debug_eprintln!("{}", e);
-            }
-          }
-          WebviewMessage::Navigate(url) => webview.load_url(url.as_str()),
-          WebviewMessage::Print => {
-            let _ = webview.print();
-          }
-          WebviewMessage::Close => {
-            windows.0.borrow_mut().get_mut(&window_id).map(|window| {
-              if let Some(i) = window.webviews.iter().position(|w| w.id == webview.id) {
-                window.webviews.remove(i);
-              }
-              window
-            });
-          }
-          WebviewMessage::SetSize(size) => {
-            let mut bounds = webview.bounds();
-            let size = size.to_logical(window.scale_factor());
-            bounds.width = size.width;
-            bounds.height = size.height;
-
-            if let Some(b) = &webview.bounds {
-              let window_size = window.inner_size();
-              let mut bounds = b.lock().unwrap();
-              bounds.width_rate = size.width as f32 / window_size.width as f32;
-              bounds.height_rate = size.height as f32 / window_size.height as f32;
+        if let Some(webview) = webview_handle {
+          if let Some((Some(new_parent_window), new_parent_window_webviews)) = windows
+            .0
+            .borrow_mut()
+            .get_mut(&new_parent_window_id)
+            .map(|w| (w.inner.clone(), &mut w.webviews))
+          {
+            #[cfg(target_os = "macos")]
+            {
+              use wry::WebViewExtMacOS;
+              webview.inner.reparent(new_parent_window.ns_window() as _);
+              new_parent_window_webviews.push(webview);
             }
             }
-
-            webview.set_bounds(bounds);
-          }
-          WebviewMessage::SetPosition(position) => {
-            let mut bounds = webview.bounds();
-            let position = position.to_logical(window.scale_factor());
-            bounds.x = position.x;
-            bounds.y = position.y;
-
-            if let Some(b) = &webview.bounds {
-              let window_size = window.inner_size();
-              let mut bounds = b.lock().unwrap();
-              bounds.width_rate = position.x as f32 / window_size.width as f32;
-              bounds.height_rate = position.y as f32 / window_size.height as f32;
+            #[cfg(windows)]
+            {
+              webview.inner.reparent(new_parent_window.hwnd());
+              new_parent_window_webviews.push(webview);
             }
             }
-
-            webview.set_bounds(bounds);
-          }
-          WebviewMessage::SetFocus => {
-            webview.focus();
-          }
-          WebviewMessage::WithWebview(f) => {
             #[cfg(any(
             #[cfg(any(
               target_os = "linux",
               target_os = "linux",
               target_os = "dragonfly",
               target_os = "dragonfly",
@@ -2774,68 +2757,163 @@ fn handle_user_message<T: UserEvent>(
               target_os = "openbsd"
               target_os = "openbsd"
             ))]
             ))]
             {
             {
-              f(webview.webview());
+              if let Some(container) = new_parent_window.default_vbox() {
+                webview.inner.reparent(container);
+                new_parent_window_webviews.push(webview);
+              }
             }
             }
-            #[cfg(target_os = "macos")]
-            {
-              use wry::WebViewExtMacOS;
-              f(Webview {
-                webview: webview.webview(),
-                manager: webview.manager(),
-                ns_window: webview.ns_window(),
-              });
+          }
+        }
+      } else {
+        let webview_handle = windows.0.borrow().get(&window_id).map(|w| {
+          (
+            w.inner.clone(),
+            w.webviews.iter().find(|w| w.id == webview_id).cloned(),
+          )
+        });
+        if let Some((Some(window), Some(webview))) = webview_handle {
+          match webview_message {
+            WebviewMessage::WebviewEvent(_) => { /* already handled */ }
+            WebviewMessage::SynthesizedWindowEvent(_) => { /* already handled */ }
+            WebviewMessage::Reparent(_window_id) => { /* already handled */ }
+            WebviewMessage::AddEventListener(id, listener) => {
+              webview
+                .webview_event_listeners
+                .lock()
+                .unwrap()
+                .insert(id, listener);
             }
             }
-            #[cfg(target_os = "ios")]
-            {
-              use tao::platform::ios::WindowExtIOS;
-              use wry::WebViewExtIOS;
 
 
-              f(Webview {
-                webview: webview.inner.webview(),
-                manager: webview.inner.manager(),
-                view_controller: window.ui_view_controller() as cocoa::base::id,
-              });
+            #[cfg(all(feature = "tracing", not(target_os = "android")))]
+            WebviewMessage::EvaluateScript(script, tx, span) => {
+              let _span = span.entered();
+              if let Err(e) = webview.evaluate_script(&script) {
+                debug_eprintln!("{}", e);
+              }
+              tx.send(()).unwrap();
             }
             }
-            #[cfg(windows)]
-            {
-              f(Webview {
-                controller: webview.controller(),
+            #[cfg(not(all(feature = "tracing", not(target_os = "android"))))]
+            WebviewMessage::EvaluateScript(script) => {
+              if let Err(e) = webview.evaluate_script(&script) {
+                debug_eprintln!("{}", e);
+              }
+            }
+            WebviewMessage::Navigate(url) => webview.load_url(url.as_str()),
+            WebviewMessage::Print => {
+              let _ = webview.print();
+            }
+            WebviewMessage::Close => {
+              windows.0.borrow_mut().get_mut(&window_id).map(|window| {
+                if let Some(i) = window.webviews.iter().position(|w| w.id == webview.id) {
+                  window.webviews.remove(i);
+                }
+                window
               });
               });
             }
             }
-            #[cfg(target_os = "android")]
-            {
-              f(webview.handle())
+            WebviewMessage::SetSize(size) => {
+              let mut bounds = webview.bounds();
+              let size = size.to_logical(window.scale_factor());
+              bounds.width = size.width;
+              bounds.height = size.height;
+
+              if let Some(b) = &webview.bounds {
+                let window_size = window.inner_size();
+                let mut bounds = b.lock().unwrap();
+                bounds.width_rate = size.width as f32 / window_size.width as f32;
+                bounds.height_rate = size.height as f32 / window_size.height as f32;
+              }
+
+              webview.set_bounds(bounds);
             }
             }
-          }
+            WebviewMessage::SetPosition(position) => {
+              let mut bounds = webview.bounds();
+              let position = position.to_logical(window.scale_factor());
+              bounds.x = position.x;
+              bounds.y = position.y;
+
+              if let Some(b) = &webview.bounds {
+                let window_size = window.inner_size();
+                let mut bounds = b.lock().unwrap();
+                bounds.width_rate = position.x as f32 / window_size.width as f32;
+                bounds.height_rate = position.y as f32 / window_size.height as f32;
+              }
 
 
-          #[cfg(any(debug_assertions, feature = "devtools"))]
-          WebviewMessage::OpenDevTools => {
-            webview.open_devtools();
-          }
-          #[cfg(any(debug_assertions, feature = "devtools"))]
-          WebviewMessage::CloseDevTools => {
-            webview.close_devtools();
-          }
-          #[cfg(any(debug_assertions, feature = "devtools"))]
-          WebviewMessage::IsDevToolsOpen(tx) => {
-            tx.send(webview.is_devtools_open()).unwrap();
-          }
+              webview.set_bounds(bounds);
+            }
+            // Getters
+            WebviewMessage::Url(tx) => {
+              tx.send(webview.url().parse().unwrap()).unwrap();
+            }
+            WebviewMessage::Position(tx) => {
+              let bounds = webview.bounds();
+              let position =
+                LogicalPosition::new(bounds.x, bounds.y).to_physical(window.scale_factor());
+              tx.send(position).unwrap();
+            }
+            WebviewMessage::Size(tx) => {
+              let bounds = webview.bounds();
+              let size =
+                LogicalSize::new(bounds.width, bounds.height).to_physical(window.scale_factor());
+              tx.send(size).unwrap();
+            }
+            WebviewMessage::SetFocus => {
+              webview.focus();
+            }
+            WebviewMessage::WithWebview(f) => {
+              #[cfg(any(
+                target_os = "linux",
+                target_os = "dragonfly",
+                target_os = "freebsd",
+                target_os = "netbsd",
+                target_os = "openbsd"
+              ))]
+              {
+                f(webview.webview());
+              }
+              #[cfg(target_os = "macos")]
+              {
+                use wry::WebViewExtMacOS;
+                f(Webview {
+                  webview: webview.webview(),
+                  manager: webview.manager(),
+                  ns_window: webview.ns_window(),
+                });
+              }
+              #[cfg(target_os = "ios")]
+              {
+                use tao::platform::ios::WindowExtIOS;
+                use wry::WebViewExtIOS;
+
+                f(Webview {
+                  webview: webview.inner.webview(),
+                  manager: webview.inner.manager(),
+                  view_controller: window.ui_view_controller() as cocoa::base::id,
+                });
+              }
+              #[cfg(windows)]
+              {
+                f(Webview {
+                  controller: webview.controller(),
+                });
+              }
+              #[cfg(target_os = "android")]
+              {
+                f(webview.handle())
+              }
+            }
 
 
-          // Getters
-          WebviewMessage::Url(tx) => {
-            tx.send(webview.url().parse().unwrap()).unwrap();
-          }
-          WebviewMessage::Position(tx) => {
-            let bounds = webview.bounds();
-            let position =
-              LogicalPosition::new(bounds.x, bounds.y).to_physical(window.scale_factor());
-            tx.send(position).unwrap();
-          }
-          WebviewMessage::Size(tx) => {
-            let bounds = webview.bounds();
-            let size =
-              LogicalSize::new(bounds.width, bounds.height).to_physical(window.scale_factor());
-            tx.send(size).unwrap();
+            #[cfg(any(debug_assertions, feature = "devtools"))]
+            WebviewMessage::OpenDevTools => {
+              webview.open_devtools();
+            }
+            #[cfg(any(debug_assertions, feature = "devtools"))]
+            WebviewMessage::CloseDevTools => {
+              webview.close_devtools();
+            }
+            #[cfg(any(debug_assertions, feature = "devtools"))]
+            WebviewMessage::IsDevToolsOpen(tx) => {
+              tx.send(webview.is_devtools_open()).unwrap();
+            }
           }
           }
         }
         }
       }
       }
@@ -3341,7 +3419,7 @@ fn create_window<T: UserEvent, F: Fn(RawWindow) + Send + 'static>(
     webviews.push(create_webview(
     webviews.push(create_webview(
       WebviewKind::WindowContent,
       WebviewKind::WindowContent,
       &window,
       &window,
-      window_id,
+      Arc::new(Mutex::new(window_id)),
       webview_id,
       webview_id,
       context,
       context,
       webview,
       webview,
@@ -3390,7 +3468,7 @@ enum WebviewKind {
   WindowChild,
   WindowChild,
 }
 }
 
 
-#[derive(Clone)]
+#[derive(Debug, Clone)]
 struct WebviewBounds {
 struct WebviewBounds {
   x_rate: f32,
   x_rate: f32,
   y_rate: f32,
   y_rate: f32,
@@ -3401,7 +3479,7 @@ struct WebviewBounds {
 fn create_webview<T: UserEvent>(
 fn create_webview<T: UserEvent>(
   kind: WebviewKind,
   kind: WebviewKind,
   window: &Window,
   window: &Window,
-  window_id: WindowId,
+  window_id: Arc<Mutex<WindowId>>,
   id: WebviewId,
   id: WebviewId,
   context: &Context<T>,
   context: &Context<T>,
   pending: PendingWebview<T, Wry<T>>,
   pending: PendingWebview<T, Wry<T>>,
@@ -3470,6 +3548,7 @@ fn create_webview<T: UserEvent>(
 
 
   if webview_attributes.file_drop_handler_enabled {
   if webview_attributes.file_drop_handler_enabled {
     let proxy = context.proxy.clone();
     let proxy = context.proxy.clone();
+    let window_id_ = window_id.clone();
     webview_builder = webview_builder.with_file_drop_handler(move |event| {
     webview_builder = webview_builder.with_file_drop_handler(move |event| {
       let event = match event {
       let event = match event {
         WryFileDropEvent::Hovered {
         WryFileDropEvent::Hovered {
@@ -3496,7 +3575,7 @@ fn create_webview<T: UserEvent>(
         WebviewMessage::WebviewEvent(WebviewEvent::FileDrop(event))
         WebviewMessage::WebviewEvent(WebviewEvent::FileDrop(event))
       };
       };
 
 
-      let _ = proxy.send_event(Message::Webview(window_id, id, message));
+      let _ = proxy.send_event(Message::Webview(*window_id_.lock().unwrap(), id, message));
       true
       true
     });
     });
   }
   }
@@ -3598,7 +3677,7 @@ fn create_webview<T: UserEvent>(
 
 
   webview_builder = webview_builder.with_ipc_handler(create_ipc_handler(
   webview_builder = webview_builder.with_ipc_handler(create_ipc_handler(
     kind,
     kind,
-    window_id,
+    window_id.clone(),
     id,
     id,
     context.clone(),
     context.clone(),
     label.clone(),
     label.clone(),
@@ -3696,12 +3775,13 @@ fn create_webview<T: UserEvent>(
     let controller = webview.controller();
     let controller = webview.controller();
     let proxy = context.proxy.clone();
     let proxy = context.proxy.clone();
     let proxy_ = proxy.clone();
     let proxy_ = proxy.clone();
+    let window_id_ = window_id.clone();
     let mut token = EventRegistrationToken::default();
     let mut token = EventRegistrationToken::default();
     unsafe {
     unsafe {
       controller.add_GotFocus(
       controller.add_GotFocus(
         &FocusChangedEventHandler::create(Box::new(move |_, _| {
         &FocusChangedEventHandler::create(Box::new(move |_, _| {
-          let _ = proxy_.send_event(Message::Webview(
-            window_id,
+          let _ = proxy.send_event(Message::Webview(
+            *window_id_.lock().unwrap(),
             id,
             id,
             WebviewMessage::SynthesizedWindowEvent(SynthesizedWindowEvent::Focused(true)),
             WebviewMessage::SynthesizedWindowEvent(SynthesizedWindowEvent::Focused(true)),
           ));
           ));
@@ -3714,8 +3794,8 @@ fn create_webview<T: UserEvent>(
     unsafe {
     unsafe {
       controller.add_LostFocus(
       controller.add_LostFocus(
         &FocusChangedEventHandler::create(Box::new(move |_, _| {
         &FocusChangedEventHandler::create(Box::new(move |_, _| {
-          let _ = proxy.send_event(Message::Webview(
-            window_id,
+          let _ = proxy_.send_event(Message::Webview(
+            *window_id.lock().unwrap(),
             id,
             id,
             WebviewMessage::SynthesizedWindowEvent(SynthesizedWindowEvent::Focused(false)),
             WebviewMessage::SynthesizedWindowEvent(SynthesizedWindowEvent::Focused(false)),
           ));
           ));
@@ -3745,7 +3825,7 @@ fn create_webview<T: UserEvent>(
 /// Create a wry ipc handler from a tauri ipc handler.
 /// Create a wry ipc handler from a tauri ipc handler.
 fn create_ipc_handler<T: UserEvent>(
 fn create_ipc_handler<T: UserEvent>(
   _kind: WebviewKind,
   _kind: WebviewKind,
-  window_id: WindowId,
+  window_id: Arc<Mutex<WindowId>>,
   webview_id: WebviewId,
   webview_id: WebviewId,
   context: Context<T>,
   context: Context<T>,
   label: String,
   label: String,
@@ -3754,7 +3834,7 @@ fn create_ipc_handler<T: UserEvent>(
   Box::new(move |request| {
   Box::new(move |request| {
     #[cfg(windows)]
     #[cfg(windows)]
     if _kind == WebviewKind::WindowContent
     if _kind == WebviewKind::WindowContent
-      && undecorated_resizing::handle_request(context.clone(), window_id, &request)
+      && undecorated_resizing::handle_request(context.clone(), *window_id.lock().unwrap(), &request)
     {
     {
       return;
       return;
     }
     }
@@ -3764,7 +3844,7 @@ fn create_ipc_handler<T: UserEvent>(
         DetachedWebview {
         DetachedWebview {
           label: label.clone(),
           label: label.clone(),
           dispatcher: WryWebviewDispatcher {
           dispatcher: WryWebviewDispatcher {
-            window_id,
+            window_id: window_id.clone(),
             webview_id,
             webview_id,
             context: context.clone(),
             context: context.clone(),
           },
           },

+ 3 - 0
core/tauri-runtime/src/lib.rs

@@ -449,6 +449,9 @@ pub trait WebviewDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + '
 
 
   /// Executes javascript on the window this [`WindowDispatch`] represents.
   /// Executes javascript on the window this [`WindowDispatch`] represents.
   fn eval_script<S: Into<String>>(&self, script: S) -> Result<()>;
   fn eval_script<S: Into<String>>(&self, script: S) -> Result<()>;
+
+  /// Moves the webview to the given window.
+  fn reparent(&self, window_id: WindowId) -> Result<()>;
 }
 }
 
 
 /// Window dispatcher. A thread-safe handle to the window APIs.
 /// Window dispatcher. A thread-safe handle to the window APIs.

+ 1 - 0
core/tauri/build.rs

@@ -122,6 +122,7 @@ const PLUGINS: &[(&str, &[(&str, bool)])] = &[
       ("set_webview_position", false),
       ("set_webview_position", false),
       ("set_webview_focus", false),
       ("set_webview_focus", false),
       ("print", false),
       ("print", false),
+      ("reparent", false),
       // internal
       // internal
       ("internal_toggle_devtools", true),
       ("internal_toggle_devtools", true),
     ],
     ],

+ 8 - 0
core/tauri/permissions/webview/autogenerated/reference.md

@@ -32,6 +32,14 @@ Enables the print command without any pre-configured scope.
 
 
 Denies the print command without any pre-configured scope.
 Denies the print command without any pre-configured scope.
 
 
+## allow-reparent
+
+Enables the reparent command without any pre-configured scope.
+
+## deny-reparent
+
+Denies the reparent command without any pre-configured scope.
+
 ## allow-set-webview-focus
 ## allow-set-webview-focus
 
 
 Enables the set_webview_focus command without any pre-configured scope.
 Enables the set_webview_focus command without any pre-configured scope.

文件差异内容过多而无法显示
+ 0 - 0
core/tauri/scripts/bundle.global.js


+ 4 - 2
core/tauri/src/ipc/protocol.rs

@@ -244,11 +244,13 @@ fn handle_ipc_message<R: Runtime>(message: String, manager: &AppManager<R>, labe
       }
       }
     }
     }
 
 
-    match invoke_message.unwrap_or_else(|| {
+    let message = invoke_message.unwrap_or_else(|| {
       #[cfg(feature = "tracing")]
       #[cfg(feature = "tracing")]
       let _span = tracing::trace_span!("ipc::request::deserialize").entered();
       let _span = tracing::trace_span!("ipc::request::deserialize").entered();
       serde_json::from_str::<Message>(&message).map_err(Into::into)
       serde_json::from_str::<Message>(&message).map_err(Into::into)
-    }) {
+    });
+
+    match message {
       Ok(message) => {
       Ok(message) => {
         let request = InvokeRequest {
         let request = InvokeRequest {
           cmd: message.cmd,
           cmd: message.cmd,

+ 4 - 0
core/tauri/src/test/mock_runtime.rs

@@ -540,6 +540,10 @@ impl<T: UserEvent> WebviewDispatch<T> for MockWebviewDispatcher {
   fn set_focus(&self) -> Result<()> {
   fn set_focus(&self) -> Result<()> {
     Ok(())
     Ok(())
   }
   }
+
+  fn reparent(&self, window_id: WindowId) -> Result<()> {
+    Ok(())
+  }
 }
 }
 
 
 impl<T: UserEvent> WindowDispatch<T> for MockWindowDispatcher {
 impl<T: UserEvent> WindowDispatch<T> for MockWindowDispatcher {

+ 52 - 25
core/tauri/src/webview/mod.rs

@@ -606,7 +606,7 @@ tauri::Builder::default()
       .webviews_lock()
       .webviews_lock()
       .values()
       .values()
       .map(|w| WebviewLabelDef {
       .map(|w| WebviewLabelDef {
-        window_label: w.window.label().to_string(),
+        window_label: w.window().label().to_string(),
         label: w.label().to_string(),
         label: w.label().to_string(),
       })
       })
       .collect::<Vec<_>>();
       .collect::<Vec<_>>();
@@ -794,7 +794,10 @@ fn main() {
 /// Webview.
 /// Webview.
 #[default_runtime(crate::Wry, wry)]
 #[default_runtime(crate::Wry, wry)]
 pub struct Webview<R: Runtime> {
 pub struct Webview<R: Runtime> {
-  pub(crate) window: Window<R>,
+  window_label: Arc<Mutex<String>>,
+  /// The manager to associate this webview with.
+  pub(crate) manager: Arc<AppManager<R>>,
+  pub(crate) app_handle: AppHandle<R>,
   /// The webview created by the runtime.
   /// The webview created by the runtime.
   pub(crate) webview: DetachedWebview<EventLoopMessage, R>,
   pub(crate) webview: DetachedWebview<EventLoopMessage, R>,
 }
 }
@@ -802,7 +805,7 @@ pub struct Webview<R: Runtime> {
 impl<R: Runtime> std::fmt::Debug for Webview<R> {
 impl<R: Runtime> std::fmt::Debug for Webview<R> {
   fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
   fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     f.debug_struct("Window")
     f.debug_struct("Window")
-      .field("window", &self.window)
+      .field("window_label", &self.window_label)
       .field("webview", &self.webview)
       .field("webview", &self.webview)
       .finish()
       .finish()
   }
   }
@@ -811,7 +814,9 @@ impl<R: Runtime> std::fmt::Debug for Webview<R> {
 impl<R: Runtime> Clone for Webview<R> {
 impl<R: Runtime> Clone for Webview<R> {
   fn clone(&self) -> Self {
   fn clone(&self) -> Self {
     Self {
     Self {
-      window: self.window.clone(),
+      window_label: self.window_label.clone(),
+      manager: self.manager.clone(),
+      app_handle: self.app_handle.clone(),
       webview: self.webview.clone(),
       webview: self.webview.clone(),
     }
     }
   }
   }
@@ -836,7 +841,12 @@ impl<R: Runtime> PartialEq for Webview<R> {
 impl<R: Runtime> Webview<R> {
 impl<R: Runtime> Webview<R> {
   /// Create a new webview that is attached to the window.
   /// Create a new webview that is attached to the window.
   pub(crate) fn new(window: Window<R>, webview: DetachedWebview<EventLoopMessage, R>) -> Self {
   pub(crate) fn new(window: Window<R>, webview: DetachedWebview<EventLoopMessage, R>) -> Self {
-    Self { window, webview }
+    Self {
+      window_label: Arc::new(Mutex::new(window.label().into())),
+      manager: window.manager.clone(),
+      app_handle: window.app_handle.clone(),
+      webview,
+    }
   }
   }
 
 
   /// Initializes a webview builder with the given window label and URL to load on the webview.
   /// Initializes a webview builder with the given window label and URL to load on the webview.
@@ -883,8 +893,9 @@ impl<R: Runtime> Webview<R> {
 
 
   /// Closes this webview.
   /// Closes this webview.
   pub fn close(&self) -> crate::Result<()> {
   pub fn close(&self) -> crate::Result<()> {
-    if self.window.is_webview_window {
-      self.window.close()
+    let window = self.window();
+    if window.is_webview_window {
+      window.close()
     } else {
     } else {
       self.webview.dispatcher.close()?;
       self.webview.dispatcher.close()?;
       self.manager().on_webview_close(self.label());
       self.manager().on_webview_close(self.label());
@@ -894,8 +905,9 @@ impl<R: Runtime> Webview<R> {
 
 
   /// Resizes this webview.
   /// Resizes this webview.
   pub fn set_size<S: Into<Size>>(&self, size: S) -> crate::Result<()> {
   pub fn set_size<S: Into<Size>>(&self, size: S) -> crate::Result<()> {
-    if self.window.is_webview_window {
-      self.window.set_size(size.into())
+    let window = self.window();
+    if window.is_webview_window {
+      window.set_size(size.into())
     } else {
     } else {
       self
       self
         .webview
         .webview
@@ -907,8 +919,9 @@ impl<R: Runtime> Webview<R> {
 
 
   /// Sets this webviews's position.
   /// Sets this webviews's position.
   pub fn set_position<Pos: Into<Position>>(&self, position: Pos) -> crate::Result<()> {
   pub fn set_position<Pos: Into<Position>>(&self, position: Pos) -> crate::Result<()> {
-    if self.window.is_webview_window {
-      self.window.set_position(position.into())
+    let window = self.window();
+    if window.is_webview_window {
+      window.set_position(position.into())
     } else {
     } else {
       self
       self
         .webview
         .webview
@@ -923,13 +936,23 @@ impl<R: Runtime> Webview<R> {
     self.webview.dispatcher.set_focus().map_err(Into::into)
     self.webview.dispatcher.set_focus().map_err(Into::into)
   }
   }
 
 
+  /// Move the webview to the given window.
+  pub fn reparent(&self, window: &Window<R>) -> crate::Result<()> {
+    let current_window = self.window();
+    if !current_window.is_webview_window {
+      self.webview.dispatcher.reparent(window.window.id)?;
+    }
+    Ok(())
+  }
+
   /// Returns the webview position.
   /// Returns the webview position.
   ///
   ///
   /// - For child webviews, returns the position of the top-left hand corner of the webviews's client area relative to the top-left hand corner of the parent window.
   /// - For child webviews, returns the position of the top-left hand corner of the webviews's client area relative to the top-left hand corner of the parent window.
   /// - For webview window, returns the inner position of the window.
   /// - For webview window, returns the inner position of the window.
   pub fn position(&self) -> crate::Result<PhysicalPosition<i32>> {
   pub fn position(&self) -> crate::Result<PhysicalPosition<i32>> {
-    if self.window.is_webview_window {
-      self.window.inner_position()
+    let window = self.window();
+    if window.is_webview_window {
+      window.inner_position()
     } else {
     } else {
       self.webview.dispatcher.position().map_err(Into::into)
       self.webview.dispatcher.position().map_err(Into::into)
     }
     }
@@ -937,8 +960,9 @@ impl<R: Runtime> Webview<R> {
 
 
   /// Returns the physical size of the webviews's client area.
   /// Returns the physical size of the webviews's client area.
   pub fn size(&self) -> crate::Result<PhysicalSize<u32>> {
   pub fn size(&self) -> crate::Result<PhysicalSize<u32>> {
-    if self.window.is_webview_window {
-      self.window.inner_size()
+    let window = self.window();
+    if window.is_webview_window {
+      window.inner_size()
     } else {
     } else {
       self.webview.dispatcher.size().map_err(Into::into)
       self.webview.dispatcher.size().map_err(Into::into)
     }
     }
@@ -948,8 +972,11 @@ impl<R: Runtime> Webview<R> {
 /// Webview APIs.
 /// Webview APIs.
 impl<R: Runtime> Webview<R> {
 impl<R: Runtime> Webview<R> {
   /// The window that is hosting this webview.
   /// The window that is hosting this webview.
-  pub fn window(&self) -> &Window<R> {
-    &self.window
+  pub fn window(&self) -> Window<R> {
+    self
+      .manager
+      .get_window(&self.window_label.lock().unwrap())
+      .expect("could not locate webview parent window")
   }
   }
 
 
   /// Executes a closure, providing it with the webview handle that is specific to the current platform.
   /// Executes a closure, providing it with the webview handle that is specific to the current platform.
@@ -1099,7 +1126,7 @@ fn main() {
     );
     );
 
 
     #[cfg(mobile)]
     #[cfg(mobile)]
-    let app_handle = self.window.app_handle.clone();
+    let app_handle = self.app_handle.clone();
 
 
     let message = InvokeMessage::new(
     let message = InvokeMessage::new(
       self,
       self,
@@ -1415,7 +1442,7 @@ tauri::Builder::default()
   where
   where
     F: Fn(Event) + Send + 'static,
     F: Fn(Event) + Send + 'static,
   {
   {
-    self.window.manager.listen(
+    self.manager.listen(
       event.into(),
       event.into(),
       EventTarget::Webview {
       EventTarget::Webview {
         label: self.label().to_string(),
         label: self.label().to_string(),
@@ -1454,7 +1481,7 @@ tauri::Builder::default()
   "####
   "####
   )]
   )]
   pub fn unlisten(&self, id: EventId) {
   pub fn unlisten(&self, id: EventId) {
-    self.window.manager.unlisten(id)
+    self.manager.unlisten(id)
   }
   }
 
 
   /// Listen to an event on this webview only once.
   /// Listen to an event on this webview only once.
@@ -1464,7 +1491,7 @@ tauri::Builder::default()
   where
   where
     F: FnOnce(Event) + Send + 'static,
     F: FnOnce(Event) + Send + 'static,
   {
   {
-    self.window.manager.once(
+    self.manager.once(
       event.into(),
       event.into(),
       EventTarget::Webview {
       EventTarget::Webview {
         label: self.label().to_string(),
         label: self.label().to_string(),
@@ -1478,19 +1505,19 @@ impl<R: Runtime> Manager<R> for Webview<R> {}
 
 
 impl<R: Runtime> ManagerBase<R> for Webview<R> {
 impl<R: Runtime> ManagerBase<R> for Webview<R> {
   fn manager(&self) -> &AppManager<R> {
   fn manager(&self) -> &AppManager<R> {
-    &self.window.manager
+    &self.manager
   }
   }
 
 
   fn manager_owned(&self) -> Arc<AppManager<R>> {
   fn manager_owned(&self) -> Arc<AppManager<R>> {
-    self.window.manager.clone()
+    self.manager.clone()
   }
   }
 
 
   fn runtime(&self) -> RuntimeOrDispatch<'_, R> {
   fn runtime(&self) -> RuntimeOrDispatch<'_, R> {
-    self.window.app_handle.runtime()
+    self.app_handle.runtime()
   }
   }
 
 
   fn managed_app_handle(&self) -> &AppHandle<R> {
   fn managed_app_handle(&self) -> &AppHandle<R> {
-    &self.window.app_handle
+    &self.app_handle
   }
   }
 }
 }
 
 

+ 14 - 0
core/tauri/src/webview/plugin.rs

@@ -159,6 +159,19 @@ mod desktop_commands {
   setter!(set_webview_position, set_position, Position);
   setter!(set_webview_position, set_position, Position);
   setter!(set_webview_focus, set_focus);
   setter!(set_webview_focus, set_focus);
 
 
+  #[command(root = "crate")]
+  pub async fn reparent<R: Runtime>(
+    webview: crate::Webview<R>,
+    label: Option<String>,
+    window: String,
+  ) -> crate::Result<()> {
+    let webview = get_webview(webview, label)?;
+    if let Some(window) = webview.manager.get_window(&window) {
+      webview.reparent(&window)?;
+    }
+    Ok(())
+  }
+
   #[cfg(any(debug_assertions, feature = "devtools"))]
   #[cfg(any(debug_assertions, feature = "devtools"))]
   #[command(root = "crate")]
   #[command(root = "crate")]
   pub async fn internal_toggle_devtools<R: Runtime>(
   pub async fn internal_toggle_devtools<R: Runtime>(
@@ -227,6 +240,7 @@ pub fn init<R: Runtime>() -> TauriPlugin<R> {
             desktop_commands::set_webview_position,
             desktop_commands::set_webview_position,
             desktop_commands::set_webview_focus,
             desktop_commands::set_webview_focus,
             desktop_commands::print,
             desktop_commands::print,
+            desktop_commands::reparent,
             #[cfg(any(debug_assertions, feature = "devtools"))]
             #[cfg(any(debug_assertions, feature = "devtools"))]
             desktop_commands::internal_toggle_devtools,
             desktop_commands::internal_toggle_devtools,
           ]);
           ]);

+ 8 - 4
core/tauri/src/webview/webview_window.rs

@@ -572,7 +572,7 @@ impl<'a, R: Runtime, M: Manager<R>> WebviewWindowBuilder<'a, R, M> {
   /// - **Linux**: This makes the new window transient for parent, see <https://docs.gtk.org/gtk3/method.Window.set_transient_for.html>
   /// - **Linux**: This makes the new window transient for parent, see <https://docs.gtk.org/gtk3/method.Window.set_transient_for.html>
   /// - **macOS**: This adds the window as a child of parent, see <https://developer.apple.com/documentation/appkit/nswindow/1419152-addchildwindow?language=objc>
   /// - **macOS**: This adds the window as a child of parent, see <https://developer.apple.com/documentation/appkit/nswindow/1419152-addchildwindow?language=objc>
   pub fn parent(mut self, parent: &WebviewWindow<R>) -> crate::Result<Self> {
   pub fn parent(mut self, parent: &WebviewWindow<R>) -> crate::Result<Self> {
-    self.window_builder = self.window_builder.parent(&parent.webview.window)?;
+    self.window_builder = self.window_builder.parent(&parent.webview.window())?;
     Ok(self)
     Ok(self)
   }
   }
 
 
@@ -586,7 +586,7 @@ impl<'a, R: Runtime, M: Manager<R>> WebviewWindowBuilder<'a, R, M> {
   /// For more information, see <https://docs.microsoft.com/en-us/windows/win32/winmsg/window-features#owned-windows>
   /// For more information, see <https://docs.microsoft.com/en-us/windows/win32/winmsg/window-features#owned-windows>
   #[cfg(windows)]
   #[cfg(windows)]
   pub fn owner(mut self, owner: &WebviewWindow<R>) -> crate::Result<Self> {
   pub fn owner(mut self, owner: &WebviewWindow<R>) -> crate::Result<Self> {
-    self.window_builder = self.window_builder.owner(&owner.webview.window)?;
+    self.window_builder = self.window_builder.owner(&owner.webview.window())?;
     Ok(self)
     Ok(self)
   }
   }
 
 
@@ -638,7 +638,9 @@ impl<'a, R: Runtime, M: Manager<R>> WebviewWindowBuilder<'a, R, M> {
     target_os = "openbsd"
     target_os = "openbsd"
   ))]
   ))]
   pub fn transient_for(mut self, parent: &WebviewWindow<R>) -> crate::Result<Self> {
   pub fn transient_for(mut self, parent: &WebviewWindow<R>) -> crate::Result<Self> {
-    self.window_builder = self.window_builder.transient_for(&parent.webview.window)?;
+    self.window_builder = self
+      .window_builder
+      .transient_for(&parent.webview.window())?;
     Ok(self)
     Ok(self)
   }
   }
 
 
@@ -868,7 +870,9 @@ impl<R: Runtime> raw_window_handle::HasWindowHandle for WebviewWindow<R> {
   fn window_handle(
   fn window_handle(
     &self,
     &self,
   ) -> std::result::Result<raw_window_handle::WindowHandle<'_>, raw_window_handle::HandleError> {
   ) -> std::result::Result<raw_window_handle::WindowHandle<'_>, raw_window_handle::HandleError> {
-    self.webview.window().window_handle()
+    Ok(unsafe {
+      raw_window_handle::WindowHandle::borrow_raw(self.webview.window().window_handle()?.as_raw())
+    })
   }
   }
 }
 }
 
 

+ 2 - 2
core/tauri/src/window/mod.rs

@@ -333,7 +333,7 @@ tauri::Builder::default()
       .webviews_lock()
       .webviews_lock()
       .values()
       .values()
       .map(|w| WebviewLabelDef {
       .map(|w| WebviewLabelDef {
-        window_label: w.window.label().to_string(),
+        window_label: w.window().label().to_string(),
         label: w.label().to_string(),
         label: w.label().to_string(),
       })
       })
       .collect::<Vec<_>>();
       .collect::<Vec<_>>();
@@ -988,7 +988,7 @@ impl<R: Runtime> Window<R> {
       .webview
       .webview
       .webviews_lock()
       .webviews_lock()
       .values()
       .values()
-      .filter(|w| w.window() == self)
+      .filter(|w| &w.window() == self)
       .cloned()
       .cloned()
       .collect()
       .collect()
   }
   }

+ 18 - 0
tooling/api/src/webview.ts

@@ -31,6 +31,7 @@ import {
 } from './event'
 } from './event'
 import { invoke } from './core'
 import { invoke } from './core'
 import { Window, getCurrent as getCurrentWindow } from './window'
 import { Window, getCurrent as getCurrentWindow } from './window'
+import { WebviewWindow } from './webviewWindow'
 
 
 interface FileDropPayload {
 interface FileDropPayload {
   paths: string[]
   paths: string[]
@@ -474,6 +475,23 @@ class Webview {
     })
     })
   }
   }
 
 
+  /**
+   * Moves this webview to the given label.
+   * @example
+   * ```typescript
+   * import { getCurrent } from '@tauri-apps/api/webview';
+   * await getCurrent().reparent('other-window');
+   * ```
+   *
+   * @returns A promise indicating the success or failure of the operation.
+   */
+  async reparent(window: Window | WebviewWindow | string): Promise<void> {
+    return invoke('plugin:webview|set_webview_focus', {
+      label: this.label,
+      window: typeof window === 'string' ? window : window.label
+    })
+  }
+
   // Listeners
   // Listeners
 
 
   /**
   /**

部分文件因为文件数量过多而无法显示