From ca27730b01f7bd00d5183bcdaaf432189dbbfc9a Mon Sep 17 00:00:00 2001 From: LGUG2Z Date: Fri, 6 Aug 2021 14:57:16 -0700 Subject: [PATCH] fix(operation_direction): adjust for layout flips If the BSP layout was flipped on the X or Y axis (or both), OperationDirection commands would not adjust their directions accordingly and prevent the user from focusing, moving etc in a valid direction on the flipped layout. This commit addresses that bug by ensuring that we always try to apply any axis adjustments to an OperationDirection before calling the is_valid or new_idx functions. --- komorebi-core/src/operation_direction.rs | 51 ++++++++++++++++++++++-- komorebi/src/window_manager.rs | 1 + komorebi/src/workspace.rs | 9 ++++- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/komorebi-core/src/operation_direction.rs b/komorebi-core/src/operation_direction.rs index 96aec684..b4c180b7 100644 --- a/komorebi-core/src/operation_direction.rs +++ b/komorebi-core/src/operation_direction.rs @@ -5,6 +5,7 @@ use strum::Display; use strum::EnumString; use crate::Layout; +use crate::LayoutFlip; #[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString)] #[strum(serialize_all = "snake_case")] @@ -29,8 +30,50 @@ impl OperationDirection { } } - pub fn is_valid(&self, layout: Layout, idx: usize, len: usize) -> bool { - match self { + fn flip_direction( + direction: &OperationDirection, + layout_flip: Option, + ) -> OperationDirection { + if let Some(flip) = layout_flip { + match direction { + OperationDirection::Left => match flip { + LayoutFlip::Horizontal | LayoutFlip::HorizontalAndVertical => { + OperationDirection::Right + } + _ => *direction, + }, + OperationDirection::Right => match flip { + LayoutFlip::Horizontal | LayoutFlip::HorizontalAndVertical => { + OperationDirection::Left + } + _ => *direction, + }, + OperationDirection::Up => match flip { + LayoutFlip::Vertical | LayoutFlip::HorizontalAndVertical => { + OperationDirection::Down + } + _ => *direction, + }, + OperationDirection::Down => match flip { + LayoutFlip::Vertical | LayoutFlip::HorizontalAndVertical => { + OperationDirection::Up + } + _ => *direction, + }, + } + } else { + *direction + } + } + + pub fn is_valid( + &self, + layout: Layout, + layout_flip: Option, + idx: usize, + len: usize, + ) -> bool { + match OperationDirection::flip_direction(self, layout_flip) { OperationDirection::Up => match layout { Layout::BSP => len > 2 && idx != 0 && idx != 1, Layout::Columns => false, @@ -54,8 +97,8 @@ impl OperationDirection { } } - pub fn new_idx(&self, layout: Layout, idx: usize) -> usize { - match self { + pub fn new_idx(&self, layout: Layout, layout_flip: Option, idx: usize) -> usize { + match OperationDirection::flip_direction(self, layout_flip) { OperationDirection::Up => match layout { Layout::BSP => { if idx % 2 == 0 { diff --git a/komorebi/src/window_manager.rs b/komorebi/src/window_manager.rs index d6c638bb..0c685a9d 100644 --- a/komorebi/src/window_manager.rs +++ b/komorebi/src/window_manager.rs @@ -204,6 +204,7 @@ impl WindowManager { let is_valid = direction.is_valid( workspace.layout(), + workspace.layout_flip(), workspace.focused_container_idx(), workspace.containers_mut().len(), ); diff --git a/komorebi/src/workspace.rs b/komorebi/src/workspace.rs index bad345be..9d7dccc6 100644 --- a/komorebi/src/workspace.rs +++ b/komorebi/src/workspace.rs @@ -273,11 +273,16 @@ impl Workspace { pub fn new_idx_for_direction(&self, direction: OperationDirection) -> Option { if direction.is_valid( - self.layout, + self.layout(), + self.layout_flip(), self.focused_container_idx(), self.containers().len(), ) { - Option::from(direction.new_idx(self.layout, self.containers.focused_idx())) + Option::from(direction.new_idx( + self.layout(), + self.layout_flip(), + self.containers.focused_idx(), + )) } else { None }