From 28b2dc8c525c86c2a9367fc12f7968604accb2b0 Mon Sep 17 00:00:00 2001 From: Jacob Mischka Date: Thu, 15 Jul 2021 17:29:24 -0500 Subject: [PATCH] Listen to VimResized event and resize the window when needed Fixes #156 --- src/shell.rs | 22 +++++++++++++++++++++- src/ui.rs | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/shell.rs b/src/shell.rs index 56a02e90..7a9b44c1 100644 --- a/src/shell.rs +++ b/src/shell.rs @@ -524,6 +524,24 @@ impl State { } } + pub fn should_resize(&self, columns: usize, rows: usize) -> bool { + let (w, h) = self.calc_nvim_size(); + columns != h.get() as usize || rows != w.get() as usize + } + + pub fn calc_window_size(&self, columns: usize, rows: usize) -> (usize, usize) { + let &CellMetrics { + line_height, + char_width, + .. + } = self.render_state.borrow().font_ctx.cell_metrics(); + + ( + (columns as f64 * char_width).ceil() as usize, + (rows as f64 * line_height).ceil() as usize, + ) + } + fn calc_nvim_size(&self) -> (NonZeroI64, NonZeroI64) { let &CellMetrics { line_height, @@ -1787,7 +1805,9 @@ impl State { } pub fn option_set(&mut self, name: String, val: Value) -> RepaintMode { - if let "guifont" = name.as_str() { self.set_font_from_value(val) }; + if let "guifont" = name.as_str() { + self.set_font_from_value(val) + }; RepaintMode::Nothing } diff --git a/src/ui.rs b/src/ui.rs index f00ba91e..16c2a15d 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -253,6 +253,12 @@ impl Ui { clone!(shell_ref => move |args| set_completeopts(&*shell_ref, args)), ); + let update_size = shell.state.borrow().subscribe( + SubscriptionKey::from("VimResized"), + &["&lines", "&columns"], + clone!(comps_ref, shell_ref => move |args| update_window_size(&*comps_ref, &*shell_ref, args)), + ); + window.connect_delete_event(clone!(comps_ref, shell_ref => move |_, _| { gtk_delete(&*comps_ref, &*shell_ref) })); @@ -285,6 +291,7 @@ impl Ui { &update_title, &update_subtitle, &update_completeopt, + &update_size, &post_config_cmds, mode, ); @@ -308,6 +315,7 @@ impl Ui { update_title: &SubscriptionHandle, update_subtitle: &Option, update_completeopt: &SubscriptionHandle, + update_size: &SubscriptionHandle, post_config_cmds: &Option>, mode: StartMode, ) { @@ -318,6 +326,7 @@ impl Ui { shell.set_autocmds(); shell.run_now(&update_title); shell.run_now(&update_completeopt); + shell.run_now(&update_size); if let Some(ref update_subtitle) = update_subtitle { shell.run_now(&update_subtitle); } @@ -551,7 +560,9 @@ fn on_help_about(window: >k::ApplicationWindow) { let about = AboutDialog::new(); about.set_transient_for(Some(window)); about.set_program_name("NeovimGtk"); - about.set_version(Some(crate::GIT_BUILD_VERSION.unwrap_or(env!("CARGO_PKG_VERSION")))); + about.set_version(Some( + crate::GIT_BUILD_VERSION.unwrap_or(env!("CARGO_PKG_VERSION")), + )); about.set_logo_icon_name(Some("org.daa.NeovimGtk")); about.set_authors(&[env!("CARGO_PKG_AUTHORS")]); about.set_comments(Some(misc::about_comments().as_str())); @@ -625,6 +636,26 @@ fn update_window_title(comps: &Arc>, args: Vec) { window.set_title(filename); } +fn update_window_size(comps: &UiMutex, shell: &RefCell, args: Vec) { + let lines = &args[0]; + let cols = &args[1]; + + if let (Ok(lines), Ok(cols)) = (lines.parse::(), cols.parse::()) { + let state_ref = shell.borrow().state.clone(); + let state = state_ref.borrow(); + + if state.should_resize(cols, lines) { + let (width, height) = state.calc_window_size(cols, lines); + + let comps_ref = comps.clone(); + let comps = comps_ref.borrow(); + let window = comps.window.as_ref().unwrap(); + + window.resize(width as i32, height as i32); + } + } +} + #[derive(Serialize, Deserialize)] struct WindowState { current_width: i32,