aboutsummaryrefslogtreecommitdiff
path: root/src/layout/floating.rs
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-12-15 10:30:32 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2024-12-30 20:12:37 +0300
commit6a7c8fcfd529ec31d274b347f4a591ad40366c09 (patch)
treebb4bff6524e5734d576bb42b9eff9b0353ccf1d0 /src/layout/floating.rs
parent14b1003c627cb6ceddfb29ef3298e0b9481f91e6 (diff)
downloadniri-6a7c8fcfd529ec31d274b347f4a591ad40366c09.tar.gz
niri-6a7c8fcfd529ec31d274b347f4a591ad40366c09.tar.bz2
niri-6a7c8fcfd529ec31d274b347f4a591ad40366c09.zip
floating: Implement directional focus
Diffstat (limited to 'src/layout/floating.rs')
-rw-r--r--src/layout/floating.rs64
1 files changed, 64 insertions, 0 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;