From 6d2a9b349470f905025c0a6be027a8ba8227b972 Mon Sep 17 00:00:00 2001 From: Max Verevkin Date: Mon, 18 Jul 2022 23:55:16 +0300 Subject: refactor --- src/bar_state.rs | 106 +++++++++++--------------------- src/main.rs | 181 ++++++++++++++++++++++++++---------------------------- src/status_cmd.rs | 9 +-- 3 files changed, 128 insertions(+), 168 deletions(-) (limited to 'src') diff --git a/src/bar_state.rs b/src/bar_state.rs index 8a2d8cf..e21d64a 100644 --- a/src/bar_state.rs +++ b/src/bar_state.rs @@ -1,4 +1,4 @@ -use std::cell::{Cell, RefCell}; +use std::cell::RefCell; use std::collections::BinaryHeap; use std::io; use std::rc::Rc; @@ -32,19 +32,11 @@ use crate::text; use crate::text::{ComputedText, RenderOptions}; use crate::Env; -#[derive(PartialEq, Copy, Clone)] -enum RenderEvent { - Configure { width: u32, height: u32 }, - TagsUpdated, - Closed, -} - pub struct BarState { pub status_cmd: Option, config: Rc>, blocks: Vec, blocks_cache: Vec, - blocks_updated: bool, surfaces: Vec, layer_shell: Attached, river_status: Option>, @@ -73,8 +65,7 @@ impl BarState { config: Rc::new(RefCell::new(config)), blocks: Vec::new(), blocks_cache: Vec::new(), - blocks_updated: false, - surfaces: Default::default(), + surfaces: Vec::default(), layer_shell: env.require_global::(), river_status: env.get_global::(), river_control: env.get_global::(), @@ -89,7 +80,9 @@ impl BarState { pub fn set_blocks(&mut self, blocks: Vec) { self.blocks = blocks; - self.blocks_updated = true; + for s in &mut self.surfaces { + s.dirty = true; + } } pub fn set_error(&mut self, error: impl Into) { @@ -154,25 +147,27 @@ impl BarState { | zwlr_layer_surface_v1::Anchor::Right, ); - let next_render_event = Rc::new(Cell::new(None)); - let next_render_event_handle = Rc::clone(&next_render_event); - layer_surface.quick_assign(move |layer_surface, event, _| { - match (event, next_render_event_handle.get()) { - (zwlr_layer_surface_v1::Event::Closed, _) => { - next_render_event_handle.set(Some(RenderEvent::Closed)); + layer_surface.quick_assign(move |layer_surface, event, mut data| { + let bar_state: &mut BarState = data.get().unwrap(); + match event { + zwlr_layer_surface_v1::Event::Closed => { + bar_state.surfaces.retain(|s| s.output_id != output_id); } - ( - zwlr_layer_surface_v1::Event::Configure { - serial, - width, - height, - }, - next, - ) if next != Some(RenderEvent::Closed) => { + zwlr_layer_surface_v1::Event::Configure { + serial, + width, + height, + } => { layer_surface.ack_configure(serial); - next_render_event_handle.set(Some(RenderEvent::Configure { width, height })); + for s in &mut bar_state.surfaces { + if s.output_id == output_id && s.dimensions != (width, height) { + s.dimensions = (width, height); + s.layer_surface.set_exclusive_zone(height as _); + s.dirty = true; + } + } } - (_, _) => (), + _ => (), } }); @@ -182,9 +177,9 @@ impl BarState { let (river_output_status, tags_info) = if let Some(river_status) = &self.river_status { let tags_info = Rc::new(RefCell::new(TagsInfo::default())); let tags_info_handle = Rc::clone(&tags_info); - let next_render_event_handle = Rc::clone(&next_render_event); let river_output_status = river_status.get_river_output_status(output); - river_output_status.quick_assign(move |_, event, _| { + river_output_status.quick_assign(move |_, event, mut data| { + let bar_state: &mut BarState = data.get().unwrap(); match event { zriver_output_status_v1::Event::FocusedTags { tags } => { tags_info_handle.borrow_mut().focused = tags; @@ -194,8 +189,10 @@ impl BarState { } _ => (), } - if next_render_event_handle.get().is_none() { - next_render_event_handle.set(Some(RenderEvent::TagsUpdated)); + for s in &mut bar_state.surfaces { + if s.output_id == output_id { + s.dirty = true; + } } }); (Some(river_output_status), Some(tags_info)) @@ -207,10 +204,10 @@ impl BarState { output_id, surface, layer_surface, - next_render_event, pool, dimensions: (0, 0), config: self.config.clone(), + dirty: true, river_output_status, river_control: self.river_control.clone(), tags_info, @@ -221,10 +218,11 @@ impl BarState { } pub fn handle_events(&mut self) { - self.surfaces.retain_mut(|surface| { - !surface.handle_events(&self.blocks, &mut self.blocks_cache, self.blocks_updated) - }); - self.blocks_updated = false; + for surface in &mut self.surfaces { + if surface.dirty { + surface.draw(&self.blocks, &mut self.blocks_cache); + } + } } } @@ -232,10 +230,10 @@ pub struct Surface { output_id: u32, surface: WlSurface, layer_surface: Main, - next_render_event: Rc>>, pool: AutoMemPool, dimensions: (u32, u32), config: Rc>, + dirty: bool, // river stuff river_output_status: Option>, river_control: Option>, @@ -248,37 +246,6 @@ pub struct Surface { } impl Surface { - /// Handles any events that have occurred since the last call, redrawing if needed. - /// Returns true if the surface should be dropped. - fn handle_events( - &mut self, - blocks: &[Block], - blocks_cache: &mut Vec, - blocks_updated: bool, - ) -> bool { - match self.next_render_event.take() { - Some(RenderEvent::Closed) => return true, - Some(RenderEvent::Configure { width, height }) => { - if self.dimensions != (width, height) { - self.dimensions = (width, height); - self.layer_surface.set_exclusive_zone(height as _); - self.draw(blocks, blocks_cache); - return false; - } - } - Some(RenderEvent::TagsUpdated) => { - self.draw(blocks, blocks_cache); - return false; - } - _ => (), - } - if blocks_updated { - self.draw(blocks, blocks_cache); - return false; - } - false - } - fn click( &self, button: PointerBtn, @@ -420,6 +387,7 @@ impl Surface { // Finally, commit the surface self.surface.commit(); + self.dirty = false; } } diff --git a/src/main.rs b/src/main.rs index 5633807..a77d1be 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,5 @@ +#![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] @@ -17,9 +19,6 @@ use smithay_client_toolkit::{ WaylandSource, }; -use std::cell::RefCell; -use std::rc::Rc; - mod bar_state; mod button_manager; mod color; @@ -64,38 +63,37 @@ fn main() { ) .expect("Initial roundtrip failed!"); - let bar_state = Rc::new(RefCell::new(BarState::new(&env))); + let mut bar_state = BarState::new(&env); let env_handle = env.clone(); - let bar_state_handle = Rc::clone(&bar_state); - let output_handler = move |output: wl_output::WlOutput, info: &OutputInfo| { - if info.obsolete { - info!("Output removed"); - bar_state_handle.borrow_mut().remove_surface(info.id); - output.release(); - } else { - info!("Output detected"); - let surface = env_handle.create_surface().detach(); - let pool = env_handle - .create_auto_pool() - .expect("Failed to create a memory pool!"); - bar_state_handle - .borrow_mut() - .add_surface(&output, info.id, surface, pool); - } - }; + let output_handler = + move |output: wl_output::WlOutput, info: &OutputInfo, bar_state: &mut BarState| { + if info.obsolete { + info!("Output removed"); + bar_state.remove_surface(info.id); + output.release(); + } else { + info!("Output detected"); + let surface = env_handle.create_surface().detach(); + let pool = env_handle + .create_auto_pool() + .expect("Failed to create a memory pool!"); + bar_state.add_surface(&output, info.id, surface, pool); + } + }; // 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); + output_handler(output, &info, &mut bar_state); } } // 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, _| output_handler(output, info)); + let _listner_handle = env.listen_for_outputs(move |output, info, mut data| { + output_handler(output, info, data.get().unwrap()) + }); // Right now river only supports one seat let cursor_theme = pointer::ThemeManager::init( @@ -108,95 +106,92 @@ fn main() { if seat_data.has_pointer && !seat_data.defunct { let pointer = seat.get_pointer(); let themed_pointer = cursor_theme.theme_pointer(pointer.detach()); - let bar_state_handle = bar_state.clone(); let seat = seat.clone(); let mut pos = (0.0, 0.0); let mut cur_surface = None; - pointer.quick_assign(move |_, event, _| 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.borrow_mut().handle_click( - cur_surface, - &seat, - pos.0, - pos.1, - button.into(), - ); + 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::Axis { - time: _, - axis, - value, - } if axis == wl_pointer::Axis::VerticalScroll => { - if let Some(cur_surface) = &cur_surface { - bar_state_handle.borrow_mut().handle_click( - cur_surface, - &seat, - pos.0, - pos.1, - if value > 0.0 { - PointerBtn::WheelDown - } else { - PointerBtn::WheelUp - }, - ); + 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 + }, + ); + } + } + _ => (), } - _ => (), }); } }); } - let mut event_loop = calloop::EventLoop::<()>::try_new().unwrap(); + let mut event_loop = calloop::EventLoop::::try_new().unwrap(); WaylandSource::new(queue) .quick_insert(event_loop.handle()) .unwrap(); - if let Some(cmd) = &bar_state.borrow().status_cmd { - let bar_state_handle = Rc::clone(&bar_state); - cmd.quick_insert(event_loop.handle(), bar_state_handle); + if let Some(cmd) = &bar_state.status_cmd { + cmd.quick_insert(event_loop.handle()); } loop { - { - // Using a new scope in order to be sure that `bar_state` will not be borrowed while - // dispatching the events - bar_state.borrow_mut().handle_events(); - } + bar_state.handle_events(); display.flush().unwrap(); - if let Err(e) = event_loop.dispatch(None, &mut ()) { - bar_state.borrow_mut().set_error(e.to_string()); + if let Err(e) = event_loop.dispatch(None, &mut bar_state) { + bar_state.set_error(e.to_string()); } } } diff --git a/src/status_cmd.rs b/src/status_cmd.rs index 7cbdead..a229200 100644 --- a/src/status_cmd.rs +++ b/src/status_cmd.rs @@ -1,8 +1,6 @@ -use std::cell::RefCell; use std::io::{BufRead, BufReader, Result, Write}; use std::os::unix::prelude::AsRawFd; use std::process::{Child, ChildStdin, ChildStdout, Command, Stdio}; -use std::rc::Rc; use smithay_client_toolkit::reexports::calloop::{self, LoopHandle}; @@ -64,7 +62,7 @@ impl StatusCmd { Ok(()) } - pub fn quick_insert(&self, handle: LoopHandle<()>, bar_state: Rc>) { + pub fn quick_insert(&self, handle: LoopHandle) { handle .insert_source( calloop::generic::Generic::new( @@ -75,12 +73,11 @@ impl StatusCmd { }, calloop::Mode::Level, ), - move |ready, _, _| { + move |ready, _, bar_state| { if ready.readable { - bar_state.borrow_mut().notify_available()?; + bar_state.notify_available()?; Ok(calloop::PostAction::Continue) } else { - let mut bar_state = bar_state.borrow_mut(); bar_state.set_error("error reading from status command"); if let Some(mut child) = bar_state.status_cmd.take() { let _ = child.child.kill(); -- cgit v1.3.1