Skip to content

Commit

Permalink
feat(core): add window center API, closes #1822 (#1954)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernog authored Jun 5, 2021
1 parent f877aa5 commit 5cba6eb
Show file tree
Hide file tree
Showing 14 changed files with 90 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changes/api-window-center.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"api": patch
---

Adds `center?: boolean` to `WindowOptions` and `center()` API to the `appWindow`.
7 changes: 7 additions & 0 deletions .changes/window-center.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"tauri-runtime": patch
"tauri-runtime-wry": patch
"tauri": patch
---

Adds `Window#center` and `WindowBuilder#center` APIs.
30 changes: 30 additions & 0 deletions core/tauri-runtime-wry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ impl From<Position> for PositionWrapper {
#[derive(Debug, Clone, Default)]
pub struct WindowBuilderWrapper {
inner: WryWindowBuilder,
center: bool,
#[cfg(feature = "menu")]
menu_items: HashMap<u32, WryCustomMenuItem>,
}
Expand Down Expand Up @@ -295,6 +296,11 @@ impl WindowBuilder for WindowBuilderWrapper {
self
}

fn center(mut self) -> Self {
self.center = true;
self
}

fn position(mut self, x: f64, y: f64) -> Self {
self.inner = self.inner.with_position(WryLogicalPosition::new(x, y));
self
Expand Down Expand Up @@ -453,6 +459,7 @@ enum WindowMessage {
#[cfg(windows)]
Hwnd(Sender<Hwnd>),
// Setters
Center(Sender<Result<()>>),
SetResizable(bool),
SetTitle(String),
Maximize,
Expand Down Expand Up @@ -638,6 +645,10 @@ impl Dispatch for WryDispatcher {

// Setters

fn center(&self) -> Result<()> {
dispatcher_getter!(self, WindowMessage::Center)
}

fn print(&self) -> Result<()> {
self
.context
Expand Down Expand Up @@ -1278,6 +1289,9 @@ fn handle_event_loop(
tx.send(Hwnd(window.hwnd())).unwrap()
}
// Setters
WindowMessage::Center(tx) => {
tx.send(center_window(window)).unwrap();
}
WindowMessage::SetResizable(resizable) => window.set_resizable(resizable),
WindowMessage::SetTitle(title) => window.set_title(&title),
WindowMessage::Maximize => window.set_maximized(true),
Expand Down Expand Up @@ -1409,6 +1423,19 @@ fn handle_event_loop(
}
}

fn center_window(window: &Window) -> Result<()> {
if let Some(monitor) = window.current_monitor() {
let screen_size = monitor.size();
let window_size = window.inner_size();
let x = (screen_size.width - window_size.width) / 2;
let y = (screen_size.height - window_size.height) / 2;
window.set_outer_position(WryPhysicalPosition::new(x, y));
Ok(())
} else {
Err(Error::FailedToGetMonitor)
}
}

fn create_webview<P: Params<Runtime = Wry>>(
event_loop: &EventLoopWindowTarget<Message>,
context: DispatcherContext,
Expand All @@ -1428,6 +1455,9 @@ fn create_webview<P: Params<Runtime = Wry>>(
#[cfg(feature = "menu")]
let menu_items = window_builder.menu_items;
let window = window_builder.inner.build(event_loop).unwrap();
if window_builder.center {
let _ = center_window(&window);
}
let mut webview_builder = WebViewBuilder::new(window)
.map_err(|e| Error::CreateWebview(Box::new(e)))?
.with_url(&url)
Expand Down
6 changes: 6 additions & 0 deletions core/tauri-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ pub enum Error {
/// Failed to load window icon.
#[error("invalid icon: {0}")]
InvalidIcon(Box<dyn std::error::Error + Send>),
/// Failed to get monitor on window operation.
#[error("failed to get monitor")]
FailedToGetMonitor,
}

/// Result type.
Expand Down Expand Up @@ -317,6 +320,9 @@ pub trait Dispatch: Clone + Send + Sized + 'static {

// SETTERS

/// Centers the window.
fn center(&self) -> crate::Result<()>;

/// Opens the dialog to prints the contents of the webview.
fn print(&self) -> crate::Result<()>;

Expand Down
3 changes: 3 additions & 0 deletions core/tauri-runtime/src/webview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ pub trait WindowBuilder: WindowBuilderBase {
#[cfg_attr(doc_cfg, doc(cfg(feature = "menu")))]
fn menu<I: MenuId>(self, menu: Menu<I>) -> Self;

/// Show window in the center of the screen.
fn center(self) -> Self;

/// The initial position of the window's.
fn position(self, x: f64, y: f64) -> Self;

Expand Down
7 changes: 7 additions & 0 deletions core/tauri-utils/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ pub struct WindowConfig {
/// The window webview URL.
#[serde(default)]
pub url: WindowUrl,
/// Center the window.
#[serde(default)]
pub center: bool,
/// The horizontal position of the window's top left corner
pub x: Option<f64>,
/// The vertical position of the window's top left corner
Expand Down Expand Up @@ -125,6 +128,7 @@ impl Default for WindowConfig {
Self {
label: default_window_label(),
url: WindowUrl::default(),
center: false,
x: None,
y: None,
width: default_width(),
Expand Down Expand Up @@ -649,6 +653,7 @@ mod build {
fn to_tokens(&self, tokens: &mut TokenStream) {
let label = str_lit(&self.label);
let url = &self.url;
let center = self.center;
let x = opt_lit(self.x.as_ref());
let y = opt_lit(self.y.as_ref());
let width = self.width;
Expand All @@ -673,6 +678,7 @@ mod build {
WindowConfig,
label,
url,
center,
x,
y,
width,
Expand Down Expand Up @@ -937,6 +943,7 @@ mod test {
windows: vec![WindowConfig {
label: "main".to_string(),
url: WindowUrl::default(),
center: false,
x: None,
y: None,
width: 800f64,
Expand Down
2 changes: 1 addition & 1 deletion core/tauri/scripts/bundle.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions core/tauri/src/endpoints/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub enum Cmd {
PrimaryMonitor,
AvailableMonitors,
// Setters
Center,
SetResizable(bool),
SetTitle(String),
Maximize,
Expand Down Expand Up @@ -141,6 +142,7 @@ impl Cmd {
Self::PrimaryMonitor => return Ok(window.primary_monitor()?.into()),
Self::AvailableMonitors => return Ok(window.available_monitors()?.into()),
// Setters
Self::Center => window.center()?,
Self::SetResizable(resizable) => window.set_resizable(resizable)?,
Self::SetTitle(title) => window.set_title(&title)?,
Self::Maximize => window.maximize()?,
Expand Down
5 changes: 5 additions & 0 deletions core/tauri/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,11 @@ impl<P: Params> Window<P> {

// Setters

/// Centers the window.
pub fn center(&self) -> crate::Result<()> {
self.window.dispatcher.center().map_err(Into::into)
}

/// Opens the dialog to prints the contents of the webview.
/// Currently only supported on macOS on `wry`.
/// `window.print()` works on all platforms.
Expand Down
1 change: 1 addition & 0 deletions docs/api/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ It's composed of the following properties:
<Properties anchorRoot="tauri.windows" rows={[
{ property: "label", type: "string", description: `Window id to reference on the codebase.` },
{ property: "url", type: "string", description: `URL to load on the webview.` },
{ property: "center", type: "boolean", description: `Show window in the center of the screen.` },
{ property: "x", type: "number", description: `The horizontal position of the window's top left corner.` },
{ property: "y", type: "number", description: `The vertical position of the window's top left corner.` },
{ property: "width", optional: true, type: "number", description: `Initial window width.` },
Expand Down
2 changes: 1 addition & 1 deletion examples/api/public/build/bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/api/public/build/bundle.js.map

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions examples/api/src/components/Window.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
setPosition,
setFullscreen,
setIcon,
center,
} = appWindow;
export let onMessage;
Expand Down Expand Up @@ -95,6 +96,9 @@
<input type="checkbox" bind:checked={maximized} />
Maximize
</label>
<button title="Unminimizes after 2 seconds" on:click={center}>
Center
</button>
<button title="Unminimizes after 2 seconds" on:click={minimize_}>
Minimize
</button>
Expand Down
17 changes: 17 additions & 0 deletions tooling/api/src/window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,21 @@ class WindowManager {

// Setters

/**
* Centers the window.
*
* @param resizable
* @returns A promise indicating the success or failure of the operation.
*/
async center(): Promise<void> {
return invokeTauriCommand({
__tauriModule: 'Window',
message: {
cmd: 'center'
}
})
}

/**
* Updates the window resizable flag.
*
Expand Down Expand Up @@ -785,6 +800,8 @@ interface WindowOptions {
* Remote URL or local file path to open, e.g. `https://github.com/tauri-apps` or `path/to/page.html`.
*/
url?: string
/** Show window in the center of the screen.. */
center?: boolean
/** The initial vertical position. Only applies if `y` is also set. */
x?: number
/** The initial horizontal position. Only applies if `x` is also set. */
Expand Down

0 comments on commit 5cba6eb

Please sign in to comment.