diff --git a/src/bridge/ui_commands.rs b/src/bridge/ui_commands.rs index 4d501bb..60ab634 100644 --- a/src/bridge/ui_commands.rs +++ b/src/bridge/ui_commands.rs @@ -16,8 +16,8 @@ use crate::windows_utils::{ pub enum UiCommand { Quit, Resize { - width: u32, - height: u32, + width: u64, + height: u64, }, Keyboard(String), MouseButton { diff --git a/src/editor/mod.rs b/src/editor/mod.rs index 9ef7488..9e1362e 100644 --- a/src/editor/mod.rs +++ b/src/editor/mod.rs @@ -236,7 +236,6 @@ impl Editor { } fn resize_window(&mut self, grid: u64, width: u64, height: u64) { - trace!("editor resize {}", grid); if let Some(window) = self.windows.get_mut(&grid) { window.resize((width, height)); } else { diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index c2b919f..e2d56b9 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use std::sync::mpsc::Receiver; use std::sync::Arc; +use glutin::dpi::PhysicalSize; use log::{error, trace}; use skia_safe::{colors, dash_path_effect, BlendMode, Canvas, Color, Paint, Rect, HSV}; @@ -51,6 +52,7 @@ pub struct Renderer { pub font_height: u64, pub window_regions: Vec, pub batched_draw_command_receiver: Receiver>, + pub is_ready: bool, } impl Renderer { @@ -84,6 +86,24 @@ impl Renderer { font_height, window_regions, batched_draw_command_receiver, + is_ready: false, + } + } + + // TODO: Refactor code to use these two functions instead of multiplication. + /// Convert PhysicalSize to grid size + pub fn to_grid_size(&self, new_size: PhysicalSize) -> (u64, u64) { + let width = new_size.width as u64 / self.font_width; + let height = new_size.height as u64 / self.font_height; + (width, height) + } + + /// Convert grid size to PhysicalSize + pub fn to_physical_size(&self, new_size: (u64, u64)) -> PhysicalSize { + let (width, height) = new_size; + PhysicalSize { + width: (width * self.font_width) as u32, + height: (height * self.font_height) as u32, } } @@ -101,10 +121,11 @@ impl Renderer { let (font_width, font_height) = self.shaper.font_base_dimensions(); self.font_width = font_width; self.font_height = font_height; + self.is_ready = true; trace!( "Updating font dimensions: {}x{}", - self.font_height, self.font_width, + self.font_height, ); } diff --git a/src/settings/window_geometry.rs b/src/settings/window_geometry.rs index c494dc3..8f11037 100644 --- a/src/settings/window_geometry.rs +++ b/src/settings/window_geometry.rs @@ -1,7 +1,5 @@ -use crate::renderer::Renderer; use crate::settings::SETTINGS; use crate::window::WindowSettings; -use glutin::dpi::PhysicalSize; use serde::{Deserialize, Serialize}; use std::path::PathBuf; @@ -36,12 +34,10 @@ pub const DEFAULT_WINDOW_GEOMETRY: WindowGeometry = WindowGeometry { height: 50, }; -pub fn maybe_save_window_size(window_size: PhysicalSize, renderer: &Renderer) { +pub fn maybe_save_window_size(grid_size: (u64, u64)) { let saved_window_size = if SETTINGS.get::().remember_window_size { - WindowGeometry { - width: (window_size.width as f32 / renderer.font_width as f32) as u64, - height: (window_size.height as f32 / renderer.font_height as f32) as u64, - } + let (width, height) = grid_size; + WindowGeometry { width, height } } else { WindowGeometry { width: DEFAULT_WINDOW_GEOMETRY.width as u64, diff --git a/src/window/window_wrapper/mod.rs b/src/window/window_wrapper/mod.rs index 21efa55..f23c7fa 100644 --- a/src/window/window_wrapper/mod.rs +++ b/src/window/window_wrapper/mod.rs @@ -52,7 +52,9 @@ pub struct GlutinWindowWrapper { mouse_manager: MouseManager, title: String, fullscreen: bool, + first_render_pass: bool, saved_inner_size: PhysicalSize, + saved_grid_size: (u64, u64), ui_command_sender: LoggingTx, window_command_receiver: Receiver, } @@ -162,41 +164,44 @@ impl GlutinWindowWrapper { pub fn draw_frame(&mut self, dt: f32) { let window = self.windowed_context.window(); - let current_size = window.inner_size(); - let previous_size = self.saved_inner_size; - - if previous_size != current_size { - trace!("Updating grid size: {:#?}", current_size); - self.saved_inner_size = current_size; - self.handle_new_grid_size(current_size); - self.skia_renderer.resize(&self.windowed_context); - } if REDRAW_SCHEDULER.should_draw() || SETTINGS.get::().no_idle { - let renderer = &mut self.renderer; + self.renderer.draw_frame(self.skia_renderer.canvas(), dt); + self.skia_renderer.gr_context.flush(None); + self.windowed_context.swap_buffers().unwrap(); + } - { - let canvas = self.skia_renderer.canvas(); + // Wait until fonts are loaded, so we can set proper window size. + if !self.renderer.is_ready { + return; + } - if renderer.draw_frame(canvas, dt) { - self.handle_new_grid_size(current_size); - } + if self.first_render_pass { + self.first_render_pass = false; + if !window.is_maximized() { + window.set_inner_size(self.renderer.to_physical_size(self.saved_grid_size)); } + } - self.skia_renderer.gr_context.flush(None); - self.windowed_context.swap_buffers().unwrap(); + let new_size = window.inner_size(); + + if self.saved_inner_size != new_size { + self.saved_inner_size = new_size; + self.handle_new_grid_size(new_size); + self.skia_renderer.resize(&self.windowed_context); } } - fn handle_new_grid_size(&self, new_size: PhysicalSize) { - if new_size.width > 0 && new_size.height > 0 { - // Add 1 here to make sure resizing doesn't change the grid size on startup - let width = ((new_size.width + 1) / self.renderer.font_width as u32) as u32; - let height = ((new_size.height + 1) / self.renderer.font_height as u32) as u32; - self.ui_command_sender - .send(UiCommand::Resize { width, height }) - .ok(); + fn handle_new_grid_size(&mut self, new_size: PhysicalSize) { + let (width, height) = self.renderer.to_grid_size(new_size); + if self.saved_grid_size == (width, height) { + trace!("Grid matched saved size, skip update."); + return; } + self.saved_grid_size = (width, height); + self.ui_command_sender + .send(UiCommand::Resize { width, height }) + .ok(); } fn handle_scale_factor_update(&mut self, scale_factor: f64) { @@ -252,14 +257,6 @@ pub fn create_window( let scale_factor = windowed_context.window().scale_factor(); let renderer = Renderer::new(batched_draw_command_receiver, scale_factor); - - if !window.is_maximized() { - window.set_inner_size(get_initial_window_size(( - renderer.font_width, - renderer.font_height, - ))); - } - let saved_inner_size = window.inner_size(); let skia_renderer = SkiaRenderer::new(&windowed_context); @@ -271,6 +268,8 @@ pub fn create_window( renderer.font_height, ); + let WindowGeometry { width, height } = SETTINGS.get::().geometry; + let mut window_wrapper = GlutinWindowWrapper { windowed_context, skia_renderer, @@ -279,7 +278,9 @@ pub fn create_window( mouse_manager: MouseManager::new(ui_command_sender.clone()), title: String::from("Neovide"), fullscreen: false, + first_render_pass: true, saved_inner_size, + saved_grid_size: (width, height), ui_command_sender, window_command_receiver, }; @@ -288,7 +289,7 @@ pub fn create_window( event_loop.run(move |e, _window_target, control_flow| { if !running.load(Ordering::Relaxed) { - maybe_save_window_size(window_wrapper.saved_inner_size, &window_wrapper.renderer); + maybe_save_window_size(window_wrapper.saved_grid_size); std::process::exit(0); } @@ -311,9 +312,3 @@ pub fn create_window( *control_flow = ControlFlow::WaitUntil(previous_frame_start + frame_duration) }); } - -fn get_initial_window_size(font_dimesions: (u64, u64)) -> PhysicalSize { - let WindowGeometry { width, height } = SETTINGS.get::().geometry; - let (font_width, font_height) = font_dimesions; - PhysicalSize::new((width * font_width) as u32, (height * font_height) as u32) -}