From 85f837ae706d6f64769597158a39c49259c8b189 Mon Sep 17 00:00:00 2001 From: Max Verevkin <34583604+MaxVerevkin@users.noreply.github.com> Date: Sat, 26 Aug 2023 17:19:29 +0300 Subject: show current mode on river (can be turned off) (#15) --- src/bar.rs | 39 ++++++++++++++++++++++++++ src/config.rs | 2 ++ src/state.rs | 14 +++++++++ src/wm_info_provider.rs | 1 + src/wm_info_provider/ext_workspace_unstable.rs | 4 +++ src/wm_info_provider/river.rs | 36 +++++++++++++++++++++++- 6 files changed, 95 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/bar.rs b/src/bar.rs index 45fbc88..7cf53b9 100644 --- a/src/bar.rs +++ b/src/bar.rs @@ -31,9 +31,11 @@ pub struct Bar { pub blocks_btns: ButtonManager<(Option, Option)>, pub tags: Vec, pub layout_name: Option, + pub mode_name: Option, pub tags_btns: ButtonManager, pub tags_computed: Vec<(ColorPair, ComputedText)>, pub layout_name_computed: Option, + pub mode_computed: Option, } #[derive(Debug, PartialEq)] @@ -54,6 +56,11 @@ impl Bar { self.layout_name_computed = None; } + pub fn set_mode_name(&mut self, mode_name: Option) { + self.mode_name = mode_name; + self.mode_computed = None; + } + pub fn click( &mut self, conn: &mut Connection, @@ -223,6 +230,38 @@ impl Bar { } } + // Display mode + if ss.config.show_mode { + if let Some(mode) = &self.mode_name { + let text = self.mode_computed.get_or_insert_with(|| { + ComputedText::new( + mode, + text::Attributes { + font: &ss.config.font, + padding_left: 10.0, + padding_right: 10.0, + min_width: None, + align: Default::default(), + markup: false, + }, + ) + }); + text.render( + &cairo_ctx, + RenderOptions { + x_offset: offset_left, + bar_height: height_f, + fg_color: ss.config.tag_urgent_fg, + bg_color: Some(ss.config.tag_urgent_bg), + r_left: ss.config.tags_r, + r_right: ss.config.tags_r, + overlap: 0.0, + }, + ); + offset_left += text.width; + } + } + // Display the blocks render_blocks( &cairo_ctx, diff --git a/src/config.rs b/src/config.rs index 382f968..a75ee17 100644 --- a/src/config.rs +++ b/src/config.rs @@ -44,6 +44,7 @@ pub struct Config { pub invert_touchpad_scrolling: bool, pub show_layout_name: bool, pub blend: bool, + pub show_mode: bool, // wm-specific pub wm: WmConfig, // overrides @@ -85,6 +86,7 @@ impl Default for Config { invert_touchpad_scrolling: true, show_layout_name: true, blend: true, + show_mode: true, wm: WmConfig { river: RiverConfig { max_tag: 9 }, diff --git a/src/state.rs b/src/state.rs index 3ace244..3a8eada 100644 --- a/src/state.rs +++ b/src/state.rs @@ -182,9 +182,11 @@ impl State { blocks_btns: Default::default(), tags: Vec::new(), layout_name: None, + mode_name: None, tags_btns: Default::default(), tags_computed: Vec::new(), layout_name_computed: None, + mode_computed: None, }; if !self.hidden { @@ -258,6 +260,18 @@ impl State { bar.request_frame(conn); }); } + + pub fn mode_name_updated(&mut self, conn: &mut Connection, output: Option) { + self.for_each_bar(output, |bar, ss| { + bar.set_mode_name( + ss.wm_info_provider + .as_mut() + .unwrap() + .get_mode_name(bar.output.wl), + ); + bar.request_frame(conn); + }); + } } impl SeatHandler for State { diff --git a/src/wm_info_provider.rs b/src/wm_info_provider.rs index 128d3b9..0c6c5fa 100644 --- a/src/wm_info_provider.rs +++ b/src/wm_info_provider.rs @@ -22,6 +22,7 @@ pub trait WmInfoProvider { fn get_tags(&self, output: WlOutput) -> Vec; fn get_layout_name(&self, output: WlOutput) -> Option; + fn get_mode_name(&self, output: WlOutput) -> Option; fn click_on_tag( &mut self, diff --git a/src/wm_info_provider/ext_workspace_unstable.rs b/src/wm_info_provider/ext_workspace_unstable.rs index 8cb5855..203cba9 100644 --- a/src/wm_info_provider/ext_workspace_unstable.rs +++ b/src/wm_info_provider/ext_workspace_unstable.rs @@ -79,6 +79,10 @@ impl WmInfoProvider for ExtWorkspaceUnstable { None } + fn get_mode_name(&self, _output: WlOutput) -> Option { + None + } + fn click_on_tag( &mut self, conn: &mut Connection, diff --git a/src/wm_info_provider/river.rs b/src/wm_info_provider/river.rs index c9778bc..e9904bd 100644 --- a/src/wm_info_provider/river.rs +++ b/src/wm_info_provider/river.rs @@ -11,6 +11,7 @@ pub struct RiverInfoProvider { control: ZriverControlV1, output_statuses: Vec, max_tag: u8, + seat_status: SeatStatus, } struct OutputStatus { @@ -22,17 +23,32 @@ struct OutputStatus { layout_name: Option, } +struct SeatStatus { + _status: ZriverSeatStatusV1, + mode: Option, +} + impl RiverInfoProvider { pub fn bind( conn: &mut Connection, globals: &Globals, config: &WmConfig, ) -> Option { + let status_manager = globals.bind(conn, 1..=4).ok()?; + let wl_seat: WlSeat = globals.bind(conn, ..).ok()?; // river supports just one seat Some(Self { - status_manager: globals.bind(conn, 1..=4).ok()?, + status_manager, control: globals.bind(conn, 1..=1).ok()?, output_statuses: Vec::new(), max_tag: config.river.max_tag, + seat_status: SeatStatus { + _status: status_manager.get_river_seat_status_with_cb( + conn, + wl_seat, + seat_status_cb, + ), + mode: None, + }, }) } } @@ -81,6 +97,10 @@ impl WmInfoProvider for RiverInfoProvider { status.layout_name.clone() } + fn get_mode_name(&self, _output: WlOutput) -> Option { + self.seat_status.mode.clone() + } + fn click_on_tag( &mut self, conn: &mut Connection, @@ -149,6 +169,20 @@ fn output_status_cb( } } +fn seat_status_cb( + conn: &mut Connection, + state: &mut State, + _: ZriverSeatStatusV1, + event: zriver_seat_status_v1::Event, +) { + if let zriver_seat_status_v1::Event::Mode(mode) = event { + let river = state.shared_state.get_river().unwrap(); + let mode = mode.to_string_lossy().into_owned(); + river.seat_status.mode = (mode != "normal").then_some(mode); + state.mode_name_updated(conn, None); + } +} + fn river_command_cb( conn: &mut Connection, state: &mut State, -- cgit v1.3.1