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