Skip to content

Commit

Permalink
feat(config): add aspect ratios for float toggling
Browse files Browse the repository at this point in the history
This commit adds a new configuration option
"floating_window_aspect_ratio", which users can manipulate to set their
desired window size when using the toggle-float command.

resolve #1230
  • Loading branch information
LGUG2Z committed Jan 24, 2025
1 parent 0a2dbed commit 473e7cd
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 118 deletions.
2 changes: 2 additions & 0 deletions komorebi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ lazy_static! {

static ref WINDOWS_BY_BAR_HWNDS: Arc<Mutex<HashMap<isize, VecDeque<isize>>>> =
Arc::new(Mutex::new(HashMap::new()));

static ref FLOATING_WINDOW_TOGGLE_ASPECT_RATIO: Arc<Mutex<AspectRatio>> = Arc::new(Mutex::new(AspectRatio::Predefined(PredefinedAspectRatio::Widescreen)));
}

pub static DEFAULT_WORKSPACE_PADDING: AtomicI32 = AtomicI32::new(10);
Expand Down
11 changes: 11 additions & 0 deletions komorebi/src/static_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,16 @@ use crate::window_manager::WindowManager;
use crate::window_manager_event::WindowManagerEvent;
use crate::windows_api::WindowsApi;
use crate::workspace::Workspace;
use crate::AspectRatio;
use crate::Axis;
use crate::CrossBoundaryBehaviour;
use crate::PredefinedAspectRatio;
use crate::DATA_DIR;
use crate::DEFAULT_CONTAINER_PADDING;
use crate::DEFAULT_WORKSPACE_PADDING;
use crate::DISPLAY_INDEX_PREFERENCES;
use crate::FLOATING_APPLICATIONS;
use crate::FLOATING_WINDOW_TOGGLE_ASPECT_RATIO;
use crate::HIDING_BEHAVIOUR;
use crate::IGNORE_IDENTIFIERS;
use crate::LAYERED_WHITELIST;
Expand Down Expand Up @@ -382,6 +385,9 @@ pub struct StaticConfig {
/// HEAVILY DISCOURAGED: Identify applications for which komorebi should forcibly remove title bars
#[serde(skip_serializing_if = "Option::is_none")]
pub remove_titlebar_applications: Option<Vec<MatchingRule>>,
/// Aspect ratio to resize with when toggling floating mode for a window
#[serde(skip_serializing_if = "Option::is_none")]
pub floating_window_aspect_ratio: Option<AspectRatio>,
}

#[derive(Debug, Serialize, Deserialize, JsonSchema)]
Expand Down Expand Up @@ -637,13 +643,18 @@ impl From<&WindowManager> for StaticConfig {
slow_application_identifiers: Option::from(SLOW_APPLICATION_IDENTIFIERS.lock().clone()),
bar_configurations: None,
remove_titlebar_applications: Option::from(NO_TITLEBAR.lock().clone()),
floating_window_aspect_ratio: Option::from(*FLOATING_WINDOW_TOGGLE_ASPECT_RATIO.lock()),
}
}
}

impl StaticConfig {
#[allow(clippy::cognitive_complexity, clippy::too_many_lines)]
fn apply_globals(&mut self) -> Result<()> {
*FLOATING_WINDOW_TOGGLE_ASPECT_RATIO.lock() = self
.floating_window_aspect_ratio
.unwrap_or(AspectRatio::Predefined(PredefinedAspectRatio::Standard));

if let Some(monitor_index_preferences) = &self.monitor_index_preferences {
let mut preferences = MONITOR_INDEX_PREFERENCES.lock();
preferences.clone_from(monitor_index_preferences);
Expand Down
63 changes: 51 additions & 12 deletions komorebi/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crate::focus_manager;
use crate::stackbar_manager;
use crate::windows_api;
use crate::AnimationStyle;
use crate::FLOATING_WINDOW_TOGGLE_ASPECT_RATIO;
use crate::SLOW_APPLICATION_COMPENSATION_TIME;
use crate::SLOW_APPLICATION_IDENTIFIERS;
use std::collections::HashMap;
Expand Down Expand Up @@ -296,6 +297,38 @@ impl RenderDispatcher for TransparencyRenderDispatcher {
}
}

#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
#[serde(untagged)]
pub enum AspectRatio {
/// A predefined aspect ratio
Predefined(PredefinedAspectRatio),
/// A custom W:H aspect ratio
Custom(i32, i32),
}

#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub enum PredefinedAspectRatio {
/// 21:9
Ultrawide,
/// 16:9
Widescreen,
/// 4:3
Standard,
}

impl AspectRatio {
pub fn width_and_height(self) -> (i32, i32) {
match self {
AspectRatio::Predefined(predefined) => match predefined {
PredefinedAspectRatio::Ultrawide => (21, 9),
PredefinedAspectRatio::Widescreen => (16, 9),
PredefinedAspectRatio::Standard => (4, 3),
},
AspectRatio::Custom(w, h) => (w, h),
}
}
}

impl Window {
pub const fn hwnd(self) -> HWND {
HWND(windows_api::as_ptr!(self.hwnd))
Expand Down Expand Up @@ -369,15 +402,21 @@ impl Window {
}

pub fn center(&mut self, work_area: &Rect) -> Result<()> {
let half_width = work_area.right / 2;
let half_weight = work_area.bottom / 2;
let (aspect_ratio_width, aspect_ratio_height) = FLOATING_WINDOW_TOGGLE_ASPECT_RATIO
.lock()
.width_and_height();
let target_height = work_area.bottom / 2;
let target_width = (target_height * aspect_ratio_width) / aspect_ratio_height;

let x = work_area.left + ((work_area.right - target_width) / 2);
let y = work_area.top + ((work_area.bottom - target_height) / 2);

self.set_position(
&Rect {
left: work_area.left + ((work_area.right - half_width) / 2),
top: work_area.top + ((work_area.bottom - half_weight) / 2),
right: half_width,
bottom: half_weight,
left: x,
top: y,
right: target_width,
bottom: target_height,
},
true,
)
Expand Down Expand Up @@ -928,12 +967,12 @@ fn window_is_eligible(
}

if (allow_wsl2_gui || allow_titlebar_removed || style.contains(WindowStyle::CAPTION) && ex_style.contains(ExtendedWindowStyle::WINDOWEDGE))
&& !ex_style.contains(ExtendedWindowStyle::DLGMODALFRAME)
// Get a lot of dupe events coming through that make the redrawing go crazy
// on FocusChange events if I don't filter out this one. But, if we are
// allowing a specific layered window on the whitelist (like Steam), it should
// pass this check
&& (allow_layered || !ex_style.contains(ExtendedWindowStyle::LAYERED))
&& !ex_style.contains(ExtendedWindowStyle::DLGMODALFRAME)
// Get a lot of dupe events coming through that make the redrawing go crazy
// on FocusChange events if I don't filter out this one. But, if we are
// allowing a specific layered window on the whitelist (like Steam), it should
// pass this check
&& (allow_layered || !ex_style.contains(ExtendedWindowStyle::LAYERED))
|| managed_override
{
return true;
Expand Down
Loading

0 comments on commit 473e7cd

Please sign in to comment.