diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/handlers/compositor.rs | 2 | ||||
| -rw-r--r-- | src/input.rs | 6 | ||||
| -rw-r--r-- | src/niri.rs | 35 | ||||
| -rw-r--r-- | src/tty.rs | 28 | ||||
| -rw-r--r-- | src/winit.rs | 17 |
5 files changed, 57 insertions, 31 deletions
diff --git a/src/handlers/compositor.rs b/src/handlers/compositor.rs index b5f6291d..b2666f7f 100644 --- a/src/handlers/compositor.rs +++ b/src/handlers/compositor.rs @@ -41,6 +41,8 @@ impl CompositorHandler for Niri { xdg_shell::handle_commit(&self.space, surface); resize_grab::handle_commit(&mut self.space, surface); + + self.queue_redraw(); } } diff --git a/src/input.rs b/src/input.rs index 011378db..a8f85b3a 100644 --- a/src/input.rs +++ b/src/input.rs @@ -89,6 +89,9 @@ impl Niri { utime: event.time(), }, ); + + // Redraw to update the cursor position. + self.queue_redraw(); } InputEvent::PointerMotionAbsolute { event, .. } => { let output = self.space.outputs().next().unwrap(); @@ -112,6 +115,9 @@ impl Niri { time: event.time_msec(), }, ); + + // Redraw to update the cursor position. + self.queue_redraw(); } InputEvent::PointerButton { event, .. } => { let pointer = self.seat.get_pointer().unwrap(); diff --git a/src/niri.rs b/src/niri.rs index 8a0d0f03..9f0d3210 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -12,6 +12,7 @@ use smithay::input::keyboard::XkbConfig; use smithay::input::{Seat, SeatState}; use smithay::output::Output; use smithay::reexports::calloop::generic::Generic; +use smithay::reexports::calloop::timer::{TimeoutAction, Timer}; use smithay::reexports::calloop::{Interest, LoopHandle, LoopSignal, Mode, PostAction}; use smithay::reexports::wayland_server::backend::{ClientData, ClientId, DisconnectReason}; use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface; @@ -45,6 +46,11 @@ pub struct Niri { pub seat: Seat<Self>, pub output: Option<Output>, + + // Set to `true` if there's a redraw queued on the event loop. Reset to `false` in redraw() + // which means that you cannot queue more than one redraw at once. + pub redraw_queued: bool, + pub waiting_for_vblank: bool, } impl Niri { @@ -119,6 +125,8 @@ impl Niri { seat, output: None, + redraw_queued: false, + waiting_for_vblank: false, } } @@ -135,7 +143,32 @@ impl Niri { }) } - pub fn redraw(&mut self, backend: &mut dyn Backend) { + /// Schedules an immediate redraw if one is not already scheduled. + pub fn queue_redraw(&mut self) { + if self.redraw_queued || self.waiting_for_vblank { + return; + } + + self.redraw_queued = true; + + self.event_loop + .insert_source(Timer::immediate(), |_, _, data| { + let backend: &mut dyn Backend = if let Some(tty) = &mut data.tty { + tty + } else { + data.winit.as_mut().unwrap() + }; + data.niri.redraw(backend); + TimeoutAction::Drop + }) + .unwrap(); + } + + fn redraw(&mut self, backend: &mut dyn Backend) { + assert!(self.redraw_queued); + assert!(!self.waiting_for_vblank); + self.redraw_queued = false; + let elements = space_render_elements( backend.renderer(), [&self.space], @@ -1,6 +1,5 @@ use std::os::fd::FromRawFd; use std::path::PathBuf; -use std::time::Duration; use anyhow::anyhow; use smithay::backend::allocator::dmabuf::Dmabuf; @@ -17,7 +16,6 @@ use smithay::backend::session::libseat::LibSeatSession; use smithay::backend::session::{Event as SessionEvent, Session}; use smithay::backend::udev::{self, UdevBackend, UdevEvent}; use smithay::output::{Mode, Output, OutputModeSource, PhysicalProperties, Subpixel}; -use smithay::reexports::calloop::timer::{TimeoutAction, Timer}; use smithay::reexports::calloop::{LoopHandle, RegistrationToken}; use smithay::reexports::drm::control::connector::{ Interface as ConnectorInterface, State as ConnectorState, @@ -83,7 +81,7 @@ impl Backend for Tty { assert!(!res.needs_sync()); if res.damage.is_some() { match output_device.drm_compositor.queue_frame(()) { - Ok(()) => return, + Ok(()) => niri.waiting_for_vblank = true, Err(err) => { error!("error queueing frame: {err}"); } @@ -95,17 +93,6 @@ impl Backend for Tty { error!("error rendering frame: {err}"); } } - - // FIXME: render on demand instead of busy looping. - niri.event_loop - .insert_source( - Timer::from_duration(Duration::from_millis(6)), - |_, _, data| { - data.niri.redraw(data.tty.as_mut().unwrap()); - TimeoutAction::Drop - }, - ) - .unwrap(); } } @@ -157,7 +144,7 @@ impl Tty { output_device.drm_compositor.reset_buffers(); } - niri.redraw(tty); + niri.queue_redraw(); } } }) @@ -190,7 +177,7 @@ impl Tty { if let Err(err) = tty.device_added(device_id, path, niri) { warn!("error adding device: {err:?}"); } - niri.redraw(tty); + niri.queue_redraw(); } UdevEvent::Changed { device_id } => tty.device_changed(device_id, niri), UdevEvent::Removed { device_id } => tty.device_removed(device_id, niri), @@ -198,7 +185,7 @@ impl Tty { }) .unwrap(); - niri.redraw(self); + niri.queue_redraw(); } fn device_added( @@ -250,11 +237,8 @@ impl Tty { // .windows // .mark_presented(&output_device.last_render_states, metadata); - // Request redraw before the next VBlank. - // let frame_interval = catacomb.windows.output().frame_interval(); - // let duration = frame_interval - RENDER_TIME_OFFSET; - // catacomb.backend.schedule_redraw(duration); - data.niri.redraw(tty); + data.niri.waiting_for_vblank = false; + data.niri.queue_redraw(); } DrmEvent::Error(error) => error!("DRM error: {error}"), }; diff --git a/src/winit.rs b/src/winit.rs index 51d86c20..458ff95a 100644 --- a/src/winit.rs +++ b/src/winit.rs @@ -115,16 +115,17 @@ impl Winit { ); } WinitEvent::Input(event) => niri.process_input_event(&mut |_| (), event), - _ => (), + WinitEvent::Focus(_) => (), + WinitEvent::Refresh => niri.queue_redraw(), }); - if let Err(WinitError::WindowClosed) = res { - niri.stop_signal.stop(); - return; - } else { - res.unwrap(); + // I want this to stop compiling if more errors are added. + #[allow(clippy::single_match)] + match res { + Err(WinitError::WindowClosed) => { + niri.stop_signal.stop(); + } + Ok(()) => (), } - - niri.redraw(self); } } |
