Remove LoopData

The calloop Smithay update finally lets me do this.
This commit is contained in:
Ivan Molodetskikh
2023-09-24 17:30:06 +04:00
parent c422fdab0f
commit cd4f7c0378
6 changed files with 89 additions and 103 deletions
+42 -44
View File
@@ -39,7 +39,7 @@ use smithay_drm_extras::edid::EdidInfo;
use crate::config::Config; use crate::config::Config;
use crate::niri::{OutputRenderElements, State}; use crate::niri::{OutputRenderElements, State};
use crate::utils::get_monotonic_time; use crate::utils::get_monotonic_time;
use crate::{LoopData, Niri}; use crate::Niri;
const BACKGROUND_COLOR: [f32; 4] = [0.1, 0.1, 0.1, 1.]; const BACKGROUND_COLOR: [f32; 4] = [0.1, 0.1, 0.1, 1.];
const SUPPORTED_COLOR_FORMATS: &[Fourcc] = &[Fourcc::Argb8888, Fourcc::Abgr8888]; const SUPPORTED_COLOR_FORMATS: &[Fourcc] = &[Fourcc::Argb8888, Fourcc::Abgr8888];
@@ -47,7 +47,7 @@ const SUPPORTED_COLOR_FORMATS: &[Fourcc] = &[Fourcc::Argb8888, Fourcc::Abgr8888]
pub struct Tty { pub struct Tty {
config: Rc<RefCell<Config>>, config: Rc<RefCell<Config>>,
session: LibSeatSession, session: LibSeatSession,
udev_dispatcher: Dispatcher<'static, UdevBackend, LoopData>, udev_dispatcher: Dispatcher<'static, UdevBackend, State>,
primary_gpu_path: PathBuf, primary_gpu_path: PathBuf,
output_device: Option<OutputDevice>, output_device: Option<OutputDevice>,
connectors: Arc<Mutex<HashMap<String, Output>>>, connectors: Arc<Mutex<HashMap<String, Output>>>,
@@ -94,45 +94,44 @@ struct Surface {
} }
impl Tty { impl Tty {
pub fn new(config: Rc<RefCell<Config>>, event_loop: LoopHandle<'static, LoopData>) -> Self { pub fn new(config: Rc<RefCell<Config>>, event_loop: LoopHandle<'static, State>) -> Self {
let (session, notifier) = LibSeatSession::new().unwrap(); let (session, notifier) = LibSeatSession::new().unwrap();
let seat_name = session.seat(); let seat_name = session.seat();
let udev_backend = UdevBackend::new(session.seat()).unwrap(); let udev_backend = UdevBackend::new(session.seat()).unwrap();
let udev_dispatcher = let udev_dispatcher = Dispatcher::new(udev_backend, move |event, _, state: &mut State| {
Dispatcher::new(udev_backend, move |event, _, data: &mut LoopData| { let tty = state.backend.tty();
let tty = data.state.backend.tty(); let niri = &mut state.niri;
let niri = &mut data.state.niri;
match event { match event {
UdevEvent::Added { device_id, path } => { UdevEvent::Added { device_id, path } => {
if !tty.session.is_active() { if !tty.session.is_active() {
debug!("skipping UdevEvent::Added as session is inactive"); debug!("skipping UdevEvent::Added as session is inactive");
return; return;
}
if let Err(err) = tty.device_added(device_id, &path, niri) {
warn!("error adding device: {err:?}");
}
} }
UdevEvent::Changed { device_id } => {
if !tty.session.is_active() {
debug!("skipping UdevEvent::Changed as session is inactive");
return;
}
tty.device_changed(device_id, niri) if let Err(err) = tty.device_added(device_id, &path, niri) {
} warn!("error adding device: {err:?}");
UdevEvent::Removed { device_id } => {
if !tty.session.is_active() {
debug!("skipping UdevEvent::Removed as session is inactive");
return;
}
tty.device_removed(device_id, niri)
} }
} }
}); UdevEvent::Changed { device_id } => {
if !tty.session.is_active() {
debug!("skipping UdevEvent::Changed as session is inactive");
return;
}
tty.device_changed(device_id, niri)
}
UdevEvent::Removed { device_id } => {
if !tty.session.is_active() {
debug!("skipping UdevEvent::Removed as session is inactive");
return;
}
tty.device_removed(device_id, niri)
}
}
});
event_loop event_loop
.register_dispatcher(udev_dispatcher.clone()) .register_dispatcher(udev_dispatcher.clone())
.unwrap(); .unwrap();
@@ -142,17 +141,17 @@ impl Tty {
let input_backend = LibinputInputBackend::new(libinput.clone()); let input_backend = LibinputInputBackend::new(libinput.clone());
event_loop event_loop
.insert_source(input_backend, |mut event, _, data| { .insert_source(input_backend, |mut event, _, state| {
data.state.process_libinput_event(&mut event); state.process_libinput_event(&mut event);
data.state.process_input_event(event); state.process_input_event(event);
}) })
.unwrap(); .unwrap();
let udev_dispatcher_c = udev_dispatcher.clone(); let udev_dispatcher_c = udev_dispatcher.clone();
event_loop event_loop
.insert_source(notifier, move |event, _, data| { .insert_source(notifier, move |event, _, state| {
let tty = data.state.backend.tty(); let tty = state.backend.tty();
let niri = &mut data.state.niri; let niri = &mut state.niri;
match event { match event {
SessionEvent::PauseSession => { SessionEvent::PauseSession => {
@@ -303,8 +302,8 @@ impl Tty {
let token = niri let token = niri
.event_loop .event_loop
.insert_source(drm_notifier, move |event, metadata, data| { .insert_source(drm_notifier, move |event, metadata, state| {
let tty = data.state.backend.tty(); let tty = state.backend.tty();
match event { match event {
DrmEvent::VBlank(crtc) => { DrmEvent::VBlank(crtc) => {
let now = get_monotonic_time(); let now = get_monotonic_time();
@@ -349,8 +348,7 @@ impl Tty {
.unwrap() .unwrap()
.message(&message, 0); .message(&message, 0);
let output = data let output = state
.state
.niri .niri
.global_space .global_space
.outputs() .outputs()
@@ -360,7 +358,7 @@ impl Tty {
}) })
.unwrap() .unwrap()
.clone(); .clone();
let output_state = data.state.niri.output_state.get_mut(&output).unwrap(); let output_state = state.niri.output_state.get_mut(&output).unwrap();
// Mark the last frame as submitted. // Mark the last frame as submitted.
match surface.compositor.frame_submitted() { match surface.compositor.frame_submitted() {
@@ -398,7 +396,7 @@ impl Tty {
output_state.waiting_for_vblank = false; output_state.waiting_for_vblank = false;
output_state.frame_clock.presented(presentation_time); output_state.frame_clock.presented(presentation_time);
data.state.niri.queue_redraw(output); state.niri.queue_redraw(output);
} }
DrmEvent::Error(error) => error!("DRM error: {error}"), DrmEvent::Error(error) => error!("DRM error: {error}"),
}; };
+11 -14
View File
@@ -18,9 +18,9 @@ use smithay::utils::Transform;
use smithay::wayland::dmabuf::DmabufFeedback; use smithay::wayland::dmabuf::DmabufFeedback;
use crate::config::Config; use crate::config::Config;
use crate::niri::OutputRenderElements; use crate::niri::{OutputRenderElements, State};
use crate::utils::get_monotonic_time; use crate::utils::get_monotonic_time;
use crate::{LoopData, Niri}; use crate::Niri;
pub struct Winit { pub struct Winit {
config: Rc<RefCell<Config>>, config: Rc<RefCell<Config>>,
@@ -31,7 +31,7 @@ pub struct Winit {
} }
impl Winit { impl Winit {
pub fn new(config: Rc<RefCell<Config>>, event_loop: LoopHandle<LoopData>) -> Self { pub fn new(config: Rc<RefCell<Config>>, event_loop: LoopHandle<State>) -> Self {
let builder = WindowBuilder::new() let builder = WindowBuilder::new()
.with_inner_size(LogicalSize::new(1280.0, 800.0)) .with_inner_size(LogicalSize::new(1280.0, 800.0))
// .with_resizable(false) // .with_resizable(false)
@@ -79,10 +79,10 @@ impl Winit {
let timer = Timer::immediate(); let timer = Timer::immediate();
event_loop event_loop
.insert_source(timer, move |_, _, data| { .insert_source(timer, move |_, _, state| {
let res = winit_event_loop.dispatch_new_events(|event| match event { let res = winit_event_loop.dispatch_new_events(|event| match event {
WinitEvent::Resized { size, .. } => { WinitEvent::Resized { size, .. } => {
let winit = data.state.backend.winit(); let winit = state.backend.winit();
winit.output.change_current_state( winit.output.change_current_state(
Some(Mode { Some(Mode {
size, size,
@@ -92,24 +92,21 @@ impl Winit {
None, None,
None, None,
); );
data.state.niri.output_resized(winit.output.clone()); state.niri.output_resized(winit.output.clone());
} }
WinitEvent::Input(event) => data.state.process_input_event(event), WinitEvent::Input(event) => state.process_input_event(event),
WinitEvent::Focus(_) => (), WinitEvent::Focus(_) => (),
WinitEvent::Refresh => data WinitEvent::Refresh => state
.state
.niri .niri
.queue_redraw(data.state.backend.winit().output.clone()), .queue_redraw(state.backend.winit().output.clone()),
}); });
// I want this to stop compiling if more errors are added. // I want this to stop compiling if more errors are added.
#[allow(clippy::single_match)] #[allow(clippy::single_match)]
match res { match res {
Err(WinitError::WindowClosed) => { Err(WinitError::WindowClosed) => {
data.state.niri.stop_signal.stop(); state.niri.stop_signal.stop();
data.state state.niri.remove_output(&state.backend.winit().output);
.niri
.remove_output(&data.state.backend.winit().output);
} }
Ok(()) => (), Ok(()) => (),
} }
+4 -4
View File
@@ -47,11 +47,11 @@ impl CompositorHandler for State {
let res = state let res = state
.niri .niri
.event_loop .event_loop
.insert_source(source, move |_, _, data| { .insert_source(source, move |_, _, state| {
let display_handle = data.state.niri.display_handle.clone(); let display_handle = state.niri.display_handle.clone();
data.state state
.client_compositor_state(&client) .client_compositor_state(&client)
.blocker_cleared(&mut data.state, &display_handle); .blocker_cleared(state, &display_handle);
Ok(()) Ok(())
}); });
if res.is_ok() { if res.is_ok() {
+6 -11
View File
@@ -38,10 +38,6 @@ struct Cli {
command: Vec<OsString>, command: Vec<OsString>,
} }
pub struct LoopData {
state: State,
}
fn main() { fn main() {
env::set_var("RUST_BACKTRACE", "1"); env::set_var("RUST_BACKTRACE", "1");
@@ -68,13 +64,12 @@ fn main() {
let mut event_loop = EventLoop::try_new().unwrap(); let mut event_loop = EventLoop::try_new().unwrap();
let display = Display::new().unwrap(); let display = Display::new().unwrap();
let state = State::new( let mut state = State::new(
config, config,
event_loop.handle(), event_loop.handle(),
event_loop.get_signal(), event_loop.get_signal(),
display, display,
); );
let mut data = LoopData { state };
// Spawn commands from cli and auto-start. // Spawn commands from cli and auto-start.
if let Some((command, args)) = cli.command.split_first() { if let Some((command, args)) = cli.command.split_first() {
@@ -88,17 +83,17 @@ fn main() {
} }
event_loop event_loop
.run(None, &mut data, move |data| { .run(None, &mut state, move |state| {
let _span = tracy_client::span!("loop callback"); let _span = tracy_client::span!("loop callback");
// These should be called periodically, before flushing the clients. // These should be called periodically, before flushing the clients.
data.state.niri.monitor_set.refresh(); state.niri.monitor_set.refresh();
data.state.niri.popups.cleanup(); state.niri.popups.cleanup();
data.state.update_focus(); state.update_focus();
{ {
let _span = tracy_client::span!("flush_clients"); let _span = tracy_client::span!("flush_clients");
data.state.niri.display_handle.flush_clients().unwrap(); state.niri.display_handle.flush_clients().unwrap();
} }
}) })
.unwrap(); .unwrap();
+24 -28
View File
@@ -70,12 +70,11 @@ use crate::frame_clock::FrameClock;
use crate::layout::{MonitorRenderElement, MonitorSet}; use crate::layout::{MonitorRenderElement, MonitorSet};
use crate::pw_utils::{Cast, PipeWire}; use crate::pw_utils::{Cast, PipeWire};
use crate::utils::{center, get_monotonic_time, load_default_cursor, make_screenshot_path}; use crate::utils::{center, get_monotonic_time, load_default_cursor, make_screenshot_path};
use crate::LoopData;
pub struct Niri { pub struct Niri {
pub config: Rc<RefCell<Config>>, pub config: Rc<RefCell<Config>>,
pub event_loop: LoopHandle<'static, LoopData>, pub event_loop: LoopHandle<'static, State>,
pub stop_signal: LoopSignal, pub stop_signal: LoopSignal,
pub display_handle: DisplayHandle, pub display_handle: DisplayHandle,
@@ -139,7 +138,7 @@ pub struct State {
impl State { impl State {
pub fn new( pub fn new(
config: Config, config: Config,
event_loop: LoopHandle<'static, LoopData>, event_loop: LoopHandle<'static, State>,
stop_signal: LoopSignal, stop_signal: LoopSignal,
display: Display<State>, display: Display<State>,
) -> Self { ) -> Self {
@@ -201,7 +200,7 @@ impl State {
impl Niri { impl Niri {
pub fn new( pub fn new(
config: Rc<RefCell<Config>>, config: Rc<RefCell<Config>>,
event_loop: LoopHandle<'static, LoopData>, event_loop: LoopHandle<'static, State>,
stop_signal: LoopSignal, stop_signal: LoopSignal,
display: Display<State>, display: Display<State>,
backend: &Backend, backend: &Backend,
@@ -244,9 +243,8 @@ impl Niri {
let socket_source = ListeningSocketSource::new_auto().unwrap(); let socket_source = ListeningSocketSource::new_auto().unwrap();
let socket_name = socket_source.socket_name().to_os_string(); let socket_name = socket_source.socket_name().to_os_string();
event_loop event_loop
.insert_source(socket_source, move |client, _, data| { .insert_source(socket_source, move |client, _, state| {
if let Err(err) = data if let Err(err) = state
.state
.niri .niri
.display_handle .display_handle
.insert_client(client, Arc::new(ClientState::default())) .insert_client(client, Arc::new(ClientState::default()))
@@ -273,7 +271,7 @@ impl Niri {
event_loop event_loop
.insert_source(from_screen_cast, { .insert_source(from_screen_cast, {
let to_niri = to_niri.clone(); let to_niri = to_niri.clone();
move |event, _, data| match event { move |event, _, state| match event {
calloop::channel::Event::Msg(msg) => match msg { calloop::channel::Event::Msg(msg) => match msg {
ToNiriMsg::StartCast { ToNiriMsg::StartCast {
session_id, session_id,
@@ -285,7 +283,7 @@ impl Niri {
debug!(session_id, "StartCast"); debug!(session_id, "StartCast");
let gbm = match data.state.backend.gbm_device() { let gbm = match state.backend.gbm_device() {
Some(gbm) => gbm, Some(gbm) => gbm,
None => { None => {
debug!("no GBM device available"); debug!("no GBM device available");
@@ -293,7 +291,7 @@ impl Niri {
} }
}; };
let pw = data.state.niri.pipewire.as_ref().unwrap(); let pw = state.niri.pipewire.as_ref().unwrap();
match pw.start_cast( match pw.start_cast(
to_niri.clone(), to_niri.clone(),
gbm, gbm,
@@ -303,7 +301,7 @@ impl Niri {
signal_ctx, signal_ctx,
) { ) {
Ok(cast) => { Ok(cast) => {
data.state.niri.casts.push(cast); state.niri.casts.push(cast);
} }
Err(err) => { Err(err) => {
warn!("error starting screencast: {err:?}"); warn!("error starting screencast: {err:?}");
@@ -321,20 +319,19 @@ impl Niri {
debug!(session_id, "StopCast"); debug!(session_id, "StopCast");
for i in (0..data.state.niri.casts.len()).rev() { for i in (0..state.niri.casts.len()).rev() {
let cast = &data.state.niri.casts[i]; let cast = &state.niri.casts[i];
if cast.session_id != session_id { if cast.session_id != session_id {
continue; continue;
} }
let cast = data.state.niri.casts.swap_remove(i); let cast = state.niri.casts.swap_remove(i);
if let Err(err) = cast.stream.disconnect() { if let Err(err) = cast.stream.disconnect() {
warn!("error disconnecting stream: {err:?}"); warn!("error disconnecting stream: {err:?}");
} }
} }
let server = let server = state.niri.zbus_conn.as_ref().unwrap().object_server();
data.state.niri.zbus_conn.as_ref().unwrap().object_server();
let path = let path =
format!("/org/gnome/Mutter/ScreenCast/Session/u{}", session_id); format!("/org/gnome/Mutter/ScreenCast/Session/u{}", session_id);
if let Ok(iface) = if let Ok(iface) =
@@ -360,11 +357,11 @@ impl Niri {
let (to_niri, from_screenshot) = calloop::channel::channel(); let (to_niri, from_screenshot) = calloop::channel::channel();
let (to_screenshot, from_niri) = async_channel::unbounded(); let (to_screenshot, from_niri) = async_channel::unbounded();
event_loop event_loop
.insert_source(from_screenshot, move |event, _, data| match event { .insert_source(from_screenshot, move |event, _, state| match event {
calloop::channel::Event::Msg(ScreenshotToNiri::TakeScreenshot { calloop::channel::Event::Msg(ScreenshotToNiri::TakeScreenshot {
include_cursor, include_cursor,
}) => { }) => {
let renderer = data.state.backend.renderer(); let renderer = state.backend.renderer();
let on_done = { let on_done = {
let to_screenshot = to_screenshot.clone(); let to_screenshot = to_screenshot.clone();
move |path| { move |path| {
@@ -375,10 +372,9 @@ impl Niri {
} }
}; };
let res = let res = state
data.state .niri
.niri .screenshot_all_outputs(renderer, include_cursor, on_done);
.screenshot_all_outputs(renderer, include_cursor, on_done);
if let Err(err) = res { if let Err(err) = res {
warn!("error taking a screenshot: {err:?}"); warn!("error taking a screenshot: {err:?}");
@@ -536,10 +532,10 @@ impl Niri {
let display_source = Generic::new(display, Interest::READ, Mode::Level); let display_source = Generic::new(display, Interest::READ, Mode::Level);
event_loop event_loop
.insert_source(display_source, |_, display, data| { .insert_source(display_source, |_, display, state| {
// SAFETY: we don't drop the display. // SAFETY: we don't drop the display.
unsafe { unsafe {
display.get_mut().dispatch_clients(&mut data.state).unwrap(); display.get_mut().dispatch_clients(state).unwrap();
} }
Ok(PostAction::Continue) Ok(PostAction::Continue)
}) })
@@ -624,8 +620,8 @@ impl Niri {
self.event_loop self.event_loop
.insert_source( .insert_source(
Timer::from_duration(Duration::from_secs(10)), Timer::from_duration(Duration::from_secs(10)),
move |_, _, data| { move |_, _, state| {
data.state state
.niri .niri
.display_handle .display_handle
.remove_global::<State>(global.clone()); .remove_global::<State>(global.clone());
@@ -788,8 +784,8 @@ impl Niri {
// Timer::immediate() adds a millisecond of delay for some reason. // Timer::immediate() adds a millisecond of delay for some reason.
// This should be fixed in calloop v0.11: https://github.com/Smithay/calloop/issues/142 // This should be fixed in calloop v0.11: https://github.com/Smithay/calloop/issues/142
let idle = self.event_loop.insert_idle(move |data| { let idle = self.event_loop.insert_idle(move |state| {
data.state.niri.redraw(&mut data.state.backend, &output); state.niri.redraw(&mut state.backend, &output);
}); });
state.queued_redraw = Some(idle); state.queued_redraw = Some(idle);
} }
+2 -2
View File
@@ -30,7 +30,7 @@ use smithay::reexports::gbm::Modifier;
use zbus::SignalContext; use zbus::SignalContext;
use crate::dbus::mutter_screen_cast::{self, CursorMode, ToNiriMsg}; use crate::dbus::mutter_screen_cast::{self, CursorMode, ToNiriMsg};
use crate::LoopData; use crate::niri::State;
pub struct PipeWire { pub struct PipeWire {
_context: Context<MainLoop>, _context: Context<MainLoop>,
@@ -50,7 +50,7 @@ pub struct Cast {
} }
impl PipeWire { impl PipeWire {
pub fn new(event_loop: &LoopHandle<'static, LoopData>) -> anyhow::Result<Self> { pub fn new(event_loop: &LoopHandle<'static, State>) -> anyhow::Result<Self> {
let main_loop = MainLoop::new().context("error creating MainLoop")?; let main_loop = MainLoop::new().context("error creating MainLoop")?;
let context = Context::new(&main_loop).context("error creating Context")?; let context = Context::new(&main_loop).context("error creating Context")?;
let core = context.connect(None).context("error creating Core")?; let core = context.connect(None).context("error creating Core")?;