Skip to content

Commit

Permalink
feat: add new position command; allow size and position to be set w…
Browse files Browse the repository at this point in the history
…ith `set-floating` command (#817)
  • Loading branch information
DreamMaoMao authored Nov 7, 2024
1 parent bc7839a commit 04e6c2f
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 3 deletions.
72 changes: 69 additions & 3 deletions packages/wm/src/app_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ use crate::{
windows::{
commands::{
ignore_window, move_window_in_direction, move_window_to_workspace,
resize_window, set_window_size, update_window_state,
resize_window, set_window_position, set_window_position_to_center,
set_window_size, update_window_state,
},
traits::WindowGetters,
WindowState,
Expand Down Expand Up @@ -188,13 +189,26 @@ pub enum InvokeCommand {
#[clap(long)]
direction: Direction,
},
Position(InvokePositionCommand),
Resize(InvokeResizeCommand),
SetFloating {
#[clap(long, default_missing_value = "true", require_equals = true, num_args = 0..=1)]
shown_on_top: Option<bool>,

#[clap(long, default_missing_value = "true", require_equals = true, num_args = 0..=1)]
centered: Option<bool>,

#[clap(long, allow_hyphen_values = true)]
x_pos: Option<i32>,

#[clap(long, allow_hyphen_values = true)]
y_pos: Option<i32>,

#[clap(long, allow_hyphen_values = true)]
width: Option<LengthValue>,

#[clap(long, allow_hyphen_values = true)]
height: Option<LengthValue>,
},
SetFullscreen {
#[clap(long, default_missing_value = "true", require_equals = true, num_args = 0..=1)]
Expand Down Expand Up @@ -430,6 +444,20 @@ impl InvokeCommand {
config,
)
}
InvokeCommand::Position(args) => {
match subject_container.as_window_container() {
Ok(window) => match args.centered {
true => set_window_position_to_center(window, state),
false => set_window_position(
window,
args.x_pos.clone(),
args.y_pos.clone(),
state,
),
},
_ => Ok(()),
}
}
InvokeCommand::Resize(args) => {
match subject_container.as_window_container() {
Ok(window) => resize_window(
Expand All @@ -444,22 +472,47 @@ impl InvokeCommand {
InvokeCommand::SetFloating {
centered,
shown_on_top,
x_pos,
y_pos,
width,
height,
} => match subject_container.as_window_container() {
Ok(window) => {
let floating_defaults =
&config.value.window_behavior.state_defaults.floating;
let is_centered = centered.unwrap_or(floating_defaults.centered);

update_window_state(
let window = update_window_state(
window.clone(),
WindowState::Floating(FloatingStateConfig {
centered: centered.unwrap_or(floating_defaults.centered),
centered: is_centered,
shown_on_top: shown_on_top
.unwrap_or(floating_defaults.shown_on_top),
}),
state,
config,
)?;

if width.is_some() || height.is_some() {
set_window_size(
window.clone(),
width.clone(),
height.clone(),
state,
)?;
}

if is_centered {
set_window_position_to_center(window, state)?;
} else if x_pos.is_some() || y_pos.is_some() {
set_window_position(
window.clone(),
x_pos.clone(),
y_pos.clone(),
state,
)?;
}

Ok(())
}
_ => Ok(()),
Expand Down Expand Up @@ -801,3 +854,16 @@ pub struct InvokeResizeCommand {
#[clap(long, allow_hyphen_values = true)]
height: Option<LengthValue>,
}

#[derive(Args, Clone, Debug, PartialEq, Serialize)]
#[group(required = true, multiple = true)]
pub struct InvokePositionCommand {
#[clap(long, action)]
centered: bool,

#[clap(long, allow_hyphen_values = true)]
x_pos: Option<i32>,

#[clap(long, allow_hyphen_values = true)]
y_pos: Option<i32>,
}
4 changes: 4 additions & 0 deletions packages/wm/src/user_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ impl UserConfig {
commands: vec![InvokeCommand::SetFloating {
centered: Some(floating_defaults.centered),
shown_on_top: Some(floating_defaults.shown_on_top),
x_pos: None,
y_pos: None,
width: None,
height: None,
}],
match_window: vec![
WindowMatchConfig {
Expand Down
2 changes: 2 additions & 0 deletions packages/wm/src/windows/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod move_window_in_direction;
mod move_window_to_workspace;
mod resize_window;
mod run_window_rules;
mod set_window_position;
mod set_window_size;
mod unmanage_window;
mod update_window_state;
Expand All @@ -14,6 +15,7 @@ pub use move_window_in_direction::*;
pub use move_window_to_workspace::*;
pub use resize_window::*;
pub use run_window_rules::*;
pub use set_window_position::*;
pub use set_window_size::*;
pub use unmanage_window::*;
pub use update_window_state::*;
57 changes: 57 additions & 0 deletions packages/wm/src/windows/commands/set_window_position.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use anyhow::Context;

use crate::{
common::Rect,
containers::{
traits::{CommonGetters, PositionGetters},
WindowContainer,
},
windows::{traits::WindowGetters, WindowState},
wm_state::WmState,
};

pub fn set_window_position(
window: WindowContainer,
target_x_pos: Option<i32>,
target_y_pos: Option<i32>,
state: &mut WmState,
) -> anyhow::Result<()> {
if matches!(window.state(), WindowState::Floating(_)) {
let window_rect = window.floating_placement();
let new_x_pos = target_x_pos.unwrap_or(window_rect.x());
let new_y_pos = target_y_pos.unwrap_or(window_rect.y());
window.set_floating_placement(Rect::from_xy(
new_x_pos,
new_y_pos,
window.floating_placement().width(),
window.floating_placement().height(),
));

state
.pending_sync
.containers_to_redraw
.push(window.clone().into());
}

Ok(())
}

pub fn set_window_position_to_center(
window: WindowContainer,
state: &mut WmState,
) -> anyhow::Result<()> {
if matches!(window.state(), WindowState::Floating(_)) {
let window_rect = window.floating_placement();
let workspace = window.workspace().context("no workspace find.")?;
window.set_floating_placement(
window_rect.translate_to_center(&workspace.to_rect()?),
);

state
.pending_sync
.containers_to_redraw
.push(window.clone().into());
}

Ok(())
}

0 comments on commit 04e6c2f

Please sign in to comment.