diff options
Diffstat (limited to 'src/main.rs')
| -rw-r--r-- | src/main.rs | 198 |
1 files changed, 36 insertions, 162 deletions
diff --git a/src/main.rs b/src/main.rs index 730edf6..b158c91 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,25 +1,9 @@ -#![allow(clippy::explicit_auto_deref)] // TODO: remove once https://github.com/rust-lang/rust-clippy/issues/9101 is resloved - -#[macro_use] -extern crate log; #[macro_use] extern crate anyhow; +#[macro_use] +extern crate log; -use smithay_client_toolkit::{ - self as sctk, default_environment, - environment::SimpleGlobal, - new_default_environment, - output::{with_output_info, OutputInfo}, - reexports::{ - calloop, - client::protocol::{wl_output::WlOutput, wl_pointer}, - protocols::wlr::unstable::layer_shell::v1::client::zwlr_layer_shell_v1, - }, - seat::pointer, - WaylandSource, -}; - -mod bar_state; +mod bar; mod button_manager; mod color; mod config; @@ -27,163 +11,53 @@ mod i3bar_protocol; mod ord_adaptor; mod pointer_btn; mod river_protocols; +mod shared_state; +mod state; mod status_cmd; mod tags; mod text; mod utils; -use bar_state::BarState; -use pointer_btn::PointerBtn; -use river_protocols::zriver_control_v1; -use river_protocols::zriver_status_manager_v1; +use smithay_client_toolkit::reexports::client::Connection; +use tokio::io::{unix::AsyncFd, Interest}; -default_environment!(Env, - fields = [ - layer_shell: SimpleGlobal<zwlr_layer_shell_v1::ZwlrLayerShellV1>, - river_status_manager: SimpleGlobal<zriver_status_manager_v1::ZriverStatusManagerV1>, - river_control: SimpleGlobal<zriver_control_v1::ZriverControlV1>, - ], - singles = [ - zwlr_layer_shell_v1::ZwlrLayerShellV1 => layer_shell, - zriver_status_manager_v1::ZriverStatusManagerV1 => river_status_manager, - zriver_control_v1::ZriverControlV1 => river_control, - ], -); +use state::State; -fn main() { +#[tokio::main(flavor = "current_thread")] +async fn main() -> anyhow::Result<()> { env_logger::init(); - let (env, _display, queue) = new_default_environment!( - Env, - fields = [ - layer_shell: SimpleGlobal::new(), - river_status_manager: SimpleGlobal::new(), - river_control: SimpleGlobal::new(), - ] - ) - .expect("Initial roundtrip failed!"); - - let mut bar_state = BarState::new(&env); + let conn = Connection::connect_to_env()?; + let mut event_queue = conn.new_event_queue(); + let mut state = State::new(&conn, &mut event_queue); - let env_handle = env.clone(); - let output_handler = move |output: WlOutput, info: &OutputInfo, bar_state: &mut BarState| { - if info.obsolete { - info!("Output {} removed", info.id); - output.release(); - } else { - info!("Output {} detected", info.id); - bar_state.add_surface(&output, info.id, &env_handle); - } - }; - - // Process currently existing outputs - for output in env.get_all_outputs() { - if let Some(info) = with_output_info(&output, Clone::clone) { - output_handler(output, &info, &mut bar_state); - } - } + let async_fd = AsyncFd::with_interest( + event_queue.prepare_read()?.connection_fd(), + Interest::READABLE, + )?; - // Setup a listener for changes - // The listener will live for as long as we keep this handle alive - let _listner_handle = env.listen_for_outputs(move |output, info, mut data| { - output_handler(output, info, data.get().unwrap()) - }); + event_queue.roundtrip(&mut state)?; + event_queue.flush()?; - // Right now river only supports one seat - let cursor_theme = pointer::ThemeManager::init( - pointer::ThemeSpec::System, - env.require_global(), - env.require_global(), - ); - for seat in env.get_all_seats() { - sctk::seat::with_seat_data(&seat, |seat_data| { - if seat_data.has_pointer && !seat_data.defunct { - let pointer = seat.get_pointer(); - let themed_pointer = cursor_theme.theme_pointer(pointer.detach()); - let seat = seat.clone(); - let mut pos = (0.0, 0.0); - let mut cur_surface = None; - pointer.quick_assign(move |_, event, mut data| { - let bar_state: &mut BarState = data.get().unwrap(); - match event { - wl_pointer::Event::Enter { - serial, - surface, - surface_x: y, - surface_y: x, - } => { - let _ = themed_pointer.set_cursor("default", Some(serial)); - cur_surface = Some(surface); - pos = (x, y); - } - wl_pointer::Event::Leave { - serial: _, - surface: _, - } => { - cur_surface = None; - } - wl_pointer::Event::Motion { - time: _, - surface_x: x, - surface_y: y, - } => { - pos = (x, y); - } - wl_pointer::Event::Button { - serial: _, - time: _, - button, - state, - } if state == wl_pointer::ButtonState::Pressed => { - if let Some(cur_surface) = &cur_surface { - bar_state.handle_click( - cur_surface, - &seat, - pos.0, - pos.1, - button.into(), - ); - } - } - wl_pointer::Event::Axis { - time: _, - axis, - value, - } if axis == wl_pointer::Axis::VerticalScroll => { - if let Some(cur_surface) = &cur_surface { - bar_state.handle_click( - cur_surface, - &seat, - pos.0, - pos.1, - if value > 0.0 { - PointerBtn::WheelDown - } else { - PointerBtn::WheelUp - }, - ); - } - } - _ => (), + loop { + tokio::select! { + readable = async_fd.readable() => { + readable?.clear_ready(); + event_queue.prepare_read()?.read()?; + event_queue.dispatch_pending(&mut state)?; + event_queue.flush()?; + } + readable = state.wait_for_status_cmd() => { + readable?.clear_ready(); + if let Err(e) = state.notify_available() { + if let Some(mut status_cmd) = state.shared_state.as_mut().unwrap().status_cmd.take() { + let _ = status_cmd.child.kill(); } - }); + state.set_error(e.to_string()); + state.draw_all(); + } + event_queue.flush()?; } - }); - } - - let mut event_loop = calloop::EventLoop::<BarState>::try_new().unwrap(); - - WaylandSource::new(queue) - .quick_insert(event_loop.handle()) - .unwrap(); - - if let Some(cmd) = &bar_state.status_cmd { - cmd.quick_insert(event_loop.handle()); - } - - loop { - if let Err(e) = event_loop.dispatch(None, &mut bar_state) { - bar_state.set_error(e.to_string()); } } } |
