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:
parent
2475969eca
commit
c3447930b7
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user