feat(window-state): add js api, closes #254 (#309)

* feat(window-state): add js api, closes #254

* symlink tsconfig.json

* update symlink

* Update plugins/window-state/package.json

Co-authored-by: Fabian-Lars <fabianlars@fabianlars.de>

* Update Cargo.toml

* move to cmd.rs

* Update plugins/window-state/guest-js/index.ts

---------

Co-authored-by: Fabian-Lars <fabianlars@fabianlars.de>
This commit is contained in:
Amr Bashir
2023-04-17 17:31:36 +02:00
committed by GitHub
parent 6f39921dbe
commit e5b07f4af2
10 changed files with 1091 additions and 787 deletions
+28
View File
@@ -0,0 +1,28 @@
use crate::{AppHandleExt, StateFlags, WindowExt};
use tauri::{command, AppHandle, Manager, Runtime};
#[command]
pub async fn save_window_state<R: Runtime>(
app: AppHandle<R>,
flags: u32,
) -> std::result::Result<(), String> {
let flags = StateFlags::from_bits(flags)
.ok_or_else(|| format!("Invalid state flags bits: {}", flags))?;
app.save_window_state(flags).map_err(|e| e.to_string())?;
Ok(())
}
#[command]
pub async fn restore_state<R: Runtime>(
app: AppHandle<R>,
label: String,
flags: u32,
) -> std::result::Result<(), String> {
let flags = StateFlags::from_bits(flags)
.ok_or_else(|| format!("Invalid state flags bits: {}", flags))?;
app.get_window(&label)
.ok_or_else(|| format!("Couldn't find window with label: {}", label))?
.restore_state(flags)
.map_err(|e| e.to_string())?;
Ok(())
}
+27 -2
View File
@@ -17,6 +17,8 @@ use std::{
sync::{Arc, Mutex},
};
mod cmd;
pub const STATE_FILENAME: &str = ".window-state";
#[derive(Debug, thiserror::Error)]
@@ -34,7 +36,7 @@ pub enum Error {
pub type Result<T> = std::result::Result<T, Error>;
bitflags! {
#[derive(Clone, Copy)]
#[derive(Clone, Copy, Debug)]
pub struct StateFlags: u32 {
const SIZE = 1 << 0;
const POSITION = 1 << 1;
@@ -51,7 +53,7 @@ impl Default for StateFlags {
}
}
#[derive(Debug, Default, Deserialize, Serialize)]
#[derive(Debug, Default, Deserialize, Serialize, PartialEq)]
struct WindowState {
width: f64,
height: f64,
@@ -65,6 +67,7 @@ struct WindowState {
struct WindowStateCache(Arc<Mutex<HashMap<String, WindowState>>>);
pub trait AppHandleExt {
/// Saves all open windows state to disk
fn save_window_state(&self, flags: StateFlags) -> Result<()>;
}
@@ -94,6 +97,7 @@ impl<R: Runtime> AppHandleExt for tauri::AppHandle<R> {
}
pub trait WindowExt {
/// Restores this window state from disk
fn restore_state(&self, flags: StateFlags) -> tauri::Result<()>;
}
@@ -101,9 +105,15 @@ impl<R: Runtime> WindowExt for Window<R> {
fn restore_state(&self, flags: StateFlags) -> tauri::Result<()> {
let cache = self.state::<WindowStateCache>();
let mut c = cache.0.lock().unwrap();
let mut should_show = true;
if let Some(state) = c.get(self.label()) {
// avoid restoring the default zeroed state
if *state == WindowState::default() {
return Ok(());
}
if flags.contains(StateFlags::DECORATIONS) {
self.set_decorations(state.decorated)?;
}
@@ -270,6 +280,10 @@ impl Builder {
pub fn build<R: Runtime>(self) -> TauriPlugin<R> {
let flags = self.state_flags;
PluginBuilder::new("window-state")
.invoke_handler(tauri::generate_handler![
cmd::save_window_state,
cmd::restore_state
])
.setup(|app| {
let cache: Arc<Mutex<HashMap<String, WindowState>>> = if let Some(app_dir) =
app.path_resolver().app_config_dir()
@@ -305,6 +319,17 @@ impl Builder {
let label = window.label().to_string();
let window_clone = window.clone();
let flags = self.state_flags;
// insert a default state if this window should be tracked and
// the disk cache doesn't have a state for it
{
cache
.lock()
.unwrap()
.entry(label.clone())
.or_insert_with(WindowState::default);
}
window.on_window_event(move |e| {
if let WindowEvent::CloseRequested { .. } = e {
let mut c = cache.lock().unwrap();