Skip to content

Commit d69b1cf

Browse files
authored
feat(api): allow mananing windows created on JS (#2154)
1 parent af634db commit d69b1cf

8 files changed

Lines changed: 499 additions & 4865 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"api": patch
3+
---
4+
5+
Allow manipulating a spawned window directly using `WebviewWindow`, which now extends `WindowManager`.

core/tauri/scripts/bundle.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/tauri/src/endpoints/window.rs

Lines changed: 106 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::{
1111
window::dpi::{Position, Size},
1212
UserAttentionType,
1313
},
14-
Params, Window,
14+
Manager, Params, Window,
1515
};
1616
use serde::Deserialize;
1717

@@ -34,13 +34,10 @@ impl From<IconDto> for Icon {
3434
}
3535
}
3636

37-
/// The API descriptor.
37+
/// Window management API descriptor.
3838
#[derive(Deserialize)]
39-
#[serde(tag = "cmd", content = "data", rename_all = "camelCase")]
40-
pub enum Cmd {
41-
CreateWebview {
42-
options: WindowConfig,
43-
},
39+
#[serde(tag = "type", content = "payload", rename_all = "camelCase")]
40+
pub enum WindowManagerCmd {
4441
// Getters
4542
ScaleFactor,
4643
InnerPosition,
@@ -85,6 +82,19 @@ pub enum Cmd {
8582
Print,
8683
}
8784

85+
/// The API descriptor.
86+
#[derive(Deserialize)]
87+
#[serde(tag = "cmd", content = "data", rename_all = "camelCase")]
88+
pub enum Cmd {
89+
CreateWebview {
90+
options: WindowConfig,
91+
},
92+
Manage {
93+
label: Option<String>,
94+
cmd: WindowManagerCmd,
95+
},
96+
}
97+
8898
#[cfg(window_create)]
8999
#[derive(Clone, serde::Serialize)]
90100
struct WindowCreatedEvent {
@@ -94,88 +104,99 @@ struct WindowCreatedEvent {
94104
impl Cmd {
95105
#[allow(dead_code)]
96106
pub async fn run<P: Params>(self, window: Window<P>) -> crate::Result<InvokeResponse> {
97-
if cfg!(not(window_all)) {
98-
Err(crate::Error::ApiNotAllowlisted("window > all".to_string()))
99-
} else {
100-
match self {
101-
#[cfg(not(window_create))]
102-
Self::CreateWebview { .. } => {
103-
return Err(crate::Error::ApiNotAllowlisted(
104-
"window > create".to_string(),
105-
));
106-
}
107-
#[cfg(window_create)]
108-
Self::CreateWebview { options } => {
109-
let mut window = window;
110-
// Panic if the user's `Tag` type decided to return an error while parsing.
111-
let label: P::Label = options.label.parse().unwrap_or_else(|_| {
112-
panic!(
113-
"Window module received unknown window label: {}",
114-
options.label
115-
)
116-
});
107+
match self {
108+
#[cfg(not(window_create))]
109+
Self::CreateWebview { .. } => {
110+
return Err(crate::Error::ApiNotAllowlisted(
111+
"window > create".to_string(),
112+
));
113+
}
114+
#[cfg(window_create)]
115+
Self::CreateWebview { options } => {
116+
let mut window = window;
117+
// Panic if the user's `Tag` type decided to return an error while parsing.
118+
let label: P::Label = options.label.parse().unwrap_or_else(|_| {
119+
panic!(
120+
"Window module received unknown window label: {}",
121+
options.label
122+
)
123+
});
117124

118-
let url = options.url.clone();
125+
let url = options.url.clone();
126+
window
127+
.create_window(label.clone(), url, |_, webview_attributes| {
128+
(
129+
<<<P::Runtime as Runtime>::Dispatcher as Dispatch>::WindowBuilder>::with_config(
130+
options,
131+
),
132+
webview_attributes,
133+
)
134+
})?
135+
.emit_others(
136+
&crate::manager::tauri_event::<P::Event>("tauri://window-created"),
137+
Some(WindowCreatedEvent {
138+
label: label.to_string(),
139+
}),
140+
)?;
141+
}
142+
Self::Manage { label, cmd } => {
143+
let window = if let Some(l) = label {
144+
window
145+
.get_window(&l.parse().unwrap_or_else(|_| panic!("invalid label")))
146+
.ok_or(crate::Error::WebviewNotFound)?
147+
} else {
119148
window
120-
.create_window(label.clone(), url, |_, webview_attributes| {
121-
(
122-
<<<P::Runtime as Runtime>::Dispatcher as Dispatch>::WindowBuilder>::with_config(
123-
options,
124-
),
125-
webview_attributes,
126-
)
127-
})?
128-
.emit_others(
129-
&crate::manager::tauri_event::<P::Event>("tauri://window-created"),
130-
Some(WindowCreatedEvent {
131-
label: label.to_string(),
132-
}),
133-
)?;
149+
};
150+
match cmd {
151+
// Getters
152+
WindowManagerCmd::ScaleFactor => return Ok(window.scale_factor()?.into()),
153+
WindowManagerCmd::InnerPosition => return Ok(window.inner_position()?.into()),
154+
WindowManagerCmd::OuterPosition => return Ok(window.outer_position()?.into()),
155+
WindowManagerCmd::InnerSize => return Ok(window.inner_size()?.into()),
156+
WindowManagerCmd::OuterSize => return Ok(window.outer_size()?.into()),
157+
WindowManagerCmd::IsFullscreen => return Ok(window.is_fullscreen()?.into()),
158+
WindowManagerCmd::IsMaximized => return Ok(window.is_maximized()?.into()),
159+
WindowManagerCmd::IsDecorated => return Ok(window.is_decorated()?.into()),
160+
WindowManagerCmd::IsResizable => return Ok(window.is_resizable()?.into()),
161+
WindowManagerCmd::IsVisible => return Ok(window.is_visible()?.into()),
162+
WindowManagerCmd::CurrentMonitor => return Ok(window.current_monitor()?.into()),
163+
WindowManagerCmd::PrimaryMonitor => return Ok(window.primary_monitor()?.into()),
164+
WindowManagerCmd::AvailableMonitors => return Ok(window.available_monitors()?.into()),
165+
// Setters
166+
WindowManagerCmd::Center => window.center()?,
167+
WindowManagerCmd::RequestUserAttention(request_type) => {
168+
window.request_user_attention(request_type)?
169+
}
170+
WindowManagerCmd::SetResizable(resizable) => window.set_resizable(resizable)?,
171+
WindowManagerCmd::SetTitle(title) => window.set_title(&title)?,
172+
WindowManagerCmd::Maximize => window.maximize()?,
173+
WindowManagerCmd::Unmaximize => window.unmaximize()?,
174+
WindowManagerCmd::ToggleMaximize => match window.is_maximized()? {
175+
true => window.unmaximize()?,
176+
false => window.maximize()?,
177+
},
178+
WindowManagerCmd::Minimize => window.minimize()?,
179+
WindowManagerCmd::Unminimize => window.unminimize()?,
180+
WindowManagerCmd::Show => window.show()?,
181+
WindowManagerCmd::Hide => window.hide()?,
182+
WindowManagerCmd::Close => window.close()?,
183+
WindowManagerCmd::SetDecorations(decorations) => window.set_decorations(decorations)?,
184+
WindowManagerCmd::SetAlwaysOnTop(always_on_top) => {
185+
window.set_always_on_top(always_on_top)?
186+
}
187+
WindowManagerCmd::SetSize(size) => window.set_size(size)?,
188+
WindowManagerCmd::SetMinSize(size) => window.set_min_size(size)?,
189+
WindowManagerCmd::SetMaxSize(size) => window.set_max_size(size)?,
190+
WindowManagerCmd::SetPosition(position) => window.set_position(position)?,
191+
WindowManagerCmd::SetFullscreen(fullscreen) => window.set_fullscreen(fullscreen)?,
192+
WindowManagerCmd::SetFocus => window.set_focus()?,
193+
WindowManagerCmd::SetIcon { icon } => window.set_icon(icon.into())?,
194+
WindowManagerCmd::SetSkipTaskbar(skip) => window.set_skip_taskbar(skip)?,
195+
WindowManagerCmd::StartDragging => window.start_dragging()?,
196+
WindowManagerCmd::Print => window.print()?,
134197
}
135-
// Getters
136-
Self::ScaleFactor => return Ok(window.scale_factor()?.into()),
137-
Self::InnerPosition => return Ok(window.inner_position()?.into()),
138-
Self::OuterPosition => return Ok(window.outer_position()?.into()),
139-
Self::InnerSize => return Ok(window.inner_size()?.into()),
140-
Self::OuterSize => return Ok(window.outer_size()?.into()),
141-
Self::IsFullscreen => return Ok(window.is_fullscreen()?.into()),
142-
Self::IsMaximized => return Ok(window.is_maximized()?.into()),
143-
Self::IsDecorated => return Ok(window.is_decorated()?.into()),
144-
Self::IsResizable => return Ok(window.is_resizable()?.into()),
145-
Self::IsVisible => return Ok(window.is_visible()?.into()),
146-
Self::CurrentMonitor => return Ok(window.current_monitor()?.into()),
147-
Self::PrimaryMonitor => return Ok(window.primary_monitor()?.into()),
148-
Self::AvailableMonitors => return Ok(window.available_monitors()?.into()),
149-
// Setters
150-
Self::Center => window.center()?,
151-
Self::RequestUserAttention(request_type) => window.request_user_attention(request_type)?,
152-
Self::SetResizable(resizable) => window.set_resizable(resizable)?,
153-
Self::SetTitle(title) => window.set_title(&title)?,
154-
Self::Maximize => window.maximize()?,
155-
Self::Unmaximize => window.unmaximize()?,
156-
Self::ToggleMaximize => match window.is_maximized()? {
157-
true => window.unmaximize()?,
158-
false => window.maximize()?,
159-
},
160-
Self::Minimize => window.minimize()?,
161-
Self::Unminimize => window.unminimize()?,
162-
Self::Show => window.show()?,
163-
Self::Hide => window.hide()?,
164-
Self::Close => window.close()?,
165-
Self::SetDecorations(decorations) => window.set_decorations(decorations)?,
166-
Self::SetAlwaysOnTop(always_on_top) => window.set_always_on_top(always_on_top)?,
167-
Self::SetSize(size) => window.set_size(size)?,
168-
Self::SetMinSize(size) => window.set_min_size(size)?,
169-
Self::SetMaxSize(size) => window.set_max_size(size)?,
170-
Self::SetPosition(position) => window.set_position(position)?,
171-
Self::SetFullscreen(fullscreen) => window.set_fullscreen(fullscreen)?,
172-
Self::SetFocus => window.set_focus()?,
173-
Self::SetIcon { icon } => window.set_icon(icon.into())?,
174-
Self::SetSkipTaskbar(skip) => window.set_skip_taskbar(skip)?,
175-
Self::StartDragging => window.start_dragging()?,
176-
Self::Print => window.print()?,
177198
}
178-
Ok(().into())
179199
}
200+
Ok(().into())
180201
}
181202
}

core/tauri/src/manager.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -336,9 +336,9 @@ impl<P: Params> WindowManager<P> {
336336
.initialization_script(&self.initialization_script(&plugin_init, is_init_global))
337337
.initialization_script(&format!(
338338
r#"
339-
window.__TAURI__.__windows = {window_labels_array}.map(function (label) {{ return {{ label: label }} }});
340-
window.__TAURI__.__currentWindow = {{ label: {current_window_label} }}
341-
"#,
339+
window.__TAURI__.__windows = {window_labels_array}.map(function (label) {{ return {{ label: label }} }});
340+
window.__TAURI__.__currentWindow = {{ label: {current_window_label} }}
341+
"#,
342342
window_labels_array = tags_to_javascript_array(pending_labels)?,
343343
current_window_label = label.to_js_string()?,
344344
));

0 commit comments

Comments
 (0)