Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/fix-restore-minimized-window-state.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"window-state": patch
---

Fix can't restore a minimized window's size and position properly
5 changes: 5 additions & 0 deletions .changes/window-state-physical-size.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"window-state": patch:breaking
---

Window's size is now stored in physical size instead of logical size
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions examples/api/src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ features = [
tauri-plugin-cli = { path = "../../../plugins/cli", version = "2.0.0-rc.1" }
tauri-plugin-global-shortcut = { path = "../../../plugins/global-shortcut", version = "2.0.0-rc.2" }
tauri-plugin-updater = { path = "../../../plugins/updater", version = "2.0.0-rc.3" }
tauri-plugin-window-state = { path = "../../../plugins/window-state", version = "2.0.0-rc.3" }

[target."cfg(any(target_os = \"android\", target_os = \"ios\"))".dependencies]
tauri-plugin-barcode-scanner = { path = "../../../plugins/barcode-scanner/", version = "2.0.0-rc.4" }
Expand Down
49 changes: 49 additions & 0 deletions examples/api/src-tauri/gen/schemas/desktop-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -7502,6 +7502,55 @@
"enum": [
"updater:deny-install"
]
},
{
"description": "window-state:default -> This permission set configures what kind of\noperations are available from the window state plugin.\n\n#### Granted Permissions\n\nAll operations are enabled by default.\n\n",
"type": "string",
"enum": [
"window-state:default"
]
},
{
"description": "window-state:allow-filename -> Enables the filename command without any pre-configured scope.",
"type": "string",
"enum": [
"window-state:allow-filename"
]
},
{
"description": "window-state:allow-restore-state -> Enables the restore_state command without any pre-configured scope.",
"type": "string",
"enum": [
"window-state:allow-restore-state"
]
},
{
"description": "window-state:allow-save-window-state -> Enables the save_window_state command without any pre-configured scope.",
"type": "string",
"enum": [
"window-state:allow-save-window-state"
]
},
{
"description": "window-state:deny-filename -> Denies the filename command without any pre-configured scope.",
"type": "string",
"enum": [
"window-state:deny-filename"
]
},
{
"description": "window-state:deny-restore-state -> Denies the restore_state command without any pre-configured scope.",
"type": "string",
"enum": [
"window-state:deny-restore-state"
]
},
{
"description": "window-state:deny-save-window-state -> Denies the save_window_state command without any pre-configured scope.",
"type": "string",
"enum": [
"window-state:deny-save-window-state"
]
}
]
},
Expand Down
5 changes: 3 additions & 2 deletions examples/api/src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ pub fn run() {
app.handle().plugin(tauri_plugin_cli::init())?;
app.handle()
.plugin(tauri_plugin_global_shortcut::Builder::new().build())?;
app.handle()
.plugin(tauri_plugin_window_state::Builder::new().build())?;
app.handle()
.plugin(tauri_plugin_updater::Builder::new().build())?;
}
Expand All @@ -63,8 +65,7 @@ pub fn run() {
.user_agent(&format!("Tauri API - {}", std::env::consts::OS))
.title("Tauri API Validation")
.inner_size(1000., 800.)
.min_inner_size(600., 400.)
.content_protected(true);
.min_inner_size(600., 400.);
}

#[cfg(target_os = "windows")]
Expand Down
2 changes: 1 addition & 1 deletion examples/api/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "../node_modules/@tauri-apps/cli/schema.json",
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
"productName": "Tauri API",
"version": "2.0.0",
"identifier": "com.tauri.api",
Expand Down
71 changes: 37 additions & 34 deletions plugins/window-state/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ use bitflags::bitflags;
use serde::{Deserialize, Serialize};
use tauri::{
plugin::{Builder as PluginBuilder, TauriPlugin},
LogicalSize, Manager, Monitor, PhysicalPosition, PhysicalSize, RunEvent, Runtime,
WebviewWindow, Window, WindowEvent,
Manager, Monitor, PhysicalPosition, PhysicalSize, RunEvent, Runtime, WebviewWindow, Window,
WindowEvent,
};

use std::{
Expand Down Expand Up @@ -72,8 +72,8 @@ struct PluginState {

#[derive(Debug, Deserialize, Serialize, PartialEq)]
struct WindowState {
width: f64,
height: f64,
width: u32,
height: u32,
x: i32,
y: i32,
// prev_x and prev_y are used to store position
Expand Down Expand Up @@ -181,7 +181,7 @@ impl<R: Runtime> WindowExt for Window<R> {
}

if flags.contains(StateFlags::SIZE) {
self.set_size(LogicalSize {
self.set_size(PhysicalSize {
width: state.width,
height: state.height,
})?;
Expand Down Expand Up @@ -223,11 +223,7 @@ impl<R: Runtime> WindowExt for Window<R> {
let mut metadata = WindowState::default();

if flags.contains(StateFlags::SIZE) {
let scale_factor = self
.current_monitor()?
.map(|m| m.scale_factor())
.unwrap_or(1.);
let size = self.inner_size()?.to_logical(scale_factor);
let size = self.inner_size()?;
metadata.width = size.width;
metadata.height = size.height;
}
Expand Down Expand Up @@ -278,10 +274,11 @@ impl<R: Runtime> WindowExtInternal for WebviewWindow<R> {

impl<R: Runtime> WindowExtInternal for Window<R> {
fn update_state(&self, state: &mut WindowState, flags: StateFlags) -> tauri::Result<()> {
let is_maximized = match flags.intersects(StateFlags::MAXIMIZED | StateFlags::SIZE) {
true => self.is_maximized()?,
false => false,
};
let is_maximized = flags
.intersects(StateFlags::MAXIMIZED | StateFlags::POSITION | StateFlags::SIZE)
&& self.is_maximized()?;
let is_minimized =
flags.intersects(StateFlags::POSITION | StateFlags::SIZE) && self.is_minimized()?;

if flags.contains(StateFlags::MAXIMIZED) {
state.maximized = is_maximized;
Expand All @@ -299,21 +296,16 @@ impl<R: Runtime> WindowExtInternal for Window<R> {
state.visible = self.is_visible()?;
}

if flags.contains(StateFlags::SIZE) {
let scale_factor = self
.current_monitor()?
.map(|m| m.scale_factor())
.unwrap_or(1.);
let size = self.inner_size()?.to_logical(scale_factor);

if flags.contains(StateFlags::SIZE) && !is_maximized && !is_minimized {
let size = self.inner_size()?;
// It doesn't make sense to save a window with 0 height or width
if size.width > 0. && size.height > 0. && !is_maximized {
if size.width > 0 && size.height > 0 {
state.width = size.width;
state.height = size.height;
}
}

if flags.contains(StateFlags::POSITION) && !is_maximized && !self.is_minimized()? {
if flags.contains(StateFlags::POSITION) && !is_maximized && !is_minimized {
let position = self.outer_position()?;
state.x = position.x;
state.y = position.y;
Expand Down Expand Up @@ -451,13 +443,26 @@ impl Builder {
}

WindowEvent::Moved(position) if flags.contains(StateFlags::POSITION) => {
let mut c = cache.lock().unwrap();
if let Some(state) = c.get_mut(&label) {
state.prev_x = state.x;
state.prev_y = state.y;

state.x = position.x;
state.y = position.y;
if !window_clone.is_minimized().unwrap_or_default() {
let mut c = cache.lock().unwrap();
if let Some(state) = c.get_mut(&label) {
state.prev_x = state.x;
state.prev_y = state.y;

state.x = position.x;
state.y = position.y;
}
}
}
WindowEvent::Resized(size) if flags.contains(StateFlags::SIZE) => {
if !window_clone.is_minimized().unwrap_or_default()
&& !window_clone.is_maximized().unwrap_or_default()
{
let mut c = cache.lock().unwrap();
if let Some(state) = c.get_mut(&label) {
state.width = size.width;
state.height = size.height;
}
}
}
_ => {}
Expand All @@ -473,13 +478,11 @@ impl Builder {
}

trait MonitorExt {
fn intersects(&self, position: PhysicalPosition<i32>, size: LogicalSize<u32>) -> bool;
fn intersects(&self, position: PhysicalPosition<i32>, size: PhysicalSize<u32>) -> bool;
}

impl MonitorExt for Monitor {
fn intersects(&self, position: PhysicalPosition<i32>, size: LogicalSize<u32>) -> bool {
let size = size.to_physical::<u32>(self.scale_factor());

fn intersects(&self, position: PhysicalPosition<i32>, size: PhysicalSize<u32>) -> bool {
let PhysicalPosition { x, y } = *self.position();
let PhysicalSize { width, height } = *self.size();

Expand Down
Loading