mirror of
https://github.com/wez/wezterm.git
synced 2024-11-10 06:34:17 +03:00
x11/wayland: reduce frequency of core event loop
In an earlier incarnation we needed to wake up more often to paint, but we now should have reliable event sources for all of the invalidation cases and we can thus sleep for much longer in the main event loop. refs: #770
This commit is contained in:
parent
a884021074
commit
7d301b91a7
@ -227,7 +227,7 @@ impl ConnectionOps for WaylandConnection {
|
||||
// there may be others to deal with
|
||||
Duration::new(0, 0)
|
||||
} else {
|
||||
Duration::from_millis(2500)
|
||||
Duration::from_secs(86400)
|
||||
};
|
||||
self.flush()?;
|
||||
{
|
||||
|
@ -11,7 +11,7 @@ use std::collections::HashMap;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::rc::Rc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::{Duration, Instant};
|
||||
use std::time::Duration;
|
||||
use xcb_util::ffi::keysyms::{xcb_key_symbols_alloc, xcb_key_symbols_free, xcb_key_symbols_t};
|
||||
|
||||
pub struct XConnection {
|
||||
@ -169,20 +169,7 @@ impl ConnectionOps for XConnection {
|
||||
PollOpt::level(),
|
||||
)?;
|
||||
|
||||
let paint_interval = Duration::from_millis(25);
|
||||
let mut last_interval = Instant::now();
|
||||
|
||||
while !*self.should_terminate.borrow() {
|
||||
let now = Instant::now();
|
||||
let diff = now - last_interval;
|
||||
let period = if diff >= paint_interval {
|
||||
self.do_paint();
|
||||
last_interval = now;
|
||||
paint_interval
|
||||
} else {
|
||||
paint_interval - diff
|
||||
};
|
||||
|
||||
// Process any events that might have accumulated in the local
|
||||
// buffer (eg: due to a flush) before we potentially go to sleep.
|
||||
// The locally queued events won't mark the fd as ready, so we
|
||||
@ -199,7 +186,7 @@ impl ConnectionOps for XConnection {
|
||||
// there may be others to deal with
|
||||
Duration::new(0, 0)
|
||||
} else {
|
||||
period
|
||||
Duration::from_secs(86400)
|
||||
};
|
||||
|
||||
match poll.poll(&mut events, Some(period)) {
|
||||
@ -425,14 +412,6 @@ impl XConnection {
|
||||
self.atom_delete
|
||||
}
|
||||
|
||||
/// Run through all of the windows and cause them to paint if they need it.
|
||||
fn do_paint(&self) {
|
||||
for window in self.windows.borrow().values() {
|
||||
window.lock().unwrap().paint().unwrap();
|
||||
}
|
||||
self.conn.flush();
|
||||
}
|
||||
|
||||
pub(crate) fn with_window_inner<
|
||||
R,
|
||||
F: FnOnce(&mut XWindowInner) -> anyhow::Result<R> + Send + 'static,
|
||||
|
@ -5,8 +5,8 @@ use crate::os::xkeysyms;
|
||||
use crate::os::{Connection, Window};
|
||||
use crate::{
|
||||
Clipboard, Dimensions, MouseButtons, MouseCursor, MouseEvent, MouseEventKind, MousePress,
|
||||
Point, Rect, ScreenPoint, Size, WindowDecorations, WindowEvent, WindowEventReceiver,
|
||||
WindowEventSender, WindowOps,
|
||||
Point, ScreenPoint, WindowDecorations, WindowEvent, WindowEventReceiver, WindowEventSender,
|
||||
WindowOps,
|
||||
};
|
||||
use anyhow::{anyhow, Context as _};
|
||||
use async_trait::async_trait;
|
||||
@ -15,7 +15,6 @@ use promise::{Future, Promise};
|
||||
use raw_window_handle::unix::XcbHandle;
|
||||
use raw_window_handle::{HasRawWindowHandle, RawWindowHandle};
|
||||
use std::any::Any;
|
||||
use std::collections::VecDeque;
|
||||
use std::convert::TryInto;
|
||||
use std::rc::{Rc, Weak};
|
||||
use std::sync::{Arc, Mutex};
|
||||
@ -59,8 +58,6 @@ pub(crate) struct XWindowInner {
|
||||
width: u16,
|
||||
height: u16,
|
||||
dpi: f64,
|
||||
expose: VecDeque<Rect>,
|
||||
paint_all: bool,
|
||||
cursors: CursorInfo,
|
||||
copy_and_paste: CopyAndPaste,
|
||||
config: ConfigHandle,
|
||||
@ -68,16 +65,6 @@ pub(crate) struct XWindowInner {
|
||||
resize_promises: Vec<Promise<Dimensions>>,
|
||||
}
|
||||
|
||||
fn enclosing_boundary_with(a: &Rect, b: &Rect) -> Rect {
|
||||
let left = a.min_x().min(b.min_x());
|
||||
let right = a.max_x().max(b.max_x());
|
||||
|
||||
let top = a.min_y().min(b.min_y());
|
||||
let bottom = a.max_y().max(b.max_y());
|
||||
|
||||
Rect::new(Point::new(left, top), Size::new(right - left, bottom - top))
|
||||
}
|
||||
|
||||
impl Drop for XWindowInner {
|
||||
fn drop(&mut self) {
|
||||
if let Some(conn) = self.conn.upgrade() {
|
||||
@ -131,33 +118,13 @@ impl XWindowInner {
|
||||
Ok(gl_state)
|
||||
}
|
||||
|
||||
pub fn paint(&mut self) -> anyhow::Result<()> {
|
||||
if !self.paint_all && self.expose.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
self.paint_all = false;
|
||||
self.expose.clear();
|
||||
self.events.try_send(WindowEvent::NeedRepaint).ok();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Add a region to the list of exposed/damaged/dirty regions.
|
||||
/// Note that a window resize will likely invalidate the entire window.
|
||||
/// If the new region intersects with the prior region, then we expand
|
||||
/// it to encompass both. This avoids bloating the list with a series
|
||||
/// of increasing rectangles when resizing larger or smaller.
|
||||
fn expose(&mut self, x: u16, y: u16, width: u16, height: u16) {
|
||||
let expose = Rect::new(
|
||||
Point::new(x as isize, y as isize),
|
||||
Size::new(width as isize, height as isize),
|
||||
);
|
||||
if let Some(prior) = self.expose.back_mut() {
|
||||
if prior.intersects(&expose) {
|
||||
*prior = enclosing_boundary_with(&prior, &expose);
|
||||
return;
|
||||
}
|
||||
}
|
||||
self.expose.push_back(expose);
|
||||
fn expose(&mut self, _x: u16, _y: u16, _width: u16, _height: u16) {
|
||||
self.events.try_send(WindowEvent::NeedRepaint).ok();
|
||||
}
|
||||
|
||||
fn do_mouse_event(&mut self, event: MouseEvent) -> anyhow::Result<()> {
|
||||
@ -767,8 +734,6 @@ impl XWindow {
|
||||
width: width.try_into()?,
|
||||
height: height.try_into()?,
|
||||
dpi: conn.default_dpi(),
|
||||
expose: VecDeque::new(),
|
||||
paint_all: true,
|
||||
copy_and_paste: CopyAndPaste::default(),
|
||||
cursors: CursorInfo::new(&conn),
|
||||
gl_state: None,
|
||||
@ -817,7 +782,7 @@ impl XWindowInner {
|
||||
xcb::map_window(self.conn().conn(), self.window_id);
|
||||
}
|
||||
fn invalidate(&mut self) {
|
||||
self.paint_all = true;
|
||||
self.events.try_send(WindowEvent::NeedRepaint).ok();
|
||||
}
|
||||
|
||||
fn toggle_fullscreen(&mut self) {
|
||||
|
Loading…
Reference in New Issue
Block a user