diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/layout/floating.rs | 64 | ||||
| -rw-r--r-- | src/layout/workspace.rs | 60 |
2 files changed, 94 insertions, 30 deletions
diff --git a/src/layout/floating.rs b/src/layout/floating.rs index 417c7518..c0a56165 100644 --- a/src/layout/floating.rs +++ b/src/layout/floating.rs @@ -160,6 +160,10 @@ impl Data { self.recompute_logical_pos(); } + pub fn center(&self) -> Point<f64, Logical> { + self.logical_pos + self.size.downscale(2.) + } + #[cfg(test)] fn verify_invariants(&self) { let mut temp = *self; @@ -627,6 +631,66 @@ impl<W: LayoutElement> FloatingSpace<W> { win.request_size(win_size, animate, None); } + fn focus_directional( + &mut self, + distance: impl Fn(Point<f64, Logical>, Point<f64, Logical>) -> f64, + ) -> bool { + let Some(active_id) = &self.active_window_id else { + return false; + }; + let active_idx = self.idx_of(active_id).unwrap(); + let center = self.data[active_idx].center(); + + let result = zip(&self.tiles, &self.data) + .filter(|(tile, _)| tile.window().id() != active_id) + .map(|(tile, data)| (tile, distance(center, data.center()))) + .filter(|(_, dist)| *dist > 0.) + .min_by(|(_, dist_a), (_, dist_b)| f64::total_cmp(dist_a, dist_b)); + if let Some((tile, _)) = result { + let id = tile.window().id().clone(); + self.activate_window(&id); + true + } else { + false + } + } + + pub fn focus_left(&mut self) -> bool { + self.focus_directional(|focus, other| focus.x - other.x) + } + + pub fn focus_right(&mut self) -> bool { + self.focus_directional(|focus, other| other.x - focus.x) + } + + pub fn focus_up(&mut self) -> bool { + self.focus_directional(|focus, other| focus.y - other.y) + } + + pub fn focus_down(&mut self) -> bool { + self.focus_directional(|focus, other| other.y - focus.y) + } + + pub fn focus_leftmost(&mut self) { + let result = self + .tiles_with_offsets() + .min_by(|(_, pos_a), (_, pos_b)| f64::total_cmp(&pos_a.x, &pos_b.x)); + if let Some((tile, _)) = result { + let id = tile.window().id().clone(); + self.activate_window(&id); + } + } + + pub fn focus_rightmost(&mut self) { + let result = self + .tiles_with_offsets() + .max_by(|(_, pos_a), (_, pos_b)| f64::total_cmp(&pos_a.x, &pos_b.x)); + if let Some((tile, _)) = result { + let id = tile.window().id().clone(); + self.activate_window(&id); + } + } + pub fn descendants_added(&mut self, id: &W::Id) -> bool { let Some(idx) = self.idx_of(id) else { return false; diff --git a/src/layout/workspace.rs b/src/layout/workspace.rs index 3b3e28ee..baae33c8 100644 --- a/src/layout/workspace.rs +++ b/src/layout/workspace.rs @@ -747,35 +747,35 @@ impl<W: LayoutElement> Workspace<W> { } pub fn focus_left(&mut self) -> bool { - // TODO if self.floating_is_active { - return true; + self.floating.focus_left() + } else { + self.scrolling.focus_left() } - self.scrolling.focus_left() } pub fn focus_right(&mut self) -> bool { - // TODO if self.floating_is_active { - return true; + self.floating.focus_right() + } else { + self.scrolling.focus_right() } - self.scrolling.focus_right() } pub fn focus_column_first(&mut self) { - // TODO if self.floating_is_active { - return; + self.floating.focus_leftmost(); + } else { + self.scrolling.focus_column_first(); } - self.scrolling.focus_column_first(); } pub fn focus_column_last(&mut self) { - // TODO if self.floating_is_active { - return; + self.floating.focus_rightmost(); + } else { + self.scrolling.focus_column_last(); } - self.scrolling.focus_column_last(); } pub fn focus_column_right_or_first(&mut self) { @@ -791,51 +791,51 @@ impl<W: LayoutElement> Workspace<W> { } pub fn focus_down(&mut self) -> bool { - // TODO if self.floating_is_active { - return true; + self.floating.focus_down() + } else { + self.scrolling.focus_down() } - self.scrolling.focus_down() } pub fn focus_up(&mut self) -> bool { - // TODO if self.floating_is_active { - return true; + self.floating.focus_up() + } else { + self.scrolling.focus_up() } - self.scrolling.focus_up() } pub fn focus_down_or_left(&mut self) { - // TODO if self.floating_is_active { - return; + self.floating.focus_down(); + } else { + self.scrolling.focus_down_or_left(); } - self.scrolling.focus_down_or_left(); } pub fn focus_down_or_right(&mut self) { - // TODO if self.floating_is_active { - return; + self.floating.focus_down(); + } else { + self.scrolling.focus_down_or_right(); } - self.scrolling.focus_down_or_right(); } pub fn focus_up_or_left(&mut self) { - // TODO if self.floating_is_active { - return; + self.floating.focus_up(); + } else { + self.scrolling.focus_up_or_left(); } - self.scrolling.focus_up_or_left(); } pub fn focus_up_or_right(&mut self) { - // TODO if self.floating_is_active { - return; + self.floating.focus_up(); + } else { + self.scrolling.focus_up_or_right(); } - self.scrolling.focus_up_or_right(); } pub fn move_left(&mut self) -> bool { |
