2022-08-14 20:40:11 +01:00
|
|
|
use crate::icon;
|
|
|
|
use crate::modules::{Module, ModuleInfo};
|
2022-08-25 21:53:42 +01:00
|
|
|
use crate::sway::get_client;
|
2022-08-21 23:36:07 +01:00
|
|
|
use color_eyre::Result;
|
2022-08-14 20:40:11 +01:00
|
|
|
use glib::Continue;
|
|
|
|
use gtk::prelude::*;
|
|
|
|
use gtk::{IconTheme, Image, Label, Orientation};
|
|
|
|
use serde::Deserialize;
|
|
|
|
use tokio::task::spawn_blocking;
|
|
|
|
|
|
|
|
#[derive(Debug, Deserialize, Clone)]
|
|
|
|
pub struct FocusedModule {
|
|
|
|
#[serde(default = "crate::config::default_true")]
|
|
|
|
show_icon: bool,
|
|
|
|
#[serde(default = "crate::config::default_true")]
|
|
|
|
show_title: bool,
|
|
|
|
|
|
|
|
#[serde(default = "default_icon_size")]
|
|
|
|
icon_size: i32,
|
|
|
|
icon_theme: Option<String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
const fn default_icon_size() -> i32 {
|
|
|
|
32
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Module<gtk::Box> for FocusedModule {
|
2022-08-21 23:36:07 +01:00
|
|
|
fn into_widget(self, _info: &ModuleInfo) -> Result<gtk::Box> {
|
2022-08-14 20:40:11 +01:00
|
|
|
let icon_theme = IconTheme::new();
|
|
|
|
|
|
|
|
if let Some(theme) = self.icon_theme {
|
|
|
|
icon_theme.set_custom_theme(Some(&theme));
|
|
|
|
}
|
|
|
|
|
|
|
|
let container = gtk::Box::new(Orientation::Horizontal, 5);
|
|
|
|
|
|
|
|
let icon = Image::builder().name("icon").build();
|
|
|
|
let label = Label::builder().name("label").build();
|
|
|
|
|
|
|
|
container.add(&icon);
|
|
|
|
container.add(&label);
|
|
|
|
|
|
|
|
let (tx, rx) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
|
|
|
|
|
2022-08-25 21:53:42 +01:00
|
|
|
let focused = {
|
|
|
|
let sway = get_client();
|
|
|
|
let mut sway = sway.lock().expect("Failed to get lock on Sway IPC client");
|
|
|
|
sway.get_open_windows()?
|
|
|
|
.into_iter()
|
|
|
|
.find(|node| node.focused)
|
|
|
|
};
|
2022-08-14 20:40:11 +01:00
|
|
|
|
|
|
|
if let Some(focused) = focused {
|
2022-08-21 23:36:07 +01:00
|
|
|
tx.send(focused)?;
|
2022-08-14 20:40:11 +01:00
|
|
|
}
|
|
|
|
|
2022-08-25 21:53:42 +01:00
|
|
|
spawn_blocking(move || {
|
|
|
|
let srx = {
|
|
|
|
let sway = get_client();
|
|
|
|
let mut sway = sway.lock().expect("Failed to get lock on Sway IPC client");
|
|
|
|
sway.subscribe_window()
|
|
|
|
};
|
|
|
|
|
|
|
|
while let Ok(payload) = srx.recv() {
|
|
|
|
let update = match payload.change.as_str() {
|
|
|
|
"focus" => true,
|
|
|
|
"title" => payload.container.focused,
|
|
|
|
_ => false,
|
|
|
|
};
|
|
|
|
|
|
|
|
if update {
|
|
|
|
tx.send(payload.container)
|
|
|
|
.expect("Failed to sendf focus update");
|
2022-08-14 20:40:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
{
|
|
|
|
rx.attach(None, move |node| {
|
2022-08-15 21:11:17 +01:00
|
|
|
let value = node.name.as_deref().unwrap_or_else(|| node.get_id());
|
2022-08-14 20:40:11 +01:00
|
|
|
|
|
|
|
let pixbuf = icon::get_icon(&icon_theme, node.get_id(), self.icon_size);
|
|
|
|
|
|
|
|
if self.show_icon {
|
|
|
|
icon.set_pixbuf(pixbuf.as_ref());
|
|
|
|
}
|
|
|
|
|
|
|
|
if self.show_title {
|
|
|
|
label.set_label(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
Continue(true)
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-08-21 23:36:07 +01:00
|
|
|
Ok(container)
|
2022-08-14 20:40:11 +01:00
|
|
|
}
|
|
|
|
}
|