1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-27 12:23:46 +03:00

window: wayland: queue Configure/Resize/Close events

This makes eg: window resizing a bit more smooth and responsive
This commit is contained in:
Wez Furlong 2019-11-29 18:47:54 -08:00
parent 2475969eca
commit c3447930b7

View File

@ -295,6 +295,7 @@ pub struct WaylandWindowInner {
last_mouse_coords: Point, last_mouse_coords: Point,
mouse_buttons: MouseButtons, mouse_buttons: MouseButtons,
modifiers: Modifiers, modifiers: Modifiers,
pending_event: Arc<Mutex<PendingEvent>>,
// wegl_surface is listed before gl_state because it // wegl_surface is listed before gl_state because it
// must be dropped before gl_state otherwise the underlying // must be dropped before gl_state otherwise the underlying
// libraries will segfault on shutdown // libraries will segfault on shutdown
@ -304,6 +305,47 @@ pub struct WaylandWindowInner {
gl_state: Option<Rc<glium::backend::Context>>, gl_state: Option<Rc<glium::backend::Context>>,
} }
#[derive(Default, Clone, Debug)]
struct PendingEvent {
close: bool,
refresh: bool,
configure: Option<(u32, u32)>,
}
impl PendingEvent {
fn queue(&mut self, evt: Event) -> bool {
match evt {
Event::Close => {
if !self.close {
self.close = true;
true
} else {
false
}
}
Event::Refresh => {
if !self.refresh {
self.refresh = true;
true
} else {
false
}
}
Event::Configure { new_size, .. } => {
let changed;
if let Some(new_size) = new_size {
changed = self.configure.is_none();
self.configure.replace(new_size);
} else {
changed = !self.refresh;
self.refresh = true;
}
changed
}
}
}
}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct WaylandWindow(usize); pub struct WaylandWindow(usize);
@ -333,15 +375,21 @@ impl WaylandWindow {
}); });
let dimensions = (width as u32, height as u32); let dimensions = (width as u32, height as u32);
let pending_event = Arc::new(Mutex::new(PendingEvent::default()));
let mut window = toolkit::window::Window::<toolkit::window::ConceptFrame>::init_from_env( let mut window = toolkit::window::Window::<toolkit::window::ConceptFrame>::init_from_env(
&*conn.environment.borrow(), &*conn.environment.borrow(),
surface.clone(), surface.clone(),
dimensions, dimensions,
move |evt| { {
WaylandConnection::with_window_inner(window_id, move |inner| { let pending_event = Arc::clone(&pending_event);
inner.handle_event(evt.clone()); move |evt| {
Ok(()) if pending_event.lock().unwrap().queue(evt) {
}); WaylandConnection::with_window_inner(window_id, move |inner| {
inner.dispatch_pending_event();
Ok(())
});
}
}
}, },
) )
.map_err(|e| failure::format_err!("Failed to create window: {}", e))?; .map_err(|e| failure::format_err!("Failed to create window: {}", e))?;
@ -512,6 +560,7 @@ impl WaylandWindow {
last_mouse_coords: Point::new(0, 0), last_mouse_coords: Point::new(0, 0),
mouse_buttons: MouseButtons::NONE, mouse_buttons: MouseButtons::NONE,
modifiers: Modifiers::NONE, modifiers: Modifiers::NONE,
pending_event,
#[cfg(feature = "opengl")] #[cfg(feature = "opengl")]
gl_state: None, gl_state: None,
#[cfg(feature = "opengl")] #[cfg(feature = "opengl")]
@ -671,41 +720,44 @@ impl WaylandWindowInner {
self.refresh_frame(); self.refresh_frame();
} }
fn handle_event(&mut self, evt: Event) { fn dispatch_pending_event(&mut self) {
match evt { let mut pending;
Event::Close => { {
if self.callbacks.can_close() { let mut pending_events = self.pending_event.lock().unwrap();
self.callbacks.destroy(); pending = pending_events.clone();
self.window.take(); *pending_events = PendingEvent::default();
} }
if pending.close {
if self.callbacks.can_close() {
self.callbacks.destroy();
self.window.take();
} }
Event::Refresh => { }
self.do_paint().unwrap(); if let Some((w, h)) = pending.configure.take() {
} if self.window.is_some() {
Event::Configure { new_size, .. } => { let factor = toolkit::surface::get_dpi_factor(&self.surface);
if self.window.is_none() { self.surface.set_buffer_scale(factor);
return; self.window.as_mut().unwrap().resize(w, h);
} let w = w * factor as u32;
if let Some((w, h)) = new_size { let h = h * factor as u32;
let factor = toolkit::surface::get_dpi_factor(&self.surface); self.dimensions = (w, h);
self.surface.set_buffer_scale(factor); #[cfg(feature = "opengl")]
self.window.as_mut().unwrap().resize(w, h); {
let w = w * factor as u32; if let Some(wegl_surface) = self.wegl_surface.as_mut() {
let h = h * factor as u32; wegl_surface.resize(w as i32, h as i32, 0, 0);
self.dimensions = (w, h);
#[cfg(feature = "opengl")]
{
if let Some(wegl_surface) = self.wegl_surface.as_mut() {
wegl_surface.resize(w as i32, h as i32, 0, 0);
}
} }
self.callbacks.resize(Dimensions {
pixel_width: w as usize,
pixel_height: h as usize,
dpi: 96 * factor as usize,
});
} }
self.callbacks.resize(Dimensions {
pixel_width: w as usize,
pixel_height: h as usize,
dpi: 96 * factor as usize,
});
self.refresh_frame(); self.refresh_frame();
pending.refresh = true;
}
}
if pending.refresh {
if self.window.is_some() {
self.do_paint().unwrap(); self.do_paint().unwrap();
} }
} }