mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-05-06 10:53:23 +02:00
feat(wm): add cmd to resize by axis
This commit adds a new command to resize by axis. Resizing is still limited to the BSP layout. This command is intended to be bound to mouse wheel up and down events, with different modified keys determining the axis to operate on.
This commit is contained in:
@@ -19,7 +19,7 @@ pub trait Arrangement {
|
||||
area: &Rect,
|
||||
len: NonZeroUsize,
|
||||
container_padding: Option<i32>,
|
||||
layout_flip: Option<Flip>,
|
||||
layout_flip: Option<Axis>,
|
||||
resize_dimensions: &[Option<Rect>],
|
||||
) -> Vec<Rect>;
|
||||
}
|
||||
@@ -31,7 +31,7 @@ impl Arrangement for DefaultLayout {
|
||||
area: &Rect,
|
||||
len: NonZeroUsize,
|
||||
container_padding: Option<i32>,
|
||||
layout_flip: Option<Flip>,
|
||||
layout_flip: Option<Axis>,
|
||||
resize_dimensions: &[Option<Rect>],
|
||||
) -> Vec<Rect> {
|
||||
let len = usize::from(len);
|
||||
@@ -57,7 +57,7 @@ impl Arrangement for DefaultLayout {
|
||||
let mut stack_left = area.left + primary_right;
|
||||
|
||||
match layout_flip {
|
||||
Some(Flip::Horizontal | Flip::HorizontalAndVertical) if len > 1 => {
|
||||
Some(Axis::Horizontal | Axis::HorizontalAndVertical) if len > 1 => {
|
||||
main_left = main_left + area.right - primary_right;
|
||||
stack_left = area.left;
|
||||
}
|
||||
@@ -99,7 +99,7 @@ impl Arrangement for DefaultLayout {
|
||||
let mut stack_top = area.top + bottom;
|
||||
|
||||
match layout_flip {
|
||||
Some(Flip::Vertical | Flip::HorizontalAndVertical) if len > 1 => {
|
||||
Some(Axis::Vertical | Axis::HorizontalAndVertical) if len > 1 => {
|
||||
main_top = main_top + area.bottom - bottom;
|
||||
stack_top = area.top;
|
||||
}
|
||||
@@ -150,7 +150,7 @@ impl Arrangement for DefaultLayout {
|
||||
let mut secondary = area.left;
|
||||
|
||||
match layout_flip {
|
||||
Some(Flip::Horizontal | Flip::HorizontalAndVertical) if len > 1 => {
|
||||
Some(Axis::Horizontal | Axis::HorizontalAndVertical) if len > 1 => {
|
||||
primary = area.left;
|
||||
secondary = area.left + primary_right;
|
||||
}
|
||||
@@ -165,7 +165,7 @@ impl Arrangement for DefaultLayout {
|
||||
let mut stack = area.left + primary_right + secondary_right;
|
||||
|
||||
match layout_flip {
|
||||
Some(Flip::Horizontal | Flip::HorizontalAndVertical) if len > 1 => {
|
||||
Some(Axis::Horizontal | Axis::HorizontalAndVertical) if len > 1 => {
|
||||
secondary = area.left + primary_right + secondary_right;
|
||||
stack = area.left;
|
||||
}
|
||||
@@ -224,7 +224,7 @@ impl Arrangement for CustomLayout {
|
||||
area: &Rect,
|
||||
len: NonZeroUsize,
|
||||
container_padding: Option<i32>,
|
||||
_layout_flip: Option<Flip>,
|
||||
_layout_flip: Option<Axis>,
|
||||
_resize_dimensions: &[Option<Rect>],
|
||||
) -> Vec<Rect> {
|
||||
let mut dimensions = vec![];
|
||||
@@ -343,7 +343,7 @@ impl Arrangement for CustomLayout {
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ArgEnum)]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
pub enum Flip {
|
||||
pub enum Axis {
|
||||
Horizontal,
|
||||
Vertical,
|
||||
HorizontalAndVertical,
|
||||
@@ -478,7 +478,7 @@ fn recursive_fibonacci(
|
||||
idx: usize,
|
||||
count: usize,
|
||||
area: &Rect,
|
||||
layout_flip: Option<Flip>,
|
||||
layout_flip: Option<Axis>,
|
||||
resize_adjustments: Vec<Option<Rect>>,
|
||||
) -> Vec<Rect> {
|
||||
let mut a = *area;
|
||||
@@ -502,21 +502,21 @@ fn recursive_fibonacci(
|
||||
|
||||
if let Some(flip) = layout_flip {
|
||||
match flip {
|
||||
Flip::Horizontal => {
|
||||
Axis::Horizontal => {
|
||||
main_x = resized.left + half_width + (half_width - half_resized_width);
|
||||
alt_x = resized.left;
|
||||
|
||||
alt_y = resized.top + half_resized_height;
|
||||
main_y = resized.top;
|
||||
}
|
||||
Flip::Vertical => {
|
||||
Axis::Vertical => {
|
||||
main_y = resized.top + half_height + (half_height - half_resized_height);
|
||||
alt_y = resized.top;
|
||||
|
||||
main_x = resized.left;
|
||||
alt_x = resized.left + half_resized_width;
|
||||
}
|
||||
Flip::HorizontalAndVertical => {
|
||||
Axis::HorizontalAndVertical => {
|
||||
main_x = resized.left + half_width + (half_width - half_resized_width);
|
||||
alt_x = resized.left;
|
||||
main_y = resized.top + half_height + (half_height - half_resized_height);
|
||||
|
||||
@@ -12,7 +12,7 @@ use strum::Display;
|
||||
use strum::EnumString;
|
||||
|
||||
pub use arrangement::Arrangement;
|
||||
pub use arrangement::Flip;
|
||||
pub use arrangement::Axis;
|
||||
pub use custom_layout::CustomLayout;
|
||||
pub use cycle_direction::CycleDirection;
|
||||
pub use default_layout::DefaultLayout;
|
||||
@@ -39,7 +39,8 @@ pub enum SocketMessage {
|
||||
CycleFocusWindow(CycleDirection),
|
||||
CycleMoveWindow(CycleDirection),
|
||||
StackWindow(OperationDirection),
|
||||
ResizeWindow(OperationDirection, Sizing),
|
||||
ResizeWindowEdge(OperationDirection, Sizing),
|
||||
ResizeWindowAxis(Axis, Sizing),
|
||||
UnstackWindow,
|
||||
CycleStack(CycleDirection),
|
||||
MoveContainerToMonitorNumber(usize),
|
||||
@@ -57,7 +58,7 @@ pub enum SocketMessage {
|
||||
AdjustWorkspacePadding(Sizing, i32),
|
||||
ChangeLayout(DefaultLayout),
|
||||
ChangeLayoutCustom(PathBuf),
|
||||
FlipLayout(Flip),
|
||||
FlipLayout(Axis),
|
||||
// Monitor and Workspace Commands
|
||||
EnsureWorkspaces(usize, usize),
|
||||
NewWorkspace,
|
||||
|
||||
@@ -7,7 +7,7 @@ use strum::Display;
|
||||
use strum::EnumString;
|
||||
|
||||
use crate::direction::Direction;
|
||||
use crate::Flip;
|
||||
use crate::Axis;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ArgEnum)]
|
||||
#[strum(serialize_all = "snake_case")]
|
||||
@@ -29,23 +29,23 @@ impl OperationDirection {
|
||||
}
|
||||
}
|
||||
|
||||
fn flip(self, layout_flip: Option<Flip>) -> Self {
|
||||
fn flip(self, layout_flip: Option<Axis>) -> Self {
|
||||
layout_flip.map_or(self, |flip| match self {
|
||||
Self::Left => match flip {
|
||||
Flip::Horizontal | Flip::HorizontalAndVertical => Self::Right,
|
||||
Flip::Vertical => self,
|
||||
Axis::Horizontal | Axis::HorizontalAndVertical => Self::Right,
|
||||
Axis::Vertical => self,
|
||||
},
|
||||
Self::Right => match flip {
|
||||
Flip::Horizontal | Flip::HorizontalAndVertical => Self::Left,
|
||||
Flip::Vertical => self,
|
||||
Axis::Horizontal | Axis::HorizontalAndVertical => Self::Left,
|
||||
Axis::Vertical => self,
|
||||
},
|
||||
Self::Up => match flip {
|
||||
Flip::Vertical | Flip::HorizontalAndVertical => Self::Down,
|
||||
Flip::Horizontal => self,
|
||||
Axis::Vertical | Axis::HorizontalAndVertical => Self::Down,
|
||||
Axis::Horizontal => self,
|
||||
},
|
||||
Self::Down => match flip {
|
||||
Flip::Vertical | Flip::HorizontalAndVertical => Self::Up,
|
||||
Flip::Horizontal => self,
|
||||
Axis::Vertical | Axis::HorizontalAndVertical => Self::Up,
|
||||
Axis::Horizontal => self,
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -54,7 +54,7 @@ impl OperationDirection {
|
||||
pub fn destination(
|
||||
self,
|
||||
layout: &dyn Direction,
|
||||
layout_flip: Option<Flip>,
|
||||
layout_flip: Option<Axis>,
|
||||
idx: usize,
|
||||
len: NonZeroUsize,
|
||||
) -> Option<usize> {
|
||||
|
||||
@@ -15,7 +15,9 @@ use miow::pipe::connect;
|
||||
use parking_lot::Mutex;
|
||||
use uds_windows::UnixStream;
|
||||
|
||||
use komorebi_core::Axis;
|
||||
use komorebi_core::FocusFollowsMouseImplementation;
|
||||
use komorebi_core::OperationDirection;
|
||||
use komorebi_core::Rect;
|
||||
use komorebi_core::SocketMessage;
|
||||
use komorebi_core::StateQuery;
|
||||
@@ -260,8 +262,67 @@ impl WindowManager {
|
||||
let mut stream = UnixStream::connect(&socket)?;
|
||||
stream.write_all(response.as_bytes())?;
|
||||
}
|
||||
SocketMessage::ResizeWindow(direction, sizing) => {
|
||||
self.resize_window(direction, sizing, Option::from(50))?;
|
||||
SocketMessage::ResizeWindowEdge(direction, sizing) => {
|
||||
self.resize_window(direction, sizing, Option::from(50), true)?;
|
||||
}
|
||||
SocketMessage::ResizeWindowAxis(axis, sizing) => {
|
||||
match axis {
|
||||
Axis::Horizontal => {
|
||||
self.resize_window(
|
||||
OperationDirection::Left,
|
||||
sizing,
|
||||
Option::from(50),
|
||||
false,
|
||||
)?;
|
||||
self.resize_window(
|
||||
OperationDirection::Right,
|
||||
sizing,
|
||||
Option::from(50),
|
||||
false,
|
||||
)?;
|
||||
}
|
||||
Axis::Vertical => {
|
||||
self.resize_window(
|
||||
OperationDirection::Up,
|
||||
sizing,
|
||||
Option::from(50),
|
||||
false,
|
||||
)?;
|
||||
self.resize_window(
|
||||
OperationDirection::Down,
|
||||
sizing,
|
||||
Option::from(50),
|
||||
false,
|
||||
)?;
|
||||
}
|
||||
Axis::HorizontalAndVertical => {
|
||||
self.resize_window(
|
||||
OperationDirection::Left,
|
||||
sizing,
|
||||
Option::from(50),
|
||||
false,
|
||||
)?;
|
||||
self.resize_window(
|
||||
OperationDirection::Right,
|
||||
sizing,
|
||||
Option::from(50),
|
||||
false,
|
||||
)?;
|
||||
self.resize_window(
|
||||
OperationDirection::Up,
|
||||
sizing,
|
||||
Option::from(50),
|
||||
false,
|
||||
)?;
|
||||
self.resize_window(
|
||||
OperationDirection::Down,
|
||||
sizing,
|
||||
Option::from(50),
|
||||
false,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
self.update_focused_workspace(false)?;
|
||||
}
|
||||
SocketMessage::FocusFollowsMouse(mut implementation, enable) => {
|
||||
if !CUSTOM_FFM.load(Ordering::SeqCst) {
|
||||
|
||||
@@ -384,7 +384,7 @@ impl WindowManager {
|
||||
}
|
||||
|
||||
for (edge, sizing, step) in ops {
|
||||
self.resize_window(edge, sizing, Option::from(step))?;
|
||||
self.resize_window(edge, sizing, Option::from(step), true)?;
|
||||
}
|
||||
|
||||
self.update_focused_workspace(false)?;
|
||||
|
||||
@@ -16,9 +16,9 @@ use uds_windows::UnixListener;
|
||||
|
||||
use komorebi_core::custom_layout::CustomLayout;
|
||||
use komorebi_core::Arrangement;
|
||||
use komorebi_core::Axis;
|
||||
use komorebi_core::CycleDirection;
|
||||
use komorebi_core::DefaultLayout;
|
||||
use komorebi_core::Flip;
|
||||
use komorebi_core::FocusFollowsMouseImplementation;
|
||||
use komorebi_core::Layout;
|
||||
use komorebi_core::OperationDirection;
|
||||
@@ -677,6 +677,7 @@ impl WindowManager {
|
||||
direction: OperationDirection,
|
||||
sizing: Sizing,
|
||||
step: Option<i32>,
|
||||
update: bool,
|
||||
) -> Result<()> {
|
||||
let work_area = self.focused_monitor_work_area()?;
|
||||
let workspace = self.focused_workspace_mut()?;
|
||||
@@ -715,21 +716,21 @@ impl WindowManager {
|
||||
// can flip them however they need to be flipped once the resizing has been done
|
||||
if let Some(flip) = workspace.layout_flip() {
|
||||
match flip {
|
||||
Flip::Horizontal => {
|
||||
Axis::Horizontal => {
|
||||
if matches!(direction, OperationDirection::Left)
|
||||
|| matches!(direction, OperationDirection::Right)
|
||||
{
|
||||
direction = direction.opposite();
|
||||
}
|
||||
}
|
||||
Flip::Vertical => {
|
||||
Axis::Vertical => {
|
||||
if matches!(direction, OperationDirection::Up)
|
||||
|| matches!(direction, OperationDirection::Down)
|
||||
{
|
||||
direction = direction.opposite();
|
||||
}
|
||||
}
|
||||
Flip::HorizontalAndVertical => direction = direction.opposite(),
|
||||
Axis::HorizontalAndVertical => direction = direction.opposite(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -744,7 +745,12 @@ impl WindowManager {
|
||||
);
|
||||
|
||||
workspace.resize_dimensions_mut()[focused_idx] = resize;
|
||||
return self.update_focused_workspace(false);
|
||||
|
||||
return if update {
|
||||
self.update_focused_workspace(false)
|
||||
} else {
|
||||
Ok(())
|
||||
};
|
||||
}
|
||||
|
||||
tracing::warn!("cannot resize container in this direction");
|
||||
@@ -1085,7 +1091,7 @@ impl WindowManager {
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub fn flip_layout(&mut self, layout_flip: Flip) -> Result<()> {
|
||||
pub fn flip_layout(&mut self, layout_flip: Axis) -> Result<()> {
|
||||
tracing::info!("flipping layout");
|
||||
|
||||
let workspace = self.focused_workspace_mut()?;
|
||||
@@ -1097,28 +1103,28 @@ impl WindowManager {
|
||||
}
|
||||
Some(current_layout_flip) => {
|
||||
match current_layout_flip {
|
||||
Flip::Horizontal => match layout_flip {
|
||||
Flip::Horizontal => workspace.set_layout_flip(None),
|
||||
Flip::Vertical => {
|
||||
workspace.set_layout_flip(Option::from(Flip::HorizontalAndVertical))
|
||||
Axis::Horizontal => match layout_flip {
|
||||
Axis::Horizontal => workspace.set_layout_flip(None),
|
||||
Axis::Vertical => {
|
||||
workspace.set_layout_flip(Option::from(Axis::HorizontalAndVertical))
|
||||
}
|
||||
Flip::HorizontalAndVertical => {
|
||||
workspace.set_layout_flip(Option::from(Flip::HorizontalAndVertical))
|
||||
Axis::HorizontalAndVertical => {
|
||||
workspace.set_layout_flip(Option::from(Axis::HorizontalAndVertical))
|
||||
}
|
||||
},
|
||||
Flip::Vertical => match layout_flip {
|
||||
Flip::Horizontal => {
|
||||
workspace.set_layout_flip(Option::from(Flip::HorizontalAndVertical))
|
||||
Axis::Vertical => match layout_flip {
|
||||
Axis::Horizontal => {
|
||||
workspace.set_layout_flip(Option::from(Axis::HorizontalAndVertical))
|
||||
}
|
||||
Flip::Vertical => workspace.set_layout_flip(None),
|
||||
Flip::HorizontalAndVertical => {
|
||||
workspace.set_layout_flip(Option::from(Flip::HorizontalAndVertical))
|
||||
Axis::Vertical => workspace.set_layout_flip(None),
|
||||
Axis::HorizontalAndVertical => {
|
||||
workspace.set_layout_flip(Option::from(Axis::HorizontalAndVertical))
|
||||
}
|
||||
},
|
||||
Flip::HorizontalAndVertical => match layout_flip {
|
||||
Flip::Horizontal => workspace.set_layout_flip(Option::from(Flip::Vertical)),
|
||||
Flip::Vertical => workspace.set_layout_flip(Option::from(Flip::Horizontal)),
|
||||
Flip::HorizontalAndVertical => workspace.set_layout_flip(None),
|
||||
Axis::HorizontalAndVertical => match layout_flip {
|
||||
Axis::Horizontal => workspace.set_layout_flip(Option::from(Axis::Vertical)),
|
||||
Axis::Vertical => workspace.set_layout_flip(Option::from(Axis::Horizontal)),
|
||||
Axis::HorizontalAndVertical => workspace.set_layout_flip(None),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ use getset::MutGetters;
|
||||
use getset::Setters;
|
||||
use serde::Serialize;
|
||||
|
||||
use komorebi_core::Axis;
|
||||
use komorebi_core::CycleDirection;
|
||||
use komorebi_core::DefaultLayout;
|
||||
use komorebi_core::Flip;
|
||||
use komorebi_core::Layout;
|
||||
use komorebi_core::OperationDirection;
|
||||
use komorebi_core::Rect;
|
||||
@@ -41,7 +41,7 @@ pub struct Workspace {
|
||||
#[getset(get = "pub", set = "pub")]
|
||||
layout: Layout,
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
layout_flip: Option<Flip>,
|
||||
layout_flip: Option<Axis>,
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
workspace_padding: Option<i32>,
|
||||
#[getset(get_copy = "pub", set = "pub")]
|
||||
|
||||
@@ -68,6 +68,10 @@ Resize(edge, sizing) {
|
||||
Run, komorebic.exe resize %edge% %sizing%, , Hide
|
||||
}
|
||||
|
||||
ResizeAxis(axis, sizing) {
|
||||
Run, komorebic.exe resize-axis %axis% %sizing%, , Hide
|
||||
}
|
||||
|
||||
Unstack() {
|
||||
Run, komorebic.exe unstack, , Hide
|
||||
}
|
||||
@@ -136,8 +140,8 @@ LoadCustomLayout(path) {
|
||||
Run, komorebic.exe load-custom-layout %path%, , Hide
|
||||
}
|
||||
|
||||
FlipLayout(flip) {
|
||||
Run, komorebic.exe flip-layout %flip%, , Hide
|
||||
FlipLayout(axis) {
|
||||
Run, komorebic.exe flip-layout %axis%, , Hide
|
||||
}
|
||||
|
||||
Promote() {
|
||||
|
||||
@@ -28,9 +28,9 @@ use windows::Win32::UI::WindowsAndMessaging::SW_RESTORE;
|
||||
use derive_ahk::AhkFunction;
|
||||
use derive_ahk::AhkLibrary;
|
||||
use komorebi_core::ApplicationIdentifier;
|
||||
use komorebi_core::Axis;
|
||||
use komorebi_core::CycleDirection;
|
||||
use komorebi_core::DefaultLayout;
|
||||
use komorebi_core::Flip;
|
||||
use komorebi_core::FocusFollowsMouseImplementation;
|
||||
use komorebi_core::OperationDirection;
|
||||
use komorebi_core::Rect;
|
||||
@@ -85,7 +85,7 @@ gen_enum_subcommand_args! {
|
||||
CycleWorkspace: CycleDirection,
|
||||
Stack: OperationDirection,
|
||||
CycleStack: CycleDirection,
|
||||
FlipLayout: Flip,
|
||||
FlipLayout: Axis,
|
||||
ChangeLayout: DefaultLayout,
|
||||
WatchConfiguration: BooleanState,
|
||||
MouseFollowsFocus: BooleanState,
|
||||
@@ -168,6 +168,14 @@ struct Resize {
|
||||
sizing: Sizing,
|
||||
}
|
||||
|
||||
#[derive(Parser, AhkFunction)]
|
||||
struct ResizeAxis {
|
||||
#[clap(arg_enum)]
|
||||
axis: Axis,
|
||||
#[clap(arg_enum)]
|
||||
sizing: Sizing,
|
||||
}
|
||||
|
||||
#[derive(Parser, AhkFunction)]
|
||||
struct InvisibleBorders {
|
||||
/// Size of the left invisible border
|
||||
@@ -381,6 +389,9 @@ enum SubCommand {
|
||||
/// Resize the focused window in the specified direction
|
||||
#[clap(setting = AppSettings::ArgRequiredElseHelp)]
|
||||
Resize(Resize),
|
||||
/// Resize the focused window along the specified axis
|
||||
#[clap(setting = AppSettings::ArgRequiredElseHelp)]
|
||||
ResizeAxis(ResizeAxis),
|
||||
/// Unstack the focused window
|
||||
Unstack,
|
||||
/// Cycle the focused stack in the specified cycle direction
|
||||
@@ -757,7 +768,7 @@ fn main() -> Result<()> {
|
||||
)?;
|
||||
}
|
||||
SubCommand::FlipLayout(arg) => {
|
||||
send_message(&*SocketMessage::FlipLayout(arg.flip).as_bytes()?)?;
|
||||
send_message(&*SocketMessage::FlipLayout(arg.axis).as_bytes()?)?;
|
||||
}
|
||||
SubCommand::FocusMonitor(arg) => {
|
||||
send_message(&*SocketMessage::FocusMonitorNumber(arg.target).as_bytes()?)?;
|
||||
@@ -868,7 +879,12 @@ fn main() -> Result<()> {
|
||||
}
|
||||
}
|
||||
SubCommand::Resize(resize) => {
|
||||
send_message(&*SocketMessage::ResizeWindow(resize.edge, resize.sizing).as_bytes()?)?;
|
||||
send_message(
|
||||
&*SocketMessage::ResizeWindowEdge(resize.edge, resize.sizing).as_bytes()?,
|
||||
)?;
|
||||
}
|
||||
SubCommand::ResizeAxis(arg) => {
|
||||
send_message(&*SocketMessage::ResizeWindowAxis(arg.axis, arg.sizing).as_bytes()?)?;
|
||||
}
|
||||
SubCommand::FocusFollowsMouse(arg) => {
|
||||
send_message(
|
||||
|
||||
Reference in New Issue
Block a user