Resize timer (#58)

This commit is contained in:
daa84 2018-02-19 13:03:46 +03:00
parent babf2171f2
commit 7e857a1dad

View File

@ -1,4 +1,4 @@
use std::cell::RefCell; use std::cell::{Cell, RefCell};
use std::rc::Rc; use std::rc::Rc;
use std::sync::{Arc, Condvar, Mutex}; use std::sync::{Arc, Condvar, Mutex};
use std::ops::Deref; use std::ops::Deref;
@ -6,9 +6,9 @@ use std::thread;
use std::time::Duration; use std::time::Duration;
use cairo; use cairo;
use pango::{LayoutExt, FontDescription}; use pango::{FontDescription, LayoutExt};
use gdk; use gdk;
use gdk::{ModifierType, EventButton, EventMotion, EventType, EventScroll}; use gdk::{EventButton, EventMotion, EventScroll, EventType, ModifierType};
use gdk_sys; use gdk_sys;
use glib; use glib;
use gtk; use gtk;
@ -18,11 +18,11 @@ use pangocairo;
use neovim_lib::{Neovim, NeovimApi, NeovimApiAsync, Value}; use neovim_lib::{Neovim, NeovimApi, NeovimApiAsync, Value};
use neovim_lib::neovim_api::Tabpage; use neovim_lib::neovim_api::Tabpage;
use settings::{Settings, FontSource}; use settings::{FontSource, Settings};
use ui_model::{UiModel, Attrs, ModelRect}; use ui_model::{Attrs, ModelRect, UiModel};
use color::{ColorModel, Color, COLOR_BLACK, COLOR_WHITE, COLOR_RED}; use color::{Color, ColorModel, COLOR_BLACK, COLOR_RED, COLOR_WHITE};
use nvim::{self, RedrawEvents, GuiApi, RepaintMode, ErrorReport, NeovimClient, NeovimRef, use nvim::{self, CompleteItem, ErrorReport, GuiApi, NeovimClient, NeovimClientAsync, NeovimRef,
NeovimClientAsync, CompleteItem}; RedrawEvents, RepaintMode};
use input; use input;
use input::keyval_to_input_string; use input::keyval_to_input_string;
use cursor::Cursor; use cursor::Cursor;
@ -59,6 +59,7 @@ pub struct State {
cursor: Option<Cursor>, cursor: Option<Cursor>,
popup_menu: RefCell<PopupMenu>, popup_menu: RefCell<PopupMenu>,
settings: Rc<RefCell<Settings>>, settings: Rc<RefCell<Settings>>,
resize_timer: Rc<Cell<Option<glib::SourceId>>>,
pub clipboard_clipboard: gtk::Clipboard, pub clipboard_clipboard: gtk::Clipboard,
pub clipboard_primary: gtk::Clipboard, pub clipboard_primary: gtk::Clipboard,
@ -92,6 +93,7 @@ impl State {
cursor: None, cursor: None,
popup_menu, popup_menu,
settings, settings,
resize_timer: Rc::new(Cell::new(None)),
clipboard_clipboard: gtk::Clipboard::get(&gdk::Atom::intern("CLIPBOARD")), clipboard_clipboard: gtk::Clipboard::get(&gdk::Atom::intern("CLIPBOARD")),
clipboard_primary: gtk::Clipboard::get(&gdk::Atom::intern("PRIMARY")), clipboard_primary: gtk::Clipboard::get(&gdk::Atom::intern("PRIMARY")),
@ -275,11 +277,25 @@ impl State {
return; return;
} }
if let Some(mut nvim) = self.nvim() { let resize_timer = self.resize_timer.take();
if let Some(resize_timer) = resize_timer {
glib::source_remove(resize_timer);
}
let nvim = self.nvim.clone();
let resize_timer = self.resize_timer.clone();
let resize_id = gtk::timeout_add(200, move || {
resize_timer.set(None);
if let Some(mut nvim) = nvim.nvim() {
nvim.ui_try_resize_async(columns as u64, rows as u64) nvim.ui_try_resize_async(columns as u64, rows as u64)
.cb(|r| r.report_err()) .cb(|r| r.report_err())
.call(); .call();
} }
Continue(false)
});
self.resize_timer.set(Some(resize_id));
} }
fn edit_paste(&self, clipboard: &str) { fn edit_paste(&self, clipboard: &str) {
@ -294,7 +310,6 @@ impl State {
let paste_code = format!("<C-r>{}", clipboard); let paste_code = format!("<C-r>{}", clipboard);
nvim.input_async(&paste_code).cb(|r| r.report_err()).call(); nvim.input_async(&paste_code).cb(|r| r.report_err()).call();
}; };
} }
} }
} }
@ -379,10 +394,12 @@ impl Shell {
self.widget.pack_start(&state.stack, true, true, 0); self.widget.pack_start(&state.stack, true, true, 0);
state.drawing_area.set_events( state
(gdk_sys::GDK_BUTTON_RELEASE_MASK | gdk_sys::GDK_BUTTON_PRESS_MASK | .drawing_area
gdk_sys::GDK_BUTTON_MOTION_MASK | gdk_sys::GDK_SCROLL_MASK | .set_events(
gdk_sys::GDK_SMOOTH_SCROLL_MASK) (gdk_sys::GDK_BUTTON_RELEASE_MASK | gdk_sys::GDK_BUTTON_PRESS_MASK
| gdk_sys::GDK_BUTTON_MOTION_MASK | gdk_sys::GDK_SCROLL_MASK
| gdk_sys::GDK_SMOOTH_SCROLL_MASK)
.bits() as i32, .bits() as i32,
); );
@ -398,33 +415,32 @@ impl Shell {
let ref_state = self.state.clone(); let ref_state = self.state.clone();
let ref_ui_state = self.ui_state.clone(); let ref_ui_state = self.ui_state.clone();
state.drawing_area.connect_button_release_event( state
move |_, ev| { .drawing_area
.connect_button_release_event(move |_, ev| {
gtk_button_release( gtk_button_release(
&mut *ref_state.borrow_mut(), &mut *ref_state.borrow_mut(),
&mut *ref_ui_state.borrow_mut(), &mut *ref_ui_state.borrow_mut(),
ev, ev,
) )
}, });
);
let ref_state = self.state.clone(); let ref_state = self.state.clone();
let ref_ui_state = self.ui_state.clone(); let ref_ui_state = self.ui_state.clone();
state.drawing_area.connect_motion_notify_event( state
move |_, ev| { .drawing_area
.connect_motion_notify_event(move |_, ev| {
gtk_motion_notify( gtk_motion_notify(
&mut *ref_state.borrow_mut(), &mut *ref_state.borrow_mut(),
&mut *ref_ui_state.borrow_mut(), &mut *ref_ui_state.borrow_mut(),
ev, ev,
) )
}, });
);
let ref_state = self.state.clone(); let ref_state = self.state.clone();
state.drawing_area.connect_draw( state
move |_, ctx| gtk_draw(&ref_state, ctx), .drawing_area
); .connect_draw(move |_, ctx| gtk_draw(&ref_state, ctx));
let ref_state = self.state.clone(); let ref_state = self.state.clone();
state.drawing_area.connect_key_press_event(move |_, ev| { state.drawing_area.connect_key_press_event(move |_, ev| {
@ -464,14 +480,14 @@ impl Shell {
}); });
let ref_state = self.state.clone(); let ref_state = self.state.clone();
state.drawing_area.connect_focus_in_event(move |_, _| { state
gtk_focus_in(&mut *ref_state.borrow_mut()) .drawing_area
}); .connect_focus_in_event(move |_, _| gtk_focus_in(&mut *ref_state.borrow_mut()));
let ref_state = self.state.clone(); let ref_state = self.state.clone();
state.drawing_area.connect_focus_out_event(move |_, _| { state
gtk_focus_out(&mut *ref_state.borrow_mut()) .drawing_area
}); .connect_focus_out_event(move |_, _| gtk_focus_out(&mut *ref_state.borrow_mut()));
let ref_state = self.state.clone(); let ref_state = self.state.clone();
state.drawing_area.connect_realize(move |w| { state.drawing_area.connect_realize(move |w| {
@ -486,9 +502,9 @@ impl Shell {
}); });
let ref_state = self.state.clone(); let ref_state = self.state.clone();
state.im_context.connect_commit(move |_, ch| { state
ref_state.borrow().im_commit(ch) .im_context
}); .connect_commit(move |_, ch| ref_state.borrow().im_commit(ch));
let ref_state = self.state.clone(); let ref_state = self.state.clone();
state.drawing_area.connect_configure_event(move |_, _| { state.drawing_area.connect_configure_event(move |_, _| {
@ -497,10 +513,9 @@ impl Shell {
}); });
let ref_state = self.state.clone(); let ref_state = self.state.clone();
state.drawing_area.connect_size_allocate( state.drawing_area.connect_size_allocate(move |_, _| {
move |_, _| { init_nvim(&ref_state); }, init_nvim(&ref_state);
); });
} }
#[cfg(unix)] #[cfg(unix)]
@ -676,9 +691,8 @@ fn mouse_input(shell: &mut State, input: &str, state: ModifierType, position: (f
let nvim = shell.nvim(); let nvim = shell.nvim();
if let Some(mut nvim) = nvim { if let Some(mut nvim) = nvim {
nvim.input(&input_str).expect( nvim.input(&input_str)
"Can't send mouse input event", .expect("Can't send mouse input event");
);
} }
} }
@ -705,7 +719,6 @@ fn gtk_motion_notify(shell: &mut State, ui_state: &mut UiState, ev: &EventMotion
} }
fn gtk_draw(state_arc: &Arc<UiMutex<State>>, ctx: &cairo::Context) -> Inhibit { fn gtk_draw(state_arc: &Arc<UiMutex<State>>, ctx: &cairo::Context) -> Inhibit {
let state = state_arc.borrow(); let state = state_arc.borrow();
if state.nvim.is_initialized() { if state.nvim.is_initialized() {
render::render( render::render(
@ -788,12 +801,8 @@ fn init_nvim_async(
}); });
// attach ui // attach ui
if let Err(err) = nvim::post_start_init( if let Err(err) =
nvim, nvim::post_start_init(nvim, options.open_path.as_ref(), cols as u64, rows as u64)
options.open_path.as_ref(),
cols as u64,
rows as u64,
)
{ {
show_nvim_init_error(&err, state_arc.clone()); show_nvim_init_error(&err, state_arc.clone());
} else { } else {
@ -837,7 +846,6 @@ fn set_nvim_initialized(state_arc: Arc<UiMutex<State>>) {
Continue(false) Continue(false)
})); }));
idle_cb_call!(state_arc.nvim_started_cb()); idle_cb_call!(state_arc.nvim_started_cb());
} }
@ -867,7 +875,6 @@ fn draw_initializing(state: &State, ctx: &cairo::Context) {
pangocairo::functions::update_layout(ctx, &layout); pangocairo::functions::update_layout(ctx, &layout);
pangocairo::functions::show_layout(ctx, &layout); pangocairo::functions::show_layout(ctx, &layout);
ctx.move_to(x + width as f64, y); ctx.move_to(x + width as f64, y);
state.cursor.as_ref().unwrap().draw( state.cursor.as_ref().unwrap().draw(
ctx, ctx,
@ -891,7 +898,6 @@ fn init_nvim(state_ref: &Arc<UiMutex<State>>) {
} }
} }
impl RedrawEvents for State { impl RedrawEvents for State {
fn on_cursor_goto(&mut self, row: u64, col: u64) -> RepaintMode { fn on_cursor_goto(&mut self, row: u64, col: u64) -> RepaintMode {
let repaint_area = self.model.set_cursor(row as usize, col as usize); let repaint_area = self.model.set_cursor(row as usize, col as usize);
@ -1037,15 +1043,9 @@ impl RedrawEvents for State {
let point = ModelRect::point(col as usize, row as usize); let point = ModelRect::point(col as usize, row as usize);
let (x, y, width, height) = point.to_area(self.font_ctx.cell_metrics()); let (x, y, width, height) = point.to_area(self.font_ctx.cell_metrics());
self.popup_menu.borrow_mut().show( self.popup_menu
self, .borrow_mut()
menu, .show(self, menu, selected, x, y, width, height);
selected,
x,
y,
width,
height,
);
RepaintMode::Nothing RepaintMode::Nothing
} }
@ -1060,7 +1060,6 @@ impl RedrawEvents for State {
RepaintMode::Nothing RepaintMode::Nothing
} }
fn tabline_update( fn tabline_update(
&mut self, &mut self,
selected: Tabpage, selected: Tabpage,