diff --git a/src/main.rs b/src/main.rs index 0bf0dcb..5284486 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,7 @@ use wayland_client::protocol::wl_registry::WlRegistry; use std::collections::{BTreeMap, HashMap}; use wayland_client::protocol::{wl_output, wl_output::WlOutput, wl_seat, wl_seat::WlSeat}; -use wayland_client::{Attached, DispatchData, Display, GlobalEvent, GlobalManager, Main}; +use wayland_client::{Attached, DispatchData, Display, GlobalEvent, GlobalImplementor, GlobalManager, Main}; #[derive(Debug)] struct Flags { @@ -47,6 +47,8 @@ struct Tags(u32); struct Env { flags: Flags, + // I don't know very much about wayland, and it shows + output_id_map: HashMap, output_names: BTreeMap, focused: Option, layout: Option, @@ -134,10 +136,8 @@ impl Serialize for Env { let mut name_id_map = HashMap::<&str, u32>::new(); name_id_map.reserve(self.output_names.len()); let mut id = 0; - for (_, value) in &self.output_names { - if !name_id_map.contains_key(value.as_str()) { - name_id_map.insert(value, id); - } + for (key, value) in &self.output_names { + name_id_map.insert(value, id); id += 1; } state.serialize_field("gtk_ids", &name_id_map)?; @@ -161,6 +161,7 @@ impl Env { viewtags: flags.viewtags.then(Default::default), status_manager: None, flags, + output_id_map: Default::default(), output_names: Default::default(), } } @@ -180,14 +181,6 @@ impl Env { } } -fn handle_zriver_status_manager_v1( - status_manager: Main, mut env: DispatchData -) { - if let Some(env) = env.get::() { - env.status_manager = Some(status_manager); - } -} - fn handle_river_seat_status( _status: Main, event: zriver_seat_status_v1::Event, mut env: DispatchData @@ -328,34 +321,45 @@ fn handle_output_event( fn global_manager_callback( event: GlobalEvent, registry: Attached, mut env: DispatchData ) { - let mut global_filter = wayland_client::global_filter!( - [ZriverStatusManagerV1, 1, handle_zriver_status_manager_v1], - [WlSeat, 7, |seat: Main, _env: DispatchData| { - seat.quick_assign(handle_seat_event); - }], - [WlOutput, 3, |output: Main, _env: DispatchData| { - output.quick_assign(handle_output_event); - }] - ); - match event { - GlobalEvent::New { id: _, interface: _, version: _ } => { - global_filter(event, registry, env); + GlobalEvent::New { id, interface, version } => { + match interface.as_str() { + "wl_output" if version >= 3 => { + let output: Main = registry.bind(version, id); + if let Some(env) = env.get::() { + env.output_id_map.insert(id, output.as_ref().id()); + output.quick_assign(handle_output_event); + } + }, + "wl_seat" if version >= 7 => { + let seat: Main = registry.bind(version, id); + seat.quick_assign(handle_seat_event); + }, + "zriver_status_manager_v1" => { + let status_manager = registry.bind(version, id); + if let Some(env) = env.get::() { + env.status_manager = Some(status_manager); + } + }, + _ => {} + } } GlobalEvent::Removed { id, interface: _ } => { if let Some(env) = env.get::() { - env.output_names.remove(&id); - if let Some(titles) = &mut env.titles { - titles.remove(&id); - } - if let Some(tags) = &mut env.tags { - tags.remove(&id); - } - if let Some(urgency) = &mut env.urgency { - urgency.remove(&id); - } - if let Some(viewtags) = &mut env.viewtags { - viewtags.remove(&id); + if let Some(oid) = env.output_id_map.remove(&id) { + env.output_names.remove(&oid); + if let Some(titles) = &mut env.titles { + titles.remove(&oid); + } + if let Some(tags) = &mut env.tags { + tags.remove(&oid); + } + if let Some(urgency) = &mut env.urgency { + urgency.remove(&oid); + } + if let Some(viewtags) = &mut env.viewtags { + viewtags.remove(&oid); + } } } }