diff options
| -rw-r--r-- | src/bar.rs | 13 | ||||
| -rw-r--r-- | src/shared_state.rs | 2 | ||||
| -rw-r--r-- | src/state.rs | 14 | ||||
| -rw-r--r-- | src/status_cmd.rs | 10 | ||||
| -rw-r--r-- | src/wm_info_provider.rs | 61 | ||||
| -rw-r--r-- | src/wm_info_provider/river.rs | 53 |
6 files changed, 65 insertions, 88 deletions
@@ -60,17 +60,8 @@ impl Bar { _y: f64, ) -> anyhow::Result<()> { if let Some(tag) = self.tags_btns.click(x) { - if let Some(wm_info_provider) = &mut ss.wm_info_provider { - match button { - PointerBtn::Left => { - wm_info_provider.left_click_on_tag(conn, self.output, seat, tag) - } - PointerBtn::Right => { - wm_info_provider.right_click_on_tag(conn, self.output, seat, tag) - } - _ => return Ok(()), - } - } + ss.wm_info_provider + .click_on_tag(conn, self.output, seat, tag, button); } else if let Some((name, instance)) = self.blocks_btns.click(x) { if let Some(cmd) = &mut ss.status_cmd { cmd.send_click_event(&i3bar_protocol::Event { diff --git a/src/shared_state.rs b/src/shared_state.rs index 8ec1b60..2e87749 100644 --- a/src/shared_state.rs +++ b/src/shared_state.rs @@ -10,5 +10,5 @@ pub struct SharedState { pub config: Config, pub status_cmd: Option<StatusCmd>, pub blocks_cache: BlocksCache, - pub wm_info_provider: Option<Box<dyn WmInfoProvider>>, + pub wm_info_provider: WmInfoProvider, } diff --git a/src/state.rs b/src/state.rs index 6a1f701..23f8bea 100644 --- a/src/state.rs +++ b/src/state.rs @@ -14,7 +14,7 @@ use wayrs_utils::shm_alloc::ShmAlloc; use crate::{ bar::Bar, config::Config, i3bar_protocol::Block, pointer_btn::PointerBtn, - shared_state::SharedState, status_cmd::StatusCmd, wm_info_provider, + shared_state::SharedState, status_cmd::StatusCmd, }; pub struct State { @@ -85,7 +85,7 @@ impl State { config, status_cmd, blocks_cache: BlocksCache::default(), - wm_info_provider: wm_info_provider::bind_wayland(conn, globals, wm_info_cb), + wm_info_provider: WmInfoProvider::bind(conn, globals, wm_info_cb), }, cursor_theme, @@ -139,9 +139,7 @@ impl State { .bind_with_cb(conn, 2..=4, wl_output_cb) .expect("could not bind wl_output"); - if let Some(wm_info_provider) = &mut self.shared_state.wm_info_provider { - wm_info_provider.new_outut(conn, output); - } + self.shared_state.wm_info_provider.new_ouput(conn, output); let surface = self.wl_compositor.create_surface(conn); @@ -190,9 +188,9 @@ impl State { let bar = self.bars.swap_remove(bar_index); bar.surface.destroy(conn); bar.layer_surface.destroy(conn); - if let Some(wm_info_provider) = &mut self.shared_state.wm_info_provider { - wm_info_provider.output_removed(conn, bar.output); - } + self.shared_state + .wm_info_provider + .output_removed(conn, bar.output); if bar.output.version() >= 3 { bar.output.release(conn); } diff --git a/src/status_cmd.rs b/src/status_cmd.rs index 172bee2..476204e 100644 --- a/src/status_cmd.rs +++ b/src/status_cmd.rs @@ -1,4 +1,4 @@ -use std::io::Write; +use std::io::{BufWriter, Write}; use std::os::fd::{AsRawFd, RawFd}; use std::process::{Child, ChildStdin, ChildStdout, Command, Stdio}; @@ -13,7 +13,7 @@ use crate::i3bar_protocol::{Block, Event, Protocol}; pub struct StatusCmd { pub child: Child, pub output: ChildStdout, - input: ChildStdin, + input: BufWriter<ChildStdin>, protocol: Protocol, buf: Vec<u8>, } @@ -26,7 +26,7 @@ impl StatusCmd { .stdout(Stdio::piped()) .spawn()?; let output = child.stdout.take().unwrap(); - let input = child.stdin.take().unwrap(); + let input = BufWriter::new(child.stdin.take().unwrap()); nix::fcntl::fcntl( output.as_raw_fd(), nix::fcntl::F_SETFL(nix::fcntl::OFlag::O_NONBLOCK), @@ -57,7 +57,9 @@ impl StatusCmd { pub fn send_click_event(&mut self, event: &Event) -> Result<()> { if self.protocol.supports_clicks() { - writeln!(self.input, "{}", serde_json::to_string(event)?)?; + serde_json::to_writer(&mut self.input, event)?; + self.input.write_all(b"\n")?; + self.input.flush()?; } Ok(()) } diff --git a/src/wm_info_provider.rs b/src/wm_info_provider.rs index f5ac615..12e4fb8 100644 --- a/src/wm_info_provider.rs +++ b/src/wm_info_provider.rs @@ -1,37 +1,56 @@ mod river; -use std::any::Any; - use wayrs_client::connection::Connection; use wayrs_client::global::*; +use crate::pointer_btn::PointerBtn; use crate::protocol::*; use crate::state::State; -pub type WmInfoCallback = fn(&mut Connection<State>, &mut State, WlOutput, WmInfo); +pub enum WmInfoProvider { + None, + River(river::RiverInfoProvider), +} -pub trait WmInfoProvider { - fn as_any(&mut self) -> &mut dyn Any; +pub type WmInfoCallback = fn(&mut Connection<State>, &mut State, WlOutput, WmInfo); - fn new_outut(&mut self, conn: &mut Connection<State>, output: WlOutput); +impl WmInfoProvider { + pub fn bind( + conn: &mut Connection<State>, + globals: &Globals, + callback: WmInfoCallback, + ) -> WmInfoProvider { + let Some(river) = river::RiverInfoProvider::bind(conn, globals, callback) else { return Self::None }; + Self::River(river) + } - fn output_removed(&mut self, conn: &mut Connection<State>, output: WlOutput); + pub fn new_ouput(&mut self, conn: &mut Connection<State>, output: WlOutput) { + match self { + Self::None => (), + Self::River(river) => river.new_output(conn, output), + } + } - fn left_click_on_tag( - &mut self, - conn: &mut Connection<State>, - output: WlOutput, - seat: WlSeat, - tag: &str, - ); + pub fn output_removed(&mut self, conn: &mut Connection<State>, output: WlOutput) { + match self { + Self::None => (), + Self::River(river) => river.output_removed(conn, output), + } + } - fn right_click_on_tag( + pub fn click_on_tag( &mut self, conn: &mut Connection<State>, output: WlOutput, seat: WlSeat, tag: &str, - ); + btn: PointerBtn, + ) { + match self { + Self::None => (), + Self::River(river) => river.click_on_tag(conn, output, seat, tag, btn), + } + } } #[derive(Default)] @@ -46,13 +65,3 @@ pub struct Tag { pub is_active: bool, pub is_urgent: bool, } - -pub fn bind_wayland( - conn: &mut Connection<State>, - globals: &Globals, - callback: WmInfoCallback, -) -> Option<Box<dyn WmInfoProvider>> { - // TODO: add more providers - let river = river::RiverInfoProvider::bind(conn, globals, callback)?; - Some(Box::new(river)) -} diff --git a/src/wm_info_provider/river.rs b/src/wm_info_provider/river.rs index b432da4..c7740a3 100644 --- a/src/wm_info_provider/river.rs +++ b/src/wm_info_provider/river.rs @@ -1,14 +1,13 @@ -use std::any::Any; use std::ffi::CString; use wayrs_client::connection::Connection; -use wayrs_client::global::*; +use wayrs_client::{cstr, global::*}; use super::*; use crate::protocol::*; use crate::state::State; -pub(super) struct RiverInfoProvider { +pub struct RiverInfoProvider { status_manager: ZriverStatusManagerV1, control: ZriverControlV1, output_statuses: Vec<OutputStatus>, @@ -25,7 +24,7 @@ struct OutputStatus { } impl RiverInfoProvider { - pub(super) fn bind( + pub fn bind( conn: &mut Connection<State>, globals: &Globals, callback: WmInfoCallback, @@ -39,12 +38,8 @@ impl RiverInfoProvider { } } -impl WmInfoProvider for RiverInfoProvider { - fn as_any(&mut self) -> &mut dyn Any { - self - } - - fn new_outut(&mut self, conn: &mut Connection<State>, output: WlOutput) { +impl RiverInfoProvider { + pub fn new_output(&mut self, conn: &mut Connection<State>, output: WlOutput) { let status = self.status_manager .get_river_output_status_with_cb(conn, output, output_status_cb); @@ -58,7 +53,7 @@ impl WmInfoProvider for RiverInfoProvider { }); } - fn output_removed(&mut self, conn: &mut Connection<State>, output: WlOutput) { + pub fn output_removed(&mut self, conn: &mut Connection<State>, output: WlOutput) { let index = self .output_statuses .iter() @@ -68,32 +63,21 @@ impl WmInfoProvider for RiverInfoProvider { output_status.status.destroy(conn); } - fn left_click_on_tag( + pub fn click_on_tag( &mut self, conn: &mut Connection<State>, _: WlOutput, seat: WlSeat, tag: &str, + btn: PointerBtn, ) { let tag: u32 = tag.parse().unwrap(); - self.control - .add_argument(conn, CString::new("set-focused-tags").unwrap()); - self.control - .add_argument(conn, CString::new((1u32 << (tag - 1)).to_string()).unwrap()); - self.control - .run_command_with_cb(conn, seat, river_command_cb); - } - - fn right_click_on_tag( - &mut self, - conn: &mut Connection<State>, - _: WlOutput, - seat: WlSeat, - tag: &str, - ) { - let tag: u32 = tag.parse().unwrap(); - self.control - .add_argument(conn, CString::new("toggle-focused-tags").unwrap()); + let cmd = match btn { + PointerBtn::Left => cstr!("set-focused-tags"), + PointerBtn::Right => cstr!("toggle-focused-tags"), + _ => return, + }; + self.control.add_argument(conn, cmd.to_owned()); self.control .add_argument(conn, CString::new((1u32 << (tag - 1)).to_string()).unwrap()); self.control @@ -107,14 +91,7 @@ fn output_status_cb( output_status: ZriverOutputStatusV1, event: zriver_output_status_v1::Event, ) { - let river: &mut RiverInfoProvider = state - .shared_state - .wm_info_provider - .as_mut() - .unwrap() - .as_any() - .downcast_mut() - .unwrap(); + let WmInfoProvider::River(river) = &mut state.shared_state.wm_info_provider else { unreachable!() }; let status = river .output_statuses |
