step 5: live Hyprland workspace buttons via EventStream
This commit is contained in:
parent
542cbae939
commit
241e3bc2cb
4 changed files with 109 additions and 10 deletions
66
src/main.rs
66
src/main.rs
|
|
@ -4,14 +4,27 @@ mod theme;
|
|||
|
||||
use gtk4::prelude::*;
|
||||
use gtk4_layer_shell::{Edge, Layer, LayerShell};
|
||||
use hyprland::data::Workspace;
|
||||
use hyprland::shared::WorkspaceId;
|
||||
use relm4::prelude::*;
|
||||
|
||||
struct App;
|
||||
pub struct App {
|
||||
workspaces: Vec<Workspace>,
|
||||
active_ws: WorkspaceId,
|
||||
// Stored handle so update() can manipulate the live widget directly.
|
||||
workspace_box: gtk4::Box,
|
||||
}
|
||||
|
||||
#[relm4::component]
|
||||
#[derive(Debug)]
|
||||
pub enum AppInput {
|
||||
WorkspaceList(Vec<Workspace>),
|
||||
ActiveWorkspace(WorkspaceId),
|
||||
}
|
||||
|
||||
#[relm4::component(pub)]
|
||||
impl SimpleComponent for App {
|
||||
type Init = ();
|
||||
type Input = ();
|
||||
type Input = AppInput;
|
||||
type Output = ();
|
||||
|
||||
view! {
|
||||
|
|
@ -24,11 +37,13 @@ impl SimpleComponent for App {
|
|||
#[wrap(Some)]
|
||||
set_start_widget = >k::Box {
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
set_spacing: 4,
|
||||
set_spacing: 0,
|
||||
set_margin_start: 8,
|
||||
|
||||
gtk::Label {
|
||||
set_label: "1 2 3",
|
||||
#[name = "workspace_box"]
|
||||
gtk::Box {
|
||||
set_orientation: gtk::Orientation::Horizontal,
|
||||
set_spacing: 4,
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -54,7 +69,7 @@ impl SimpleComponent for App {
|
|||
fn init(
|
||||
_: Self::Init,
|
||||
root: Self::Root,
|
||||
_sender: ComponentSender<Self>,
|
||||
sender: ComponentSender<Self>,
|
||||
) -> ComponentParts<Self> {
|
||||
root.init_layer_shell();
|
||||
root.set_layer(Layer::Top);
|
||||
|
|
@ -63,15 +78,48 @@ impl SimpleComponent for App {
|
|||
root.set_anchor(Edge::Right, true);
|
||||
root.set_exclusive_zone(32);
|
||||
|
||||
let model = App;
|
||||
// Placeholder until view_output! gives us the real handle.
|
||||
let mut model = App {
|
||||
workspaces: vec![],
|
||||
active_ws: 1,
|
||||
workspace_box: gtk4::Box::new(gtk4::Orientation::Horizontal, 4),
|
||||
};
|
||||
let widgets = view_output!();
|
||||
|
||||
// Swap in the actual widget so update() can reach it.
|
||||
model.workspace_box = widgets.workspace_box.clone();
|
||||
|
||||
theme::apply();
|
||||
bar::workspaces::spawn_watcher(sender);
|
||||
|
||||
ComponentParts { model, widgets }
|
||||
}
|
||||
|
||||
fn update(&mut self, _: Self::Input, _: ComponentSender<Self>) {}
|
||||
fn update(&mut self, msg: Self::Input, _: ComponentSender<Self>) {
|
||||
match msg {
|
||||
AppInput::WorkspaceList(list) => {
|
||||
let mut sorted = list;
|
||||
sorted.sort_by_key(|w| w.id);
|
||||
self.workspaces = sorted;
|
||||
}
|
||||
AppInput::ActiveWorkspace(id) => {
|
||||
self.active_ws = id;
|
||||
}
|
||||
}
|
||||
self.rebuild_buttons();
|
||||
}
|
||||
}
|
||||
|
||||
impl App {
|
||||
fn rebuild_buttons(&self) {
|
||||
while let Some(child) = self.workspace_box.first_child() {
|
||||
self.workspace_box.remove(&child);
|
||||
}
|
||||
for ws in &self.workspaces {
|
||||
self.workspace_box
|
||||
.append(&bar::workspaces::make_button(ws.id, &ws.name, self.active_ws));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue