From d860172334c4e062b152c83e045f4fb1f0057d08 Mon Sep 17 00:00:00 2001 From: Seaotatop Date: Sun, 9 Jul 2023 10:00:16 -0500 Subject: [PATCH] Clean up old layouts --- src/backend/winit.rs | 7 +- src/grab/move_grab.rs | 52 ++++++++---- src/handlers.rs | 19 +++-- src/layout.rs | 80 +++++++++++++++---- src/layout/automatic.rs | 160 ------------------------------------- src/layout/manual.rs | 7 -- src/output.rs | 2 +- src/state.rs | 90 ++++++++++----------- src/window.rs | 41 +--------- src/window/window_state.rs | 6 +- 10 files changed, 160 insertions(+), 304 deletions(-) delete mode 100644 src/layout/automatic.rs delete mode 100644 src/layout/manual.rs diff --git a/src/backend/winit.rs b/src/backend/winit.rs index 090f100..3a03f83 100644 --- a/src/backend/winit.rs +++ b/src/backend/winit.rs @@ -47,7 +47,6 @@ use smithay::{ }; use crate::{ - layout::{Direction, Layouts}, render::{pointer::PointerElement, CustomRenderElements, OutputRenderElements}, state::{CalloopData, State}, }; @@ -220,11 +219,7 @@ pub fn run_winit() -> Result<(), Box> { None, None, ); - Layouts::master_stack( - state, - state.space.elements().cloned().collect(), - Direction::Left, - ); + state.re_layout(); } WinitEvent::Focus(_) => {} WinitEvent::Input(input_evt) => { diff --git a/src/grab/move_grab.rs b/src/grab/move_grab.rs index 98c4740..4df0b37 100644 --- a/src/grab/move_grab.rs +++ b/src/grab/move_grab.rs @@ -19,7 +19,13 @@ use smithay::{ utils::{IsAlive, Logical, Point, Rectangle}, }; -use crate::{backend::Backend, state::State, window::window_state::WindowState}; +use crate::{ + backend::Backend, + layout::{Layout, LayoutVec}, + output::OutputState, + state::State, + window::window_state::{WindowResizeState, WindowState}, +}; pub struct MoveSurfaceGrab { pub start_data: GrabStartData, @@ -47,7 +53,7 @@ impl PointerGrab> for MoveSurfaceGrab> { // tracing::info!("window geo is: {:?}", self.window.geometry()); // tracing::info!("loc is: {:?}", data.space.element_location(&self.window)); - let tiled = WindowState::with_state(&self.window, |state| state.floating.is_tiled()); + let tiled = WindowState::with(&self.window, |state| state.floating.is_tiled()); if tiled { // INFO: this is being used instead of space.element_under(event.location) because that @@ -72,28 +78,46 @@ impl PointerGrab> for MoveSurfaceGrab> { return; } - let window_under_floating = - WindowState::with_state(&window_under, |state| state.floating.is_floating()); + let is_floating = + WindowState::with(&window_under, |state| state.floating.is_floating()); - if window_under_floating { + if is_floating { return; } - data.swap_window_positions(&self.window, &window_under); + let has_pending_resize = WindowState::with(&window_under, |state| { + !matches!(state.resize_state, WindowResizeState::Idle) + }); + + if has_pending_resize { + return; + } + + // data.swap_window_positions(&self.window, &window_under); + let output = data.focus_state.focused_output.as_ref().unwrap(); + OutputState::with(output, |state| { + let mut tags = data + .tag_state + .tags + .iter_mut() + .filter(|tg| state.tags.contains(&tg.id)); + + if let Some(first) = tags.next() { + let mut layout = first.windows.as_master_stack(); + + for tg in tags { + layout = layout.chain_with(&mut tg.windows); + } + + layout.swap(&data.space, &self.window, &window_under); + } + }) } } else { let delta = event.location - self.start_data.location; let new_loc = self.initial_window_loc.to_f64() + delta; data.space .map_element(self.window.clone(), new_loc.to_i32_round(), true); - // let loc = data - // .space - // .element_location(&self.window) - // .unwrap_or((0, 0).into()); - // tracing::info!("new loc from element_location: {}, {}", loc.x, loc.y); - // let geo = self.window.geometry(); - // tracing::info!("geo loc: {}, {}", geo.loc.x, geo.loc.y); - // tracing::info!("geo size: {}, {}", geo.size.w, geo.size.h); } } diff --git a/src/handlers.rs b/src/handlers.rs index 03f5dc8..faf7b90 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -117,7 +117,7 @@ impl CompositorHandler for State { crate::grab::resize_grab::handle_commit(self, surface); if let Some(window) = self.window_for_surface(surface) { - WindowState::with_state(&window, |state| { + WindowState::with(&window, |state| { if let WindowResizeState::WaitingForCommit(new_pos) = state.resize_state { state.resize_state = WindowResizeState::Idle; self.space.map_element(window.clone(), new_pos, false); @@ -225,11 +225,10 @@ impl XdgShellHandler for State { fn new_toplevel(&mut self, surface: ToplevelSurface) { let window = Window::new(surface); - WindowState::with_state(&window, |state| { + WindowState::with(&window, |state| { state.tags = if let Some(focused_output) = &self.focus_state.focused_output { OutputState::with(focused_output, |state| { - let output_tags: Vec = - state.focused_tags.iter().cloned().collect(); + let output_tags: Vec = state.tags.iter().cloned().collect(); if !output_tags.is_empty() { output_tags } else if let Some(first_tag) = self.tag_state.tags.first() { @@ -270,7 +269,7 @@ impl XdgShellHandler for State { .tag_state .tags .iter_mut() - .filter(|tg| state.focused_tags.contains(&tg.id)); + .filter(|tg| state.tags.contains(&tg.id)); if let Some(first) = tags.next() { let mut layout = first.windows.as_master_stack(); @@ -302,7 +301,7 @@ impl XdgShellHandler for State { .tag_state .tags .iter_mut() - .filter(|tg| state.focused_tags.contains(&tg.id)); + .filter(|tg| state.tags.contains(&tg.id)); if let Some(first) = tags.next() { tracing::debug!("first tag: {:?}", first.id); @@ -429,10 +428,10 @@ impl XdgShellHandler for State { } fn ack_configure(&mut self, surface: WlSurface, configure: Configure) { - tracing::debug!("start of ack_configure"); + // tracing::debug!("start of ack_configure"); if let Some(window) = self.window_for_surface(&surface) { - tracing::debug!("found window for surface"); - WindowState::with_state(&window, |state| { + // tracing::debug!("found window for surface"); + WindowState::with(&window, |state| { if let WindowResizeState::WaitingForAck(serial, new_loc) = state.resize_state { match &configure { Configure::Toplevel(configure) => { @@ -453,7 +452,7 @@ impl XdgShellHandler for State { // | mapping the element in commit, this means that the window won't reappear on a tag // | change. The code below is a workaround until I can figure it out. if !self.space.elements().any(|win| win == &window) { - WindowState::with_state(&window, |state| { + WindowState::with(&window, |state| { if let WindowResizeState::WaitingForCommit(new_loc) = state.resize_state { tracing::debug!("remapping window"); let win = window.clone(); diff --git a/src/layout.rs b/src/layout.rs index f978fd4..e638662 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -9,15 +9,11 @@ use smithay::{ desktop::{space::SpaceElement, Space, Window}, output::Output, utils::{Logical, Size}, + wayland::{compositor, shell::xdg::XdgToplevelSurfaceData}, }; use crate::window::window_state::{WindowResizeState, WindowState}; -pub mod automatic; -pub mod manual; - -pub struct Layouts; - pub enum Direction { Left, Right, @@ -75,7 +71,7 @@ impl MasterStack<'_, Window> { state.size = Some((output_geo.size.w / 2, height).into()); }); - WindowState::with_state(win, |state| { + WindowState::with(win, |state| { state.resize_state = WindowResizeState::WaitingForAck( win.toplevel().send_configure(), (output_geo.size.w / 2, i as i32 * height).into(), @@ -101,12 +97,12 @@ pub fn swap_window_positions(space: &Space, win1: &Window, win2: &Window }); let serial = win1.toplevel().send_configure(); - WindowState::with_state(win1, |state| { + WindowState::with(win1, |state| { state.resize_state = WindowResizeState::WaitingForAck(serial, win2_loc); }); let serial = win2.toplevel().send_configure(); - WindowState::with_state(win2, |state| { + WindowState::with(win2, |state| { state.resize_state = WindowResizeState::WaitingForAck(serial, win1_loc); }); } @@ -127,7 +123,7 @@ impl<'a> Layout<'a, Window> for MasterStack<'a, Window> { state.size = Some(output_geo.size); }); - WindowState::with_state(master, |state| { + WindowState::with(master, |state| { state.resize_state = WindowResizeState::WaitingForAck( master.toplevel().send_configure(), (0, 0).into(), @@ -143,7 +139,7 @@ impl<'a> Layout<'a, Window> for MasterStack<'a, Window> { state.size = Some((output_geo.size.w / 2, output_geo.size.h).into()); }); - WindowState::with_state(master, |state| { + WindowState::with(master, |state| { state.resize_state = WindowResizeState::WaitingForAck( master.toplevel().send_configure(), (0, 0).into(), @@ -172,7 +168,7 @@ impl<'a> Layout<'a, Window> for MasterStack<'a, Window> { state.size = Some(output_geo.size); }); - WindowState::with_state(master, |state| { + WindowState::with(master, |state| { state.resize_state = WindowResizeState::WaitingForAck( master.toplevel().send_configure(), (0, 0).into(), @@ -184,15 +180,46 @@ impl<'a> Layout<'a, Window> for MasterStack<'a, Window> { } fn swap(&mut self, space: &Space, elem1: &Window, elem2: &Window) { - let mut elems = self.inner.iter_mut().flat_map(|vec| vec.iter_mut()); - let first = elems.find(|elem| *elem == elem1); - let second = elems.find(|elem| *elem == elem2); + tracing::debug!("top of swap"); + + let mut elems = self + .inner + .iter_mut() + .flat_map(|vec| vec.iter_mut()) + .filter(|elem| *elem == elem1 || *elem == elem2) + .unique_by(|win| WindowState::with(win, |state| state.id)); + + let (first, second) = (elems.next(), elems.next()); + if let Some(first) = first { if let Some(second) = second { std::mem::swap(first, second); } } + let wins = self + .inner + .iter() + .map(|vec| { + vec.iter() + .enumerate() + .map(|(i, win)| { + compositor::with_states(win.toplevel().wl_surface(), |states| { + let lock = states + .data_map + .get::() + .expect("XdgToplevelSurfaceData doesn't exist") + .lock() + .expect("Couldn't lock XdgToplevelSurfaceData"); + (i, lock.app_id.clone().unwrap_or("".to_string())) + }) + }) + .collect::>() + }) + .collect::>(); + + tracing::debug!("windows are: {wins:?}"); + swap_window_positions(space, elem1, elem2); } @@ -205,6 +232,27 @@ impl<'a> Layout<'a, Window> for MasterStack<'a, Window> { tracing::error!("could not get output geometry"); return; }; + let wins = self + .inner + .iter() + .map(|vec| { + vec.iter() + .enumerate() + .map(|(i, win)| { + compositor::with_states(win.toplevel().wl_surface(), |states| { + let lock = states + .data_map + .get::() + .expect("XdgToplevelSurfaceData doesn't exist") + .lock() + .expect("Couldn't lock XdgToplevelSurfaceData"); + (i, lock.app_id.clone().unwrap_or("".to_string())) + }) + }) + .collect::>() + }) + .collect::>(); + tracing::debug!("windows are: {wins:?}"); if self.stack().count() == 0 { // one window @@ -212,7 +260,7 @@ impl<'a> Layout<'a, Window> for MasterStack<'a, Window> { state.size = Some(output_geo.size); }); - WindowState::with_state(master, |state| { + WindowState::with(master, |state| { state.resize_state = WindowResizeState::WaitingForAck( master.toplevel().send_configure(), (0, 0).into(), @@ -224,7 +272,7 @@ impl<'a> Layout<'a, Window> for MasterStack<'a, Window> { master.toplevel().with_pending_state(|state| { state.size = Some(new_master_size); }); - WindowState::with_state(master, |state| { + WindowState::with(master, |state| { state.resize_state = WindowResizeState::WaitingForAck( master.toplevel().send_configure(), (0, 0).into(), diff --git a/src/layout/automatic.rs b/src/layout/automatic.rs deleted file mode 100644 index 71d9179..0000000 --- a/src/layout/automatic.rs +++ /dev/null @@ -1,160 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. -// -// SPDX-License-Identifier: MPL-2.0 - -use smithay::{ - desktop::Window, - wayland::{compositor, shell::xdg::XdgToplevelSurfaceData}, -}; - -use crate::{ - backend::Backend, - state::State, - window::window_state::{WindowResizeState, WindowState}, -}; - -use super::{Direction, Layouts}; - -impl Layouts { - pub fn master_stack( - state: &mut State, - mut windows: Vec, - side: Direction, - ) { - windows.retain(|win| WindowState::with_state(win, |state| state.floating.is_tiled())); - match side { - Direction::Left => { - let window_count = windows.len(); - if window_count == 0 { - return; - } - // TODO: change focused_output to be not an option - let Some(output) = state - .focus_state - .focused_output - .as_ref() - .or_else(|| state.space.outputs().next()) - else { - tracing::warn!("no connected outputs"); - return; - // TODO: no idea what happens if you spawn a window while no monitors are - // | connected, figure that out - }; - let output_size = state.space.output_geometry(output).unwrap().size; - if window_count == 1 { - tracing::debug!("Laying out only window"); - let window = windows[0].clone(); - - window.toplevel().with_pending_state(|tl_state| { - tl_state.size = Some(state.space.output_geometry(output).unwrap().size); - tracing::debug!("only size is {:?}", tl_state.size); - }); - - let initial_configure_sent = - compositor::with_states(window.toplevel().wl_surface(), |states| { - states - .data_map - .get::() - .unwrap() - .lock() - .unwrap() - .initial_configure_sent - }); - tracing::debug!("initial configure sent is {initial_configure_sent}"); - if initial_configure_sent { - WindowState::with_state(&window, |state| { - tracing::debug!("sending configure"); - state.resize_state = WindowResizeState::WaitingForAck( - window.toplevel().send_configure(), - output.current_location(), - ); - }); - } - - return; - } - - tracing::debug!("layed out first window"); - let mut windows = windows.iter(); - let first_window = windows.next().unwrap(); - - first_window.toplevel().with_pending_state(|tl_state| { - let mut size = state.space.output_geometry(output).unwrap().size; - size.w /= 2; - tl_state.size = Some(size); - tracing::debug!("first size is {:?}", tl_state.size); - }); - - let initial_configure_sent = - compositor::with_states(first_window.toplevel().wl_surface(), |states| { - states - .data_map - .get::() - .unwrap() - .lock() - .unwrap() - .initial_configure_sent - }); - if initial_configure_sent { - WindowState::with_state(first_window, |state| { - tracing::debug!("sending resize state"); - state.resize_state = WindowResizeState::WaitingForAck( - first_window.toplevel().send_configure(), - output.current_location(), - ); - }); - } - - let window_count = windows.len() as i32; - let height = output_size.h / window_count; - let x = output.current_location().x + output_size.w / 2; - - for (i, win) in windows.enumerate() { - win.toplevel().with_pending_state(|state| { - let mut new_size = output_size; - new_size.w /= 2; - new_size.w = new_size.w.clamp(1, i32::MAX); - new_size.h /= window_count; - // INFO: The newest window won't have its geometry.loc set until after here and I don't know - // | why, so this is hardcoded to 40. I don't anticipate people using - // | windows that are that short, so figuring it out is low priority. - // | Kitty specifically will crash the compositor if it's resized such - // | that the bottom border goes above the bottom of the title bar if - // | this is set too low. - new_size.h = new_size.h.clamp(40, i32::MAX); - state.size = Some(new_size); - tracing::debug!("size is {:?}", state.size); - }); - - let mut new_loc = output.current_location(); - new_loc.x = x; - new_loc.y = (i as i32) * height; - - let initial_configure_sent = - compositor::with_states(win.toplevel().wl_surface(), |states| { - states - .data_map - .get::() - .unwrap() - .lock() - .unwrap() - .initial_configure_sent - }); - if initial_configure_sent { - WindowState::with_state(win, |state| { - state.resize_state = WindowResizeState::WaitingForAck( - win.toplevel().send_configure(), - new_loc, - ); - }); - } - } - } - Direction::Right => todo!(), - Direction::Top => todo!(), - Direction::Bottom => todo!(), - } - } -} diff --git a/src/layout/manual.rs b/src/layout/manual.rs deleted file mode 100644 index 4690005..0000000 --- a/src/layout/manual.rs +++ /dev/null @@ -1,7 +0,0 @@ -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at https://mozilla.org/MPL/2.0/. -// -// SPDX-License-Identifier: MPL-2.0 -// -// love how i'm licensing this empty file diff --git a/src/output.rs b/src/output.rs index 384f442..ccb3532 100644 --- a/src/output.rs +++ b/src/output.rs @@ -12,7 +12,7 @@ use crate::tag::TagId; #[derive(Default)] pub struct OutputState { - pub focused_tags: HashSet, + pub tags: HashSet, } impl OutputState { diff --git a/src/state.rs b/src/state.rs index ca09a02..94f4d08 100644 --- a/src/state.rs +++ b/src/state.rs @@ -136,7 +136,7 @@ impl State { Msg::SetWindowSize { window_id, size } => { let Some(window) = self.space.elements().find(|&win| { - WindowState::with_state(win, |state| state.id == window_id) + WindowState::with(win, |state| state.id == window_id) }) else { return; }; // TODO: tiled vs floating @@ -149,9 +149,9 @@ impl State { if let Some(window) = self .windows .iter() - .find(|&win| WindowState::with_state(win, |state| state.id == window_id)) + .find(|&win| WindowState::with(win, |state| state.id == window_id)) { - WindowState::with_state(window, |state| { + WindowState::with(window, |state| { state.tags = vec![tag_id.clone()]; }); } @@ -162,9 +162,9 @@ impl State { if let Some(window) = self .windows .iter() - .find(|&win| WindowState::with_state(win, |state| state.id == window_id)) + .find(|&win| WindowState::with(win, |state| state.id == window_id)) { - WindowState::with_state(window, |state| { + WindowState::with(window, |state| { if state.tags.contains(&tag_id) { state.tags.retain(|id| id != &tag_id); } else { @@ -179,12 +179,12 @@ impl State { OutputState::with( self.focus_state.focused_output.as_ref().unwrap(), // TODO: handle error |state| { - let should_remove = state.focused_tags.get(&tag_id).is_some(); + let should_remove = state.tags.get(&tag_id).is_some(); if should_remove { - state.focused_tags.remove(&tag_id); + state.tags.remove(&tag_id); tracing::debug!("toggled tag {tag_id:?} off"); } else { - state.focused_tags.insert(tag_id.clone()); + state.tags.insert(tag_id.clone()); tracing::debug!("toggled tag {tag_id:?} on"); } }, @@ -194,9 +194,9 @@ impl State { } Msg::SwitchToTag { tag_id } => { OutputState::with(self.focus_state.focused_output.as_ref().unwrap(), |state| { - state.focused_tags.clear(); - state.focused_tags.insert(tag_id.clone()); - tracing::debug!("focused tags: {:?}", state.focused_tags); + state.tags.clear(); + state.tags.insert(tag_id.clone()); + tracing::debug!("focused tags: {:?}", state.tags); }); self.re_layout(); @@ -238,7 +238,7 @@ impl State { .expect("Couldn't lock XdgToplevelSurfaceData"); (lock.app_id.clone(), lock.title.clone()) }); - let (window_id, floating) = WindowState::with_state(¤t_focus, |state| { + let (window_id, floating) = WindowState::with(¤t_focus, |state| { (state.id, state.floating.is_floating()) }); // TODO: unwrap @@ -281,7 +281,7 @@ impl State { .expect("Couldn't lock XdgToplevelSurfaceData"); (lock.app_id.clone(), lock.title.clone()) }); - let (window_id, floating) = WindowState::with_state(win, |state| { + let (window_id, floating) = WindowState::with(win, |state| { (state.id, state.floating.is_floating()) }); // TODO: unwrap @@ -471,46 +471,38 @@ impl State { } pub fn re_layout(&mut self) { - let mut windows = - OutputState::with(self.focus_state.focused_output.as_ref().unwrap(), |state| { - for window in self.space.elements().cloned().collect::>() { - let should_render = WindowState::with_state(&window, |win_state| { - for tag_id in win_state.tags.iter() { - if state.focused_tags.get(tag_id).is_some() { - return true; - } + let output = self.focus_state.focused_output.as_ref().unwrap(); + OutputState::with(output, |state| { + for window in self.space.elements().cloned().collect::>() { + let should_render = WindowState::with(&window, |win_state| { + for tag_id in win_state.tags.iter() { + if state.tags.get(tag_id).is_some() { + return true; } - false - }); - if !should_render { - self.space.unmap_elem(&window); } + false + }); + if !should_render { + self.space.unmap_elem(&window); + } + } + + let mut tags = self + .tag_state + .tags + .iter_mut() + .filter(|tg| state.tags.contains(&tg.id)); + + if let Some(first) = tags.next() { + let mut layout = first.windows.as_master_stack(); + + for tg in tags { + layout = layout.chain_with(&mut tg.windows); } - self.windows - .iter() - .filter(|&win| { - WindowState::with_state(win, |win_state| { - for tag_id in win_state.tags.iter() { - if state.focused_tags.get(tag_id).is_some() { - return true; - } - } - false - }) - }) - .cloned() - .collect::>() - }); - - tracing::debug!("Laying out {} windows", windows.len()); - - windows.as_master_stack().layout( - &self.space, - self.focus_state.focused_output.as_ref().unwrap(), - ); - - // Layouts::master_stack(self, windows, crate::layout::Direction::Left); + layout.layout(&self.space, output); + } + }); } } diff --git a/src/window.rs b/src/window.rs index 1c58b23..380abac 100644 --- a/src/window.rs +++ b/src/window.rs @@ -12,9 +12,7 @@ use smithay::{ wayland::{compositor, seat::WaylandFocus}, }; -use crate::{ - backend::Backend, layout::Layouts, state::State, window::window_state::WindowResizeState, -}; +use crate::{backend::Backend, state::State}; use self::window_state::{Float, WindowId, WindowState}; @@ -57,43 +55,11 @@ impl State { .cloned() }) } - - /// Swap the positions and sizes of two windows. - pub fn swap_window_positions(&mut self, win1: &Window, win2: &Window) { - // FIXME: moving the mouse quickly will break swapping - - let win1_loc = self.space.element_location(win1).unwrap(); // TODO: handle unwraps - let win2_loc = self.space.element_location(win2).unwrap(); - let win1_geo = win1.geometry(); - let win2_geo = win2.geometry(); - // tracing::info!("win1: {:?}, {:?}", win1_loc, win1_geo); - // tracing::info!("win2: {:?}, {:?}", win2_loc, win2_geo); - - win1.toplevel().with_pending_state(|state| { - state.size = Some(win2_geo.size); - }); - win2.toplevel().with_pending_state(|state| { - state.size = Some(win1_geo.size); - }); - - let serial = win1.toplevel().send_configure(); - WindowState::with_state(win1, |state| { - state.resize_state = WindowResizeState::WaitingForAck(serial, win2_loc); - }); - - let serial = win2.toplevel().send_configure(); - WindowState::with_state(win2, |state| { - state.resize_state = WindowResizeState::WaitingForAck(serial, win1_loc); - }); - - // self.space.map_element(win1.clone(), win2_loc, false); - // self.space.map_element(win2.clone(), win1_loc, false); - } } /// Toggle a window's floating status. pub fn toggle_floating(state: &mut State, window: &Window) { - WindowState::with_state(window, |window_state| { + WindowState::with(window, |window_state| { match window_state.floating { Float::Tiled(prev_loc_and_size) => { if let Some((prev_loc, prev_size)) = prev_loc_and_size { @@ -119,8 +85,7 @@ pub fn toggle_floating(state: &mut State, window: &Window) { } }); - let windows = state.space.elements().cloned().collect::>(); - Layouts::master_stack(state, windows, crate::layout::Direction::Left); + state.re_layout(); state.space.raise_element(window, true); } diff --git a/src/window/window_state.rs b/src/window/window_state.rs index c8f1731..9ddc930 100644 --- a/src/window/window_state.rs +++ b/src/window/window_state.rs @@ -16,7 +16,7 @@ use smithay::{ use crate::tag::{Tag, TagId, TagState}; -#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] pub struct WindowId(u32); // TODO: this probably doesn't need to be atomic @@ -44,7 +44,7 @@ pub fn tags<'a>(tag_state: &'a TagState, window: &Window) -> Vec<&'a Tag> { tag_state .tags .iter() - .filter(|&tag| WindowState::with_state(window, |state| state.tags.contains(&tag.id))) + .filter(|&tag| WindowState::with(window, |state| state.tags.contains(&tag.id))) .collect() } @@ -118,7 +118,7 @@ impl WindowState { } /// Access a [Window]'s state, optionally returning something. - pub fn with_state(window: &Window, mut func: F) -> T + pub fn with(window: &Window, mut func: F) -> T where F: FnMut(&mut Self) -> T, {