summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml5
-rw-r--r--src/bar_state.rs106
-rw-r--r--src/main.rs181
-rw-r--r--src/status_cmd.rs9
4 files changed, 133 insertions, 168 deletions
diff --git a/Cargo.toml b/Cargo.toml
index c7f2121..5a2097f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -18,3 +18,8 @@ memchr = "2.4"
[build-dependencies]
wayland-scanner = "0.29"
+
+[profile.release]
+lto = "thin"
+strip = true
+debug = 1
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<StatusCmd>,
config: Rc<RefCell<Config>>,
blocks: Vec<Block>,
blocks_cache: Vec<ComputedBlock>,
- blocks_updated: bool,
surfaces: Vec<Surface>,
layer_shell: Attached<zwlr_layer_shell_v1::ZwlrLayerShellV1>,
river_status: Option<Attached<zriver_status_manager_v1::ZriverStatusManagerV1>>,
@@ -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::<zwlr_layer_shell_v1::ZwlrLayerShellV1>(),
river_status: env.get_global::<zriver_status_manager_v1::ZriverStatusManagerV1>(),
river_control: env.get_global::<zriver_control_v1::ZriverControlV1>(),
@@ -89,7 +80,9 @@ impl BarState {
pub fn set_blocks(&mut self, blocks: Vec<Block>) {
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<String>) {
@@ -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<zwlr_layer_surface_v1::ZwlrLayerSurfaceV1>,
- next_render_event: Rc<Cell<Option<RenderEvent>>>,
pool: AutoMemPool,
dimensions: (u32, u32),
config: Rc<RefCell<Config>>,
+ dirty: bool,
// river stuff
river_output_status: Option<Main<zriver_output_status_v1::ZriverOutputStatusV1>>,
river_control: Option<Attached<zriver_control_v1::ZriverControlV1>>,
@@ -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<ComputedBlock>,
- 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::<BarState>::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<RefCell<BarState>>) {
+ pub fn quick_insert(&self, handle: LoopHandle<BarState>) {
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();