From 22cb5bc05f943cfbeb4ee74f43b4fe33aa3cdd00 Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Sun, 2 Jan 2022 23:16:56 -0800 Subject: [PATCH] refactor saved settings to be an enum to enable persistence of maximized state --- src/settings/mod.rs | 3 +- src/settings/window_geometry.rs | 91 ++++++++++++++++++--------------- src/window/mod.rs | 46 +++++++++++------ 3 files changed, 82 insertions(+), 58 deletions(-) diff --git a/src/settings/mod.rs b/src/settings/mod.rs index 866450b..a507f6b 100644 --- a/src/settings/mod.rs +++ b/src/settings/mod.rs @@ -10,7 +10,8 @@ use nvim_rs::Neovim; use parking_lot::RwLock; pub use rmpv::Value; pub use window_geometry::{ - load_last_window_position, parse_window_geometry, save_window_geometry, DEFAULT_WINDOW_GEOMETRY, + load_last_window_settings, parse_window_geometry, save_window_geometry, + PersistentWindowSettings, DEFAULT_WINDOW_GEOMETRY, }; use crate::bridge::TxWrapper; diff --git a/src/settings/window_geometry.rs b/src/settings/window_geometry.rs index 959e132..6588337 100644 --- a/src/settings/window_geometry.rs +++ b/src/settings/window_geometry.rs @@ -12,12 +12,15 @@ pub const DEFAULT_WINDOW_GEOMETRY: Dimensions = Dimensions { height: 50, }; -#[derive(Serialize, Deserialize)] -struct PersistentWindowSettings { - #[serde(default)] - position: PhysicalPosition, - #[serde(default = "default_size")] - size: Dimensions, +#[derive(Serialize, Deserialize, Debug)] +pub enum PersistentWindowSettings { + Maximized, + Windowed { + #[serde(default)] + position: PhysicalPosition, + #[serde(default = "default_size")] + size: Dimensions, + }, } fn default_size() -> Dimensions { @@ -54,51 +57,47 @@ fn load_settings() -> Result { serde_json::from_str(&json).map_err(|e| e.to_string()) } -pub fn try_to_load_last_window_size() -> Result { +pub fn load_last_window_settings() -> Result { let settings = load_settings()?; - let loaded_geometry = settings.window.size; - log::debug!("Loaded Window Size: {:?}", loaded_geometry); - - if loaded_geometry.width == 0 || loaded_geometry.height == 0 { - log::warn!("Invalid Saved Window Size. Reverting to default"); - Ok(DEFAULT_WINDOW_GEOMETRY) - } else { - Ok(loaded_geometry) - } -} + let mut loaded_settings = settings.window; + log::debug!("Loaded window settings: {:?}", loaded_settings); -pub fn load_last_window_position() -> PhysicalPosition { - let settings = load_settings(); - if let Ok(settings) = settings { - let loaded_position = settings.window.position; - log::debug!("Loaded Window Position: {:?}", loaded_position); - loaded_position - } else { - PhysicalPosition::default() + if let PersistentWindowSettings::Windowed { size, .. } = &mut loaded_settings { + if size.width == 0 || size.height == 0 { + *size = DEFAULT_WINDOW_GEOMETRY; + } } + + Ok(loaded_settings) } pub fn save_window_geometry( + maximized: bool, grid_size: Option, position: Option>, ) { let window_settings = SETTINGS.get::(); + let settings = PersistentSettings { - window: PersistentWindowSettings { - size: { - window_settings - .remember_window_size - .then(|| grid_size) - .flatten() - .unwrap_or(DEFAULT_WINDOW_GEOMETRY) - }, - position: { - window_settings - .remember_window_position - .then(|| position) - .flatten() - .unwrap_or_default() - }, + window: if maximized && window_settings.remember_window_size { + PersistentWindowSettings::Maximized + } else { + PersistentWindowSettings::Windowed { + size: { + window_settings + .remember_window_size + .then(|| grid_size) + .flatten() + .unwrap_or(DEFAULT_WINDOW_GEOMETRY) + }, + position: { + window_settings + .remember_window_position + .then(|| position) + .flatten() + .unwrap_or_default() + }, + } }, }; @@ -110,8 +109,16 @@ pub fn save_window_geometry( } pub fn parse_window_geometry(geometry: Option) -> Result { - let saved_window_size = - try_to_load_last_window_size().or::(Ok(DEFAULT_WINDOW_GEOMETRY)); + let saved_window_size = load_last_window_settings() + .and_then(|window_settings| { + if let PersistentWindowSettings::Windowed { size, .. } = window_settings { + Ok(size) + } else { + Err(String::from("Window was maximized")) + } + }) + .or::(Ok(DEFAULT_WINDOW_GEOMETRY)); + geometry.map_or(saved_window_size, |input| { let invalid_parse_err = format!( "Invalid geometry: {}\nValid format: x", diff --git a/src/window/mod.rs b/src/window/mod.rs index 3ec6116..9489d2a 100644 --- a/src/window/mod.rs +++ b/src/window/mod.rs @@ -30,7 +30,9 @@ use crate::{ redraw_scheduler::REDRAW_SCHEDULER, renderer::Renderer, running_tracker::*, - settings::{load_last_window_position, save_window_geometry, SETTINGS}, + settings::{ + load_last_window_settings, save_window_geometry, PersistentWindowSettings, SETTINGS, + }, utils::Dimensions, }; use image::{load_from_memory, GenericImageView, Pixel}; @@ -275,21 +277,37 @@ pub fn create_window( let event_loop = EventLoop::new(); let cmd_line_settings = SETTINGS.get::(); - let winit_window_builder = window::WindowBuilder::new() + + let mut maximized = cmd_line_settings.maximized; + let mut previous_position = None; + if let Ok(last_window_settings) = load_last_window_settings() { + match last_window_settings { + PersistentWindowSettings::Maximized => { + maximized = true; + } + PersistentWindowSettings::Windowed { position, .. } => { + previous_position = Some(position); + } + } + } + + let mut winit_window_builder = window::WindowBuilder::new() .with_title("Neovide") .with_window_icon(Some(icon)) - .with_maximized(cmd_line_settings.maximized) + .with_maximized(maximized) .with_transparent(true) - .with_decorations(!cmd_line_settings.frameless) - .with_position(load_last_window_position()); + .with_decorations(!cmd_line_settings.frameless); + + if let Some(previous_position) = previous_position { + if !maximized { + winit_window_builder = winit_window_builder.with_position(previous_position); + } + } #[cfg(target_os = "linux")] let winit_window_builder = winit_window_builder - .with_app_id(SETTINGS.get::().wayland_app_id) - .with_class( - "neovide".to_string(), - SETTINGS.get::().x11_wm_class, - ); + .with_app_id(cmd_line_settings.wayland_app_id) + .with_class("neovide".to_string(), cmd_line_settings.x11_wm_class); let windowed_context = ContextBuilder::new() .with_pixel_format(24, 8) @@ -333,13 +351,11 @@ pub fn create_window( event_loop.run(move |e, _window_target, control_flow| { if !RUNNING_TRACKER.is_running() { + let window = window_wrapper.windowed_context.window(); save_window_geometry( + window.is_maximized(), window_wrapper.saved_grid_size, - window_wrapper - .windowed_context - .window() - .outer_position() - .ok(), + window.outer_position().ok(), ); std::process::exit(0); }