summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs198
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());
}
}
}