From 8356f99d845b095910b4c6011463e851af9e369b Mon Sep 17 00:00:00 2001 From: Ottatop Date: Mon, 22 Jan 2024 18:36:04 -0600 Subject: [PATCH] Split `tag.get`, impl `PartialEq`, `Eq`, `Hash` for handles --- api/rust/examples/default_config/main.rs | 8 +-- api/rust/src/output.rs | 14 +++++ api/rust/src/tag.rs | 67 +++++++++++++++++------- api/rust/src/window.rs | 14 +++++ 4 files changed, 79 insertions(+), 24 deletions(-) diff --git a/api/rust/examples/default_config/main.rs b/api/rust/examples/default_config/main.rs index c77627a..edf6968 100644 --- a/api/rust/examples/default_config/main.rs +++ b/api/rust/examples/default_config/main.rs @@ -94,19 +94,19 @@ async fn main() { for tag_name in tag_names { input.keybind([mod_key], tag_name, move || { - if let Some(tg) = tag.get(tag_name, None) { + if let Some(tg) = tag.get(tag_name) { tg.switch_to(); } }); input.keybind([mod_key, Mod::Shift], tag_name, move || { - if let Some(tg) = tag.get(tag_name, None) { + if let Some(tg) = tag.get(tag_name) { tg.toggle_active(); } }); input.keybind([mod_key, Mod::Alt], tag_name, move || { - if let Some(tg) = tag.get(tag_name, None) { + if let Some(tg) = tag.get(tag_name) { if let Some(win) = window.get_focused() { win.move_to_tag(&tg); } @@ -114,7 +114,7 @@ async fn main() { }); input.keybind([mod_key, Mod::Shift, Mod::Alt], tag_name, move || { - if let Some(tg) = tag.get(tag_name, None) { + if let Some(tg) = tag.get(tag_name) { if let Some(win) = window.get_focused() { win.toggle_tag(&tg); } diff --git a/api/rust/src/output.rs b/api/rust/src/output.rs index 6ef6d9b..7fca866 100644 --- a/api/rust/src/output.rs +++ b/api/rust/src/output.rs @@ -166,6 +166,20 @@ pub struct OutputHandle { pub(crate) name: String, } +impl PartialEq for OutputHandle { + fn eq(&self, other: &Self) -> bool { + self.name == other.name + } +} + +impl Eq for OutputHandle {} + +impl std::hash::Hash for OutputHandle { + fn hash(&self, state: &mut H) { + self.name.hash(state); + } +} + /// The alignment to use for [`OutputHandle::set_loc_adj_to`]. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum Alignment { diff --git a/api/rust/src/tag.rs b/api/rust/src/tag.rs index 256fdd3..ddf93eb 100644 --- a/api/rust/src/tag.rs +++ b/api/rust/src/tag.rs @@ -131,40 +131,53 @@ impl Tag { }) } - /// Get a handle to the first tag with the given name on `output`. + /// Get a handle to the first tag with the given name on the focused output. /// - /// If `output` is `None`, the focused output will be used. + /// If you need to get a tag on a specific output, see [`Tag::get_on_output`]. /// /// # Examples /// /// ``` - /// // Get tag "1" on output "HDMI-1" - /// if let Some(op) = output.get_by_name("HDMI-1") { - /// let tg = tag.get("1", &op); - /// } - /// /// // Get tag "Thing" on the focused output - /// let tg = tag.get("Thing", None); + /// let tg = tag.get("Thing"); /// ``` - pub fn get<'a>( - &self, - name: impl Into, - output: impl Into>, - ) -> Option { + pub fn get(&self, name: impl Into) -> Option { let name = name.into(); - let output: Option<&OutputHandle> = output.into(); let output_module = Output::new(self.channel.clone(), self.fut_sender.clone()); + let focused_output = output_module.get_focused(); self.get_all().find(|tag| { let props = tag.props(); let same_tag_name = props.name.as_ref() == Some(&name); - let same_output = props.output.is_some_and(|op| { - Some(op.name) - == output - .map(|o| o.name.clone()) - .or_else(|| output_module.get_focused().map(|o| o.name)) - }); + let same_output = props.output.is_some_and(|op| Some(op) == focused_output); + + same_tag_name && same_output + }) + } + + /// Get a handle to the first tag with the given name on the specified output. + /// + /// If you just need to get a tag on the focused output, see [`Tag::get`]. + /// + /// # Examples + /// + /// ``` + /// // Get tag "Thing" on "HDMI-1" + /// let tg = tag.get_on_output("Thing", output.get_by_name("HDMI-2")?); + /// ``` + pub fn get_on_output( + &self, + name: impl Into, + output: &OutputHandle, + ) -> Option { + let name = name.into(); + + self.get_all().find(|tag| { + let props = tag.props(); + + let same_tag_name = props.name.as_ref() == Some(&name); + let same_output = props.output.is_some_and(|op| &op == output); same_tag_name && same_output }) @@ -318,6 +331,20 @@ pub struct TagHandle { pub(crate) id: u32, } +impl PartialEq for TagHandle { + fn eq(&self, other: &Self) -> bool { + self.id == other.id + } +} + +impl Eq for TagHandle {} + +impl std::hash::Hash for TagHandle { + fn hash(&self, state: &mut H) { + self.id.hash(state); + } +} + /// Various static layouts. #[repr(i32)] #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, TryFromPrimitive)] diff --git a/api/rust/src/window.rs b/api/rust/src/window.rs index c120ce8..fb6f12e 100644 --- a/api/rust/src/window.rs +++ b/api/rust/src/window.rs @@ -172,6 +172,20 @@ pub struct WindowHandle { pub(crate) output_client: OutputServiceClient, } +impl PartialEq for WindowHandle { + fn eq(&self, other: &Self) -> bool { + self.id == other.id + } +} + +impl Eq for WindowHandle {} + +impl std::hash::Hash for WindowHandle { + fn hash(&self, state: &mut H) { + self.id.hash(state); + } +} + /// Whether a window is fullscreen, maximized, or neither. #[repr(i32)] #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, TryFromPrimitive)]