summaryrefslogtreecommitdiff
path: root/src/bar.rs
diff options
context:
space:
mode:
authorcashmere <cashmere@autistici.org>2026-07-21 14:07:42 +0200
committercashmere <cashmere@autistici.org>2026-07-21 14:07:42 +0200
commit198f374a18b5c8a0e21f7d41125393aa89523f5c (patch)
treead8d32cc498b1b2715a5e71e5f438bf4bacfca53 /src/bar.rs
parent85f0a9e875eee768766d7bdd24272d348f6b1e33 (diff)
downloadi3bar-mango-198f374a18b5c8a0e21f7d41125393aa89523f5c.tar.gz
mango: show focused window next to tags, fix mmsg lookup, 0.15.x compat
- new focused-window block ({icon} {app_id} - {title}) driven by the active_client field of mmsg watch all-monitors (mangowm >= 0.14) - resolve program icons via freedesktop icon themes/.desktop files (new icon module, cairo png feature, cached per app_id) - new show_focused_window config option (default true) - run mmsg from PATH instead of hardcoded /usr/bin/mmsg (broken on NixOS) - handle null active_client fields (no focused client) without failing to parse the whole event - drop stale TODO comment and unused variable in mango provider - add .justfile run recipe exporting MANGO_INSTANCE_SIGNATURE
Diffstat (limited to 'src/bar.rs')
-rw-r--r--src/bar.rs64
1 files changed, 63 insertions, 1 deletions
diff --git a/src/bar.rs b/src/bar.rs
index 237c46a..102978d 100644
--- a/src/bar.rs
+++ b/src/bar.rs
@@ -14,7 +14,7 @@ use crate::protocol::*;
use crate::shared_state::SharedState;
use crate::state::State;
use crate::text::{self, ComputedText, RenderOptions};
-use crate::wm_info_provider::Tag;
+use crate::wm_info_provider::{FocusedWindow, Tag};
pub struct Bar {
pub output: Output,
@@ -33,10 +33,12 @@ pub struct Bar {
tags: Vec<Tag>,
layout_name: Option<String>,
mode_name: Option<String>,
+ focused_window: Option<FocusedWindow>,
tags_btns: ButtonManager<u32>,
tags_computed: Vec<(u32, ColorPair, ComputedText)>,
layout_name_computed: Option<ComputedText>,
mode_computed: Option<ComputedText>,
+ focused_window_computed: Option<ComputedText>,
}
#[derive(Debug, PartialEq)]
@@ -79,10 +81,12 @@ impl Bar {
tags: Vec::new(),
layout_name: None,
mode_name: None,
+ focused_window: None,
tags_btns: Default::default(),
tags_computed: Vec::new(),
layout_name_computed: None,
mode_computed: None,
+ focused_window_computed: None,
}
}
@@ -112,6 +116,11 @@ impl Bar {
self.mode_computed = None;
}
+ pub fn set_focused_window(&mut self, focused_window: Option<FocusedWindow>) {
+ self.focused_window = focused_window;
+ self.focused_window_computed = None;
+ }
+
pub fn click(
&mut self,
conn: &mut Connection<State>,
@@ -287,6 +296,59 @@ impl Bar {
}
}
+ // Display focused window
+ if ss.config.show_focused_window
+ && let Some(focused_window) = &self.focused_window
+ {
+ if let Some(icon) = ss.icon_cache.get(&focused_window.app_id, self.height) {
+ let icon_size = height_f - 4.0;
+ let scale = icon_size / (icon.width() as f64).max(icon.height() as f64);
+ let icon_w = icon.width() as f64 * scale;
+ let icon_h = icon.height() as f64 * scale;
+ cairo_ctx.save().unwrap();
+ cairo_ctx.translate(
+ offset_left + (icon_size - icon_w) / 2.0,
+ (height_f - icon_h) / 2.0,
+ );
+ cairo_ctx.scale(scale, scale);
+ cairo_ctx.set_source_surface(icon, 0.0, 0.0).unwrap();
+ cairo_ctx.paint().unwrap();
+ cairo_ctx.restore().unwrap();
+ offset_left += icon_size + 5.0;
+ }
+ let text = self.focused_window_computed.get_or_insert_with(|| {
+ let label = if focused_window.title.is_empty() {
+ focused_window.app_id.clone()
+ } else {
+ format!("{} - {}", focused_window.app_id, focused_window.title)
+ };
+ ComputedText::new(
+ &label,
+ 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_inactive_fg,
+ bg_color: None,
+ r_left: 0.0,
+ r_right: 0.0,
+ overlap: 0.0,
+ },
+ );
+ offset_left += text.width;
+ }
+
// Display mode
if ss.config.show_mode {
if let Some(mode) = &self.mode_name {