diff options
| -rw-r--r-- | Cargo.lock | 51 | ||||
| -rw-r--r-- | Cargo.toml | 3 | ||||
| -rw-r--r-- | README.md | 1 | ||||
| -rw-r--r-- | src/bar.rs | 46 | ||||
| -rw-r--r-- | src/main.rs | 11 | ||||
| -rw-r--r-- | src/shared_state.rs | 1 | ||||
| -rw-r--r-- | src/state.rs | 65 |
7 files changed, 138 insertions, 40 deletions
@@ -146,12 +146,28 @@ dependencies = [ ] [[package]] +name = "futures" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "531ac96c6ff5fd7c62263c5e3c67a603af4fcaee2e1a0ae5565ba3a11e69e549" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] name = "futures-channel" version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "164713a5a0dcc3e7b4b1ed7d3b433cabc18025386f9339346e8daf15963cf7ac" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -189,6 +205,12 @@ dependencies = [ ] [[package]] +name = "futures-sink" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec93083a4aecafb2a80a885c9de1f0ccae9dbd32c2bb54b0c3a65690e0b8d2f2" + +[[package]] name = "futures-task" version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -200,9 +222,13 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ef6b17e481503ec85211fed8f39d1970f128935ca1f814cd32ac4a6842e84ab" dependencies = [ + "futures-channel", "futures-core", + "futures-io", "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", @@ -342,11 +368,14 @@ dependencies = [ "anyhow", "dirs-next", "env_logger", + "futures", "log", "memchr", "pangocairo", "serde", "serde_json", + "signal-hook", + "signal-hook-tokio", "thiserror", "tokio", "toml 0.7.3", @@ -725,6 +754,16 @@ dependencies = [ ] [[package]] +name = "signal-hook" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] name = "signal-hook-registry" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -734,6 +773,18 @@ dependencies = [ ] [[package]] +name = "signal-hook-tokio" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213241f76fb1e37e27de3b6aa1b068a2c333233b59cca6634f634b80a27ecf1e" +dependencies = [ + "futures-core", + "libc", + "signal-hook", + "tokio", +] + +[[package]] name = "slab" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -14,6 +14,9 @@ serde = { version = "1", features = ["derive"] } serde_json = "1" memchr = "2" thiserror = "1.0.38" +futures = "0.3" +signal-hook = "0.3" +signal-hook-tokio = { version = "0.3", features = ["futures-v0_3"] } wayrs-client = { version = "0.4", features = ["tokio"] } wayrs-utils = { version = "0.4.0-beta.0", features = ["cursor", "shm_alloc", "seats"] } @@ -16,6 +16,7 @@ A list of things that are missing (for now): - `river` support (obviously) - `short_text` switching is "progressive" (see https://github.com/i3/i3/issues/4113) - Support for rounded corners +- Show/hide with `pkill -SIGUSR1 i3bar-river` ## Installation @@ -3,11 +3,12 @@ use std::collections::BinaryHeap; use pangocairo::cairo; use wayrs_client::connection::Connection; +use wayrs_client::proxy::Proxy; use wayrs_utils::shm_alloc::BufferSpec; use crate::button_manager::ButtonManager; use crate::color::Color; -use crate::config::Config; +use crate::config::{Config, Position}; use crate::i3bar_protocol::{self, Block, MinWidth}; use crate::ord_adaptor::DefaultLess; use crate::pointer_btn::PointerBtn; @@ -20,7 +21,8 @@ use crate::wm_info_provider::WmInfo; pub struct Bar { pub output: WlOutput, pub output_reg_name: u32, - pub configured: bool, + pub hidden: bool, + pub mapped: bool, pub frame_cb: Option<WlCallback>, pub width: u32, pub height: u32, @@ -86,7 +88,7 @@ impl Bar { } pub fn frame(&mut self, conn: &mut Connection<State>, ss: &mut SharedState) { - assert!(self.configured); + assert!(self.mapped); let (pix_width, pix_height, scale_f) = match self.scale120 { Some(scale120) => ( @@ -242,7 +244,7 @@ impl Bar { } pub fn request_frame(&mut self, conn: &mut Connection<State>) { - if self.configured && self.frame_cb.is_none() { + if self.mapped && !self.hidden && self.frame_cb.is_none() { self.frame_cb = Some(self.surface.frame_with_cb(conn, |conn, state, cb, _| { if let Some(bar) = state.bars.iter_mut().find(|bar| bar.frame_cb == Some(cb)) { bar.frame_cb = None; @@ -252,6 +254,42 @@ impl Bar { self.surface.commit(conn); } } + + pub fn show(&mut self, conn: &mut Connection<State>, shared_state: &SharedState) { + assert!(!self.mapped); + + self.hidden = false; + + let config = &shared_state.config; + + self.layer_surface.set_size(conn, 0, config.height); + self.layer_surface.set_anchor(conn, config.position.into()); + self.layer_surface.set_margin( + conn, + config.margin_top, + config.margin_right, + config.margin_bottom, + config.margin_left, + ); + self.layer_surface.set_exclusive_zone( + conn, + (shared_state.config.height) as i32 + + if config.position == Position::Top { + shared_state.config.margin_bottom + } else { + shared_state.config.margin_top + }, + ); + + self.surface.commit(conn); + } + + pub fn hide(&mut self, conn: &mut Connection<State>) { + self.hidden = true; + self.mapped = false; + self.surface.attach(conn, WlBuffer::null(), 0, 0); + self.surface.commit(conn); + } } #[allow(clippy::too_many_arguments)] diff --git a/src/main.rs b/src/main.rs index 241cd19..d3457b5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,6 +20,11 @@ mod text; mod utils; mod wm_info_provider; +use signal_hook::consts::*; +use signal_hook_tokio::Signals; + +use futures::stream::StreamExt; + use wayrs_client::connection::Connection; use state::State; @@ -28,6 +33,8 @@ use state::State; async fn main() -> anyhow::Result<()> { env_logger::init(); + let mut signals = Signals::new([SIGUSR1])?; + let mut conn = Connection::connect()?; let globals = conn.async_collect_initial_globals().await?; let mut state = State::new(&mut conn, &globals); @@ -49,6 +56,10 @@ async fn main() -> anyhow::Result<()> { } conn.async_flush().await?; } + Some(signal) = signals.next() => match signal { + SIGUSR1 => state.toggle_visibility(&mut conn), + _ => unreachable!(), + } } } } diff --git a/src/shared_state.rs b/src/shared_state.rs index 7f88afa..1551f4d 100644 --- a/src/shared_state.rs +++ b/src/shared_state.rs @@ -2,6 +2,7 @@ use crate::{ config::Config, i3bar_protocol::Block, state::ComputedBlock, status_cmd::StatusCmd, wm_info_provider::WmInfoProvider, }; + use wayrs_utils::shm_alloc::ShmAlloc; pub struct SharedState { diff --git a/src/state.rs b/src/state.rs index 2cead3d..53ef4ff 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,4 +1,3 @@ -use crate::config::Position; use crate::protocol::*; use crate::wm_info_provider::*; @@ -25,6 +24,7 @@ pub struct State { seats: Seats, pointers: Vec<Pointer>, + pub hidden: bool, pub bars: Vec<Bar>, pub shared_state: SharedState, @@ -76,6 +76,7 @@ impl State { seats: Seats::bind(conn, globals), pointers: Vec::new(), + hidden: false, bars: Vec::new(), shared_state: SharedState { @@ -169,33 +170,11 @@ impl State { layer_surface_cb, ); - let config = &self.shared_state.config; - - layer_surface.set_size(conn, 0, config.height); - layer_surface.set_anchor(conn, config.position.into()); - layer_surface.set_margin( - conn, - config.margin_top, - config.margin_right, - config.margin_bottom, - config.margin_left, - ); - layer_surface.set_exclusive_zone( - conn, - (self.shared_state.config.height) as i32 - + if config.position == Position::Top { - self.shared_state.config.margin_bottom - } else { - self.shared_state.config.margin_top - }, - ); - - // Note: layer_surface is commited when we receive the scale factor of this output - - self.bars.push(Bar { + let mut bar = Bar { output, output_reg_name: global.name, - configured: false, + hidden: self.hidden, + mapped: false, frame_cb: None, width: 0, height: self.shared_state.config.height, @@ -210,7 +189,13 @@ impl State { tags_btns: Default::default(), tags_computed: Vec::new(), layout_name_computed: None, - }); + }; + + if !self.hidden { + bar.show(conn, &self.shared_state); + } + + self.bars.push(bar); } fn drop_bar(&mut self, conn: &mut Connection<Self>, bar_index: usize) { @@ -224,6 +209,17 @@ impl State { bar.output.release(conn); } } + + pub fn toggle_visibility(&mut self, conn: &mut Connection<Self>) { + self.hidden = !self.hidden; + for bar in &mut self.bars { + if self.hidden { + bar.hide(conn); + } else { + bar.show(conn, &self.shared_state); + } + } + } } impl SeatHandler for State { @@ -274,7 +270,7 @@ fn wl_registry_cb(conn: &mut Connection<State>, state: &mut State, event: &wl_re } fn wl_output_cb( - conn: &mut Connection<State>, + _: &mut Connection<State>, state: &mut State, output: WlOutput, event: wl_output::Event, @@ -286,12 +282,6 @@ fn wl_output_cb( .find(|bar| bar.output == output) .unwrap(); bar.scale = scale as u32; - // If bar is not configured yet, it is because we were waiting for the "scale" event - // before commiting the surface. Otherwise, there is no need to do any redrawing (we'll - // do that after "configure" event). - if !bar.configured { - bar.surface.commit(conn); - } } } @@ -308,13 +298,16 @@ fn layer_surface_cb( .iter_mut() .find(|bar| bar.layer_surface == layer_surface) .unwrap(); + if bar.hidden { + return; + } assert_ne!(args.width, 0); bar.width = args.width; bar.layer_surface.ack_configure(conn, args.serial); - if bar.configured { + if bar.mapped { bar.request_frame(conn); } else { - bar.configured = true; + bar.mapped = true; bar.frame(conn, &mut state.shared_state); } } |
