Skip to content

Commit 46de49a

Browse files
authored
feat(core): always use child webviews on the unstable feature (#9059)
* feat(core): always use child webviews on the unstable feature * fmt
1 parent b4ffbe7 commit 46de49a

File tree

10 files changed

+113
-71
lines changed

10 files changed

+113
-71
lines changed

.changes/set-auto-resize.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"tauri": patch:feat
3+
"tauri-runtime": patch:feat
4+
"tauri-runtime-wry": patch:feat
5+
---
6+
7+
Added `set_auto_resize` method for the webview.

.changes/unstable-child-webview.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"tauri": patch:enhance
3+
"tauri-runtime-wry": patch:enhance
4+
---
5+
6+
When using the `unstable` feature flag, `WebviewWindow` will internally use the child webview interface for flexibility.

core/tauri-runtime-wry/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,4 @@ objc-exception = [ "wry/objc-exception" ]
5252
linux-protocol-body = [ "wry/linux-body", "webkit2gtk/v2_40" ]
5353
tracing = [ "dep:tracing", "wry/tracing" ]
5454
macos-proxy = [ "wry/mac-proxy" ]
55+
unstable = [ ]

core/tauri-runtime-wry/src/lib.rs

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,6 +1174,7 @@ pub enum WebviewMessage {
11741174
SetSize(Size),
11751175
SetFocus,
11761176
Reparent(WindowId),
1177+
SetAutoResize(bool),
11771178
// Getters
11781179
Url(Sender<Url>),
11791180
Position(Sender<PhysicalPosition<i32>>),
@@ -1384,6 +1385,17 @@ impl<T: UserEvent> WebviewDispatch<T> for WryWebviewDispatcher<T> {
13841385
Ok(())
13851386
}
13861387

1388+
fn set_auto_resize(&self, auto_resize: bool) -> Result<()> {
1389+
send_user_message(
1390+
&self.context,
1391+
Message::Webview(
1392+
*self.window_id.lock().unwrap(),
1393+
self.webview_id,
1394+
WebviewMessage::SetAutoResize(auto_resize),
1395+
),
1396+
)
1397+
}
1398+
13871399
#[cfg(all(feature = "tracing", not(target_os = "android")))]
13881400
fn eval_script<S: Into<String>>(&self, script: S) -> Result<()> {
13891401
// use a channel so the EvaluateScript task uses the current span as parent
@@ -1883,7 +1895,7 @@ pub struct WebviewWrapper {
18831895
webview_event_listeners: WebviewEventListeners,
18841896
// the key of the WebContext if it's not shared
18851897
context_key: Option<PathBuf>,
1886-
bounds: Option<Arc<Mutex<WebviewBounds>>>,
1898+
bounds: Arc<Mutex<Option<WebviewBounds>>>,
18871899
}
18881900

18891901
impl Deref for WebviewWrapper {
@@ -2824,11 +2836,10 @@ fn handle_user_message<T: UserEvent>(
28242836
bounds.width = size.width;
28252837
bounds.height = size.height;
28262838

2827-
if let Some(b) = &webview.bounds {
2839+
if let Some(b) = &mut *webview.bounds.lock().unwrap() {
28282840
let window_size = window.inner_size().to_logical::<f32>(window.scale_factor());
2829-
let mut bounds = b.lock().unwrap();
2830-
bounds.width_rate = size.width as f32 / window_size.width;
2831-
bounds.height_rate = size.height as f32 / window_size.height;
2841+
b.width_rate = size.width as f32 / window_size.width;
2842+
b.height_rate = size.height as f32 / window_size.height;
28322843
}
28332844

28342845
webview.set_bounds(bounds);
@@ -2839,12 +2850,10 @@ fn handle_user_message<T: UserEvent>(
28392850
bounds.x = position.x;
28402851
bounds.y = position.y;
28412852

2842-
if let Some(b) = &webview.bounds {
2853+
if let Some(b) = &mut *webview.bounds.lock().unwrap() {
28432854
let window_size = window.inner_size().to_logical::<f32>(window.scale_factor());
2844-
let mut bounds = b.lock().unwrap();
2845-
2846-
bounds.x_rate = position.x as f32 / window_size.width;
2847-
bounds.y_rate = position.y as f32 / window_size.height;
2855+
b.x_rate = position.x as f32 / window_size.width;
2856+
b.y_rate = position.y as f32 / window_size.height;
28482857
}
28492858

28502859
webview.set_bounds(bounds);
@@ -2868,6 +2877,20 @@ fn handle_user_message<T: UserEvent>(
28682877
WebviewMessage::SetFocus => {
28692878
webview.focus();
28702879
}
2880+
WebviewMessage::SetAutoResize(auto_resize) => {
2881+
let bounds = webview.bounds();
2882+
let window_size = window.inner_size().to_logical::<f32>(window.scale_factor());
2883+
*webview.bounds.lock().unwrap() = if auto_resize {
2884+
Some(WebviewBounds {
2885+
x_rate: (bounds.x as f32) / window_size.width,
2886+
y_rate: (bounds.y as f32) / window_size.height,
2887+
width_rate: (bounds.width as f32) / window_size.width,
2888+
height_rate: (bounds.height as f32) / window_size.height,
2889+
})
2890+
} else {
2891+
None
2892+
};
2893+
}
28712894
WebviewMessage::WithWebview(f) => {
28722895
#[cfg(any(
28732896
target_os = "linux",
@@ -3186,8 +3209,7 @@ fn handle_event_loop<T: UserEvent>(
31863209
{
31873210
let size = size.to_logical::<f32>(window.scale_factor());
31883211
for webview in webviews {
3189-
if let Some(bounds) = &webview.bounds {
3190-
let b = bounds.lock().unwrap();
3212+
if let Some(b) = &*webview.bounds.lock().unwrap() {
31913213
webview.set_bounds(wry::Rect {
31923214
x: (size.width * b.x_rate) as i32,
31933215
y: (size.height * b.y_rate) as i32,
@@ -3427,6 +3449,9 @@ fn create_window<T: UserEvent, F: Fn(RawWindow) + Send + 'static>(
34273449

34283450
if let Some(webview) = webview {
34293451
webviews.push(create_webview(
3452+
#[cfg(feature = "unstable")]
3453+
WebviewKind::WindowChild,
3454+
#[cfg(not(feature = "unstable"))]
34303455
WebviewKind::WindowContent,
34313456
&window,
34323457
Arc::new(Mutex::new(window_id)),
@@ -3622,6 +3647,24 @@ fn create_webview<T: UserEvent>(
36223647
None
36233648
}
36243649
} else {
3650+
#[cfg(feature = "unstable")]
3651+
{
3652+
let window_size = window.inner_size().to_logical::<u32>(window.scale_factor());
3653+
3654+
webview_builder = webview_builder.with_bounds(wry::Rect {
3655+
x: 0,
3656+
y: 0,
3657+
width: window_size.width,
3658+
height: window_size.height,
3659+
});
3660+
Some(WebviewBounds {
3661+
x_rate: 0.,
3662+
y_rate: 0.,
3663+
width_rate: 1.,
3664+
height_rate: 1.,
3665+
})
3666+
}
3667+
#[cfg(not(feature = "unstable"))]
36253668
None
36263669
};
36273670

@@ -3829,7 +3872,7 @@ fn create_webview<T: UserEvent>(
38293872
} else {
38303873
web_context_key
38313874
},
3832-
bounds: webview_bounds.map(|b| Arc::new(Mutex::new(b))),
3875+
bounds: Arc::new(Mutex::new(webview_bounds)),
38333876
})
38343877
}
38353878

core/tauri-runtime/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,9 @@ pub trait WebviewDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + '
452452

453453
/// Moves the webview to the given window.
454454
fn reparent(&self, window_id: WindowId) -> Result<()>;
455+
456+
/// Sets whether the webview should automatically grow and shrink its size and position when the parent window resizes.
457+
fn set_auto_resize(&self, auto_resize: bool) -> Result<()>;
455458
}
456459

457460
/// Window dispatcher. A thread-safe handle to the window APIs.

core/tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ http-range = "0.1.5"
126126

127127
[features]
128128
default = [ "wry", "compression", "objc-exception", "common-controls-v6" ]
129-
unstable = [ ]
129+
unstable = [ "tauri-runtime-wry/unstable" ]
130130
common-controls-v6 = [ "tray-icon?/common-controls-v6", "muda/common-controls-v6" ]
131131
tray-icon = [ "dep:tray-icon" ]
132132
tracing = [

core/tauri/src/manager/window.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ impl<R: Runtime> WindowManager<R> {
7777
&self,
7878
app_handle: AppHandle<R>,
7979
window: DetachedWindow<EventLoopMessage, R>,
80-
is_webview_window: bool,
8180
#[cfg(desktop)] menu: Option<crate::window::WindowMenu<R>>,
8281
) -> Window<R> {
8382
let window = Window::new(
@@ -86,7 +85,6 @@ impl<R: Runtime> WindowManager<R> {
8685
app_handle,
8786
#[cfg(desktop)]
8887
menu,
89-
is_webview_window,
9088
);
9189

9290
let window_ = window.clone();

core/tauri/src/test/mock_runtime.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,10 @@ impl<T: UserEvent> WebviewDispatch<T> for MockWebviewDispatcher {
544544
fn reparent(&self, window_id: WindowId) -> Result<()> {
545545
Ok(())
546546
}
547+
548+
fn set_auto_resize(&self, auto_resize: bool) -> Result<()> {
549+
Ok(())
550+
}
547551
}
548552

549553
impl<T: UserEvent> WindowDispatch<T> for MockWindowDispatcher {

core/tauri/src/webview/mod.rs

Lines changed: 34 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -896,42 +896,27 @@ impl<R: Runtime> Webview<R> {
896896

897897
/// Closes this webview.
898898
pub fn close(&self) -> crate::Result<()> {
899-
let window = self.window();
900-
if window.is_webview_window() {
901-
window.close()
902-
} else {
903-
self.webview.dispatcher.close()?;
904-
self.manager().on_webview_close(self.label());
905-
Ok(())
906-
}
899+
self.webview.dispatcher.close()?;
900+
self.manager().on_webview_close(self.label());
901+
Ok(())
907902
}
908903

909904
/// Resizes this webview.
910905
pub fn set_size<S: Into<Size>>(&self, size: S) -> crate::Result<()> {
911-
let window = self.window();
912-
if window.is_webview_window() {
913-
window.set_size(size.into())
914-
} else {
915-
self
916-
.webview
917-
.dispatcher
918-
.set_size(size.into())
919-
.map_err(Into::into)
920-
}
906+
self
907+
.webview
908+
.dispatcher
909+
.set_size(size.into())
910+
.map_err(Into::into)
921911
}
922912

923913
/// Sets this webviews's position.
924914
pub fn set_position<Pos: Into<Position>>(&self, position: Pos) -> crate::Result<()> {
925-
let window = self.window();
926-
if window.is_webview_window() {
927-
window.set_position(position.into())
928-
} else {
929-
self
930-
.webview
931-
.dispatcher
932-
.set_position(position.into())
933-
.map_err(Into::into)
934-
}
915+
self
916+
.webview
917+
.dispatcher
918+
.set_position(position.into())
919+
.map_err(Into::into)
935920
}
936921

937922
/// Focus the webview.
@@ -941,37 +926,39 @@ impl<R: Runtime> Webview<R> {
941926

942927
/// Move the webview to the given window.
943928
pub fn reparent(&self, window: &Window<R>) -> crate::Result<()> {
944-
let current_window = self.window();
945-
if current_window.is_webview_window() || window.is_webview_window() {
946-
Err(crate::Error::CannotReparentWebviewWindow)
947-
} else {
948-
self.webview.dispatcher.reparent(window.window.id)?;
949-
*self.window_label.lock().unwrap() = window.label().to_string();
950-
Ok(())
929+
#[cfg(not(feature = "unstable"))]
930+
{
931+
let current_window = self.window();
932+
if current_window.is_webview_window() || window.is_webview_window() {
933+
return Err(crate::Error::CannotReparentWebviewWindow);
934+
}
951935
}
936+
937+
self.webview.dispatcher.reparent(window.window.id)?;
938+
*self.window_label.lock().unwrap() = window.label().to_string();
939+
Ok(())
940+
}
941+
942+
/// Sets whether the webview should automatically grow and shrink its size and position when the parent window resizes.
943+
pub fn set_auto_resize(&self, auto_resize: bool) -> crate::Result<()> {
944+
self
945+
.webview
946+
.dispatcher
947+
.set_auto_resize(auto_resize)
948+
.map_err(Into::into)
952949
}
953950

954951
/// Returns the webview position.
955952
///
956953
/// - 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.
957954
/// - For webview window, returns the inner position of the window.
958955
pub fn position(&self) -> crate::Result<PhysicalPosition<i32>> {
959-
let window = self.window();
960-
if window.is_webview_window() {
961-
window.inner_position()
962-
} else {
963-
self.webview.dispatcher.position().map_err(Into::into)
964-
}
956+
self.webview.dispatcher.position().map_err(Into::into)
965957
}
966958

967959
/// Returns the physical size of the webviews's client area.
968960
pub fn size(&self) -> crate::Result<PhysicalSize<u32>> {
969-
let window = self.window();
970-
if window.is_webview_window() {
971-
window.inner_size()
972-
} else {
973-
self.webview.dispatcher.size().map_err(Into::into)
974-
}
961+
self.webview.dispatcher.size().map_err(Into::into)
975962
}
976963
}
977964

core/tauri/src/window/mod.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,6 @@ tauri::Builder::default()
404404
let window = app_manager.window.attach_window(
405405
self.manager.app_handle().clone(),
406406
detached_window.clone(),
407-
detached_window.webview.is_some(),
408407
#[cfg(desktop)]
409408
window_menu,
410409
);
@@ -865,8 +864,6 @@ pub struct Window<R: Runtime> {
865864
// The menu set for this window
866865
#[cfg(desktop)]
867866
pub(crate) menu: Arc<std::sync::Mutex<Option<WindowMenu<R>>>>,
868-
/// Whether this window is a Webview window (hosts only a single webview) or a container for multiple webviews
869-
is_webview_window: bool,
870867
}
871868

872869
impl<R: Runtime> std::fmt::Debug for Window<R> {
@@ -875,7 +872,6 @@ impl<R: Runtime> std::fmt::Debug for Window<R> {
875872
.field("window", &self.window)
876873
.field("manager", &self.manager)
877874
.field("app_handle", &self.app_handle)
878-
.field("is_webview_window", &self.is_webview_window)
879875
.finish()
880876
}
881877
}
@@ -896,7 +892,6 @@ impl<R: Runtime> Clone for Window<R> {
896892
app_handle: self.app_handle.clone(),
897893
#[cfg(desktop)]
898894
menu: self.menu.clone(),
899-
is_webview_window: self.is_webview_window,
900895
}
901896
}
902897
}
@@ -951,15 +946,13 @@ impl<R: Runtime> Window<R> {
951946
window: DetachedWindow<EventLoopMessage, R>,
952947
app_handle: AppHandle<R>,
953948
#[cfg(desktop)] menu: Option<WindowMenu<R>>,
954-
is_webview_window: bool,
955949
) -> Self {
956950
Self {
957951
window,
958952
manager,
959953
app_handle,
960954
#[cfg(desktop)]
961955
menu: Arc::new(std::sync::Mutex::new(menu)),
962-
is_webview_window,
963956
}
964957
}
965958

@@ -1007,7 +1000,7 @@ impl<R: Runtime> Window<R> {
10071000
}
10081001

10091002
pub(crate) fn is_webview_window(&self) -> bool {
1010-
self.is_webview_window
1003+
self.webviews().iter().all(|w| w.label() == self.label())
10111004
}
10121005

10131006
/// Runs the given closure on the main thread.

0 commit comments

Comments
 (0)