Skip to content

Commit

Permalink
feat(api): allow mananing windows created on JS (#2154)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernog authored Jul 5, 2021
1 parent af634db commit d69b1cf
Show file tree
Hide file tree
Showing 8 changed files with 499 additions and 4,865 deletions.
5 changes: 5 additions & 0 deletions .changes/webview-window-extends-window-manager.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"api": patch
---

Allow manipulating a spawned window directly using `WebviewWindow`, which now extends `WindowManager`.
2 changes: 1 addition & 1 deletion core/tauri/scripts/bundle.js

Large diffs are not rendered by default.

191 changes: 106 additions & 85 deletions core/tauri/src/endpoints/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::{
window::dpi::{Position, Size},
UserAttentionType,
},
Params, Window,
Manager, Params, Window,
};
use serde::Deserialize;

Expand All @@ -34,13 +34,10 @@ impl From<IconDto> for Icon {
}
}

/// The API descriptor.
/// Window management API descriptor.
#[derive(Deserialize)]
#[serde(tag = "cmd", content = "data", rename_all = "camelCase")]
pub enum Cmd {
CreateWebview {
options: WindowConfig,
},
#[serde(tag = "type", content = "payload", rename_all = "camelCase")]
pub enum WindowManagerCmd {
// Getters
ScaleFactor,
InnerPosition,
Expand Down Expand Up @@ -85,6 +82,19 @@ pub enum Cmd {
Print,
}

/// The API descriptor.
#[derive(Deserialize)]
#[serde(tag = "cmd", content = "data", rename_all = "camelCase")]
pub enum Cmd {
CreateWebview {
options: WindowConfig,
},
Manage {
label: Option<String>,
cmd: WindowManagerCmd,
},
}

#[cfg(window_create)]
#[derive(Clone, serde::Serialize)]
struct WindowCreatedEvent {
Expand All @@ -94,88 +104,99 @@ struct WindowCreatedEvent {
impl Cmd {
#[allow(dead_code)]
pub async fn run<P: Params>(self, window: Window<P>) -> crate::Result<InvokeResponse> {
if cfg!(not(window_all)) {
Err(crate::Error::ApiNotAllowlisted("window > all".to_string()))
} else {
match self {
#[cfg(not(window_create))]
Self::CreateWebview { .. } => {
return Err(crate::Error::ApiNotAllowlisted(
"window > create".to_string(),
));
}
#[cfg(window_create)]
Self::CreateWebview { options } => {
let mut window = window;
// Panic if the user's `Tag` type decided to return an error while parsing.
let label: P::Label = options.label.parse().unwrap_or_else(|_| {
panic!(
"Window module received unknown window label: {}",
options.label
)
});
match self {
#[cfg(not(window_create))]
Self::CreateWebview { .. } => {
return Err(crate::Error::ApiNotAllowlisted(
"window > create".to_string(),
));
}
#[cfg(window_create)]
Self::CreateWebview { options } => {
let mut window = window;
// Panic if the user's `Tag` type decided to return an error while parsing.
let label: P::Label = options.label.parse().unwrap_or_else(|_| {
panic!(
"Window module received unknown window label: {}",
options.label
)
});

let url = options.url.clone();
let url = options.url.clone();
window
.create_window(label.clone(), url, |_, webview_attributes| {
(
<<<P::Runtime as Runtime>::Dispatcher as Dispatch>::WindowBuilder>::with_config(
options,
),
webview_attributes,
)
})?
.emit_others(
&crate::manager::tauri_event::<P::Event>("tauri://window-created"),
Some(WindowCreatedEvent {
label: label.to_string(),
}),
)?;
}
Self::Manage { label, cmd } => {
let window = if let Some(l) = label {
window
.get_window(&l.parse().unwrap_or_else(|_| panic!("invalid label")))
.ok_or(crate::Error::WebviewNotFound)?
} else {
window
.create_window(label.clone(), url, |_, webview_attributes| {
(
<<<P::Runtime as Runtime>::Dispatcher as Dispatch>::WindowBuilder>::with_config(
options,
),
webview_attributes,
)
})?
.emit_others(
&crate::manager::tauri_event::<P::Event>("tauri://window-created"),
Some(WindowCreatedEvent {
label: label.to_string(),
}),
)?;
};
match cmd {
// Getters
WindowManagerCmd::ScaleFactor => return Ok(window.scale_factor()?.into()),
WindowManagerCmd::InnerPosition => return Ok(window.inner_position()?.into()),
WindowManagerCmd::OuterPosition => return Ok(window.outer_position()?.into()),
WindowManagerCmd::InnerSize => return Ok(window.inner_size()?.into()),
WindowManagerCmd::OuterSize => return Ok(window.outer_size()?.into()),
WindowManagerCmd::IsFullscreen => return Ok(window.is_fullscreen()?.into()),
WindowManagerCmd::IsMaximized => return Ok(window.is_maximized()?.into()),
WindowManagerCmd::IsDecorated => return Ok(window.is_decorated()?.into()),
WindowManagerCmd::IsResizable => return Ok(window.is_resizable()?.into()),
WindowManagerCmd::IsVisible => return Ok(window.is_visible()?.into()),
WindowManagerCmd::CurrentMonitor => return Ok(window.current_monitor()?.into()),
WindowManagerCmd::PrimaryMonitor => return Ok(window.primary_monitor()?.into()),
WindowManagerCmd::AvailableMonitors => return Ok(window.available_monitors()?.into()),
// Setters
WindowManagerCmd::Center => window.center()?,
WindowManagerCmd::RequestUserAttention(request_type) => {
window.request_user_attention(request_type)?
}
WindowManagerCmd::SetResizable(resizable) => window.set_resizable(resizable)?,
WindowManagerCmd::SetTitle(title) => window.set_title(&title)?,
WindowManagerCmd::Maximize => window.maximize()?,
WindowManagerCmd::Unmaximize => window.unmaximize()?,
WindowManagerCmd::ToggleMaximize => match window.is_maximized()? {
true => window.unmaximize()?,
false => window.maximize()?,
},
WindowManagerCmd::Minimize => window.minimize()?,
WindowManagerCmd::Unminimize => window.unminimize()?,
WindowManagerCmd::Show => window.show()?,
WindowManagerCmd::Hide => window.hide()?,
WindowManagerCmd::Close => window.close()?,
WindowManagerCmd::SetDecorations(decorations) => window.set_decorations(decorations)?,
WindowManagerCmd::SetAlwaysOnTop(always_on_top) => {
window.set_always_on_top(always_on_top)?
}
WindowManagerCmd::SetSize(size) => window.set_size(size)?,
WindowManagerCmd::SetMinSize(size) => window.set_min_size(size)?,
WindowManagerCmd::SetMaxSize(size) => window.set_max_size(size)?,
WindowManagerCmd::SetPosition(position) => window.set_position(position)?,
WindowManagerCmd::SetFullscreen(fullscreen) => window.set_fullscreen(fullscreen)?,
WindowManagerCmd::SetFocus => window.set_focus()?,
WindowManagerCmd::SetIcon { icon } => window.set_icon(icon.into())?,
WindowManagerCmd::SetSkipTaskbar(skip) => window.set_skip_taskbar(skip)?,
WindowManagerCmd::StartDragging => window.start_dragging()?,
WindowManagerCmd::Print => window.print()?,
}
// Getters
Self::ScaleFactor => return Ok(window.scale_factor()?.into()),
Self::InnerPosition => return Ok(window.inner_position()?.into()),
Self::OuterPosition => return Ok(window.outer_position()?.into()),
Self::InnerSize => return Ok(window.inner_size()?.into()),
Self::OuterSize => return Ok(window.outer_size()?.into()),
Self::IsFullscreen => return Ok(window.is_fullscreen()?.into()),
Self::IsMaximized => return Ok(window.is_maximized()?.into()),
Self::IsDecorated => return Ok(window.is_decorated()?.into()),
Self::IsResizable => return Ok(window.is_resizable()?.into()),
Self::IsVisible => return Ok(window.is_visible()?.into()),
Self::CurrentMonitor => return Ok(window.current_monitor()?.into()),
Self::PrimaryMonitor => return Ok(window.primary_monitor()?.into()),
Self::AvailableMonitors => return Ok(window.available_monitors()?.into()),
// Setters
Self::Center => window.center()?,
Self::RequestUserAttention(request_type) => window.request_user_attention(request_type)?,
Self::SetResizable(resizable) => window.set_resizable(resizable)?,
Self::SetTitle(title) => window.set_title(&title)?,
Self::Maximize => window.maximize()?,
Self::Unmaximize => window.unmaximize()?,
Self::ToggleMaximize => match window.is_maximized()? {
true => window.unmaximize()?,
false => window.maximize()?,
},
Self::Minimize => window.minimize()?,
Self::Unminimize => window.unminimize()?,
Self::Show => window.show()?,
Self::Hide => window.hide()?,
Self::Close => window.close()?,
Self::SetDecorations(decorations) => window.set_decorations(decorations)?,
Self::SetAlwaysOnTop(always_on_top) => window.set_always_on_top(always_on_top)?,
Self::SetSize(size) => window.set_size(size)?,
Self::SetMinSize(size) => window.set_min_size(size)?,
Self::SetMaxSize(size) => window.set_max_size(size)?,
Self::SetPosition(position) => window.set_position(position)?,
Self::SetFullscreen(fullscreen) => window.set_fullscreen(fullscreen)?,
Self::SetFocus => window.set_focus()?,
Self::SetIcon { icon } => window.set_icon(icon.into())?,
Self::SetSkipTaskbar(skip) => window.set_skip_taskbar(skip)?,
Self::StartDragging => window.start_dragging()?,
Self::Print => window.print()?,
}
Ok(().into())
}
Ok(().into())
}
}
6 changes: 3 additions & 3 deletions core/tauri/src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,9 +336,9 @@ impl<P: Params> WindowManager<P> {
.initialization_script(&self.initialization_script(&plugin_init, is_init_global))
.initialization_script(&format!(
r#"
window.__TAURI__.__windows = {window_labels_array}.map(function (label) {{ return {{ label: label }} }});
window.__TAURI__.__currentWindow = {{ label: {current_window_label} }}
"#,
window.__TAURI__.__windows = {window_labels_array}.map(function (label) {{ return {{ label: label }} }});
window.__TAURI__.__currentWindow = {{ label: {current_window_label} }}
"#,
window_labels_array = tags_to_javascript_array(pending_labels)?,
current_window_label = label.to_js_string()?,
));
Expand Down
Loading

0 comments on commit d69b1cf

Please sign in to comment.