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