mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-05-31 16:00:41 +02:00
feat(wm): add new float override option
This commit introduces a new option `float_override`, which makes it so every every window opened, shown or uncloaked will be set to floating, but it won't be ignored. It will be added to the floating_windows of the workspace, meaning that the user can later tile that window with toggle-float command. This allows the users to have all windows open as floating and then manually tile the ones they want.
This commit is contained in:
@@ -343,10 +343,23 @@ pub enum FocusFollowsMouseImplementation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ValueEnum, JsonSchema,
|
Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema, PartialEq,
|
||||||
|
)]
|
||||||
|
pub struct WindowManagementBehaviour {
|
||||||
|
/// The current WindowContainerBehaviour to be used
|
||||||
|
pub current_behaviour: WindowContainerBehaviour,
|
||||||
|
/// Override of `current_behaviour` to open new windows as floating windows
|
||||||
|
/// that can be later toggled to tiled, when false it will default to
|
||||||
|
/// `current_behaviour` again.
|
||||||
|
pub float_override: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(
|
||||||
|
Clone, Copy, Debug, Default, Serialize, Deserialize, Display, EnumString, ValueEnum, JsonSchema, PartialEq
|
||||||
)]
|
)]
|
||||||
pub enum WindowContainerBehaviour {
|
pub enum WindowContainerBehaviour {
|
||||||
/// Create a new container for each new window
|
/// Create a new container for each new window
|
||||||
|
#[default]
|
||||||
Create,
|
Create,
|
||||||
/// Append new windows to the focused window container
|
/// Append new windows to the focused window container
|
||||||
Append,
|
Append,
|
||||||
|
|||||||
@@ -1346,12 +1346,12 @@ impl WindowManager {
|
|||||||
self.resize_delta = delta;
|
self.resize_delta = delta;
|
||||||
}
|
}
|
||||||
SocketMessage::ToggleWindowContainerBehaviour => {
|
SocketMessage::ToggleWindowContainerBehaviour => {
|
||||||
match self.window_container_behaviour {
|
match self.window_management_behaviour.current_behaviour {
|
||||||
WindowContainerBehaviour::Create => {
|
WindowContainerBehaviour::Create => {
|
||||||
self.window_container_behaviour = WindowContainerBehaviour::Append;
|
self.window_management_behaviour.current_behaviour = WindowContainerBehaviour::Append;
|
||||||
}
|
}
|
||||||
WindowContainerBehaviour::Append => {
|
WindowContainerBehaviour::Append => {
|
||||||
self.window_container_behaviour = WindowContainerBehaviour::Create;
|
self.window_management_behaviour.current_behaviour = WindowContainerBehaviour::Create;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -333,8 +333,8 @@ impl WindowManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if proceed {
|
if proceed {
|
||||||
let behaviour =
|
let mut behaviour =
|
||||||
self.window_container_behaviour(focused_monitor_idx, focused_workspace_idx);
|
self.window_management_behaviour(focused_monitor_idx, focused_workspace_idx);
|
||||||
let workspace = self.focused_workspace_mut()?;
|
let workspace = self.focused_workspace_mut()?;
|
||||||
let workspace_contains_window = workspace.contains_window(window.hwnd);
|
let workspace_contains_window = workspace.contains_window(window.hwnd);
|
||||||
let monocle_container = workspace.monocle_container().clone();
|
let monocle_container = workspace.monocle_container().clone();
|
||||||
@@ -360,11 +360,13 @@ impl WindowManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if should_float && !matches!(event, WindowManagerEvent::Manage(_)) {
|
behaviour.float_override = behaviour.float_override || (should_float && !matches!(event, WindowManagerEvent::Manage(_)));
|
||||||
|
|
||||||
|
if behaviour.float_override {
|
||||||
workspace.floating_windows_mut().push(window);
|
workspace.floating_windows_mut().push(window);
|
||||||
self.update_focused_workspace(false, true)?;
|
self.update_focused_workspace(false, false)?;
|
||||||
} else {
|
} else {
|
||||||
match behaviour {
|
match behaviour.current_behaviour {
|
||||||
WindowContainerBehaviour::Create => {
|
WindowContainerBehaviour::Create => {
|
||||||
workspace.new_container_for_window(window);
|
workspace.new_container_for_window(window);
|
||||||
self.update_focused_workspace(false, false)?;
|
self.update_focused_workspace(false, false)?;
|
||||||
@@ -375,7 +377,6 @@ impl WindowManager {
|
|||||||
.ok_or_else(|| anyhow!("there is no focused container"))?
|
.ok_or_else(|| anyhow!("there is no focused container"))?
|
||||||
.add_window(window);
|
.add_window(window);
|
||||||
self.update_focused_workspace(true, false)?;
|
self.update_focused_workspace(true, false)?;
|
||||||
|
|
||||||
stackbar_manager::send_notification();
|
stackbar_manager::send_notification();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -431,8 +432,8 @@ impl WindowManager {
|
|||||||
|
|
||||||
let focused_monitor_idx = self.focused_monitor_idx();
|
let focused_monitor_idx = self.focused_monitor_idx();
|
||||||
let focused_workspace_idx = self.focused_workspace_idx().unwrap_or_default();
|
let focused_workspace_idx = self.focused_workspace_idx().unwrap_or_default();
|
||||||
let window_container_behaviour =
|
let window_management_behaviour =
|
||||||
self.window_container_behaviour(focused_monitor_idx, focused_workspace_idx);
|
self.window_management_behaviour(focused_monitor_idx, focused_workspace_idx);
|
||||||
|
|
||||||
let workspace = self.focused_workspace_mut()?;
|
let workspace = self.focused_workspace_mut()?;
|
||||||
let focused_container_idx = workspace.focused_container_idx();
|
let focused_container_idx = workspace.focused_container_idx();
|
||||||
@@ -550,8 +551,11 @@ impl WindowManager {
|
|||||||
}
|
}
|
||||||
// Here we handle a simple move on the same monitor which is treated as
|
// Here we handle a simple move on the same monitor which is treated as
|
||||||
// a container swap
|
// a container swap
|
||||||
|
} else if window_management_behaviour.float_override {
|
||||||
|
workspace.floating_windows_mut().push(window);
|
||||||
|
self.update_focused_workspace(false, false)?;
|
||||||
} else {
|
} else {
|
||||||
match window_container_behaviour {
|
match window_management_behaviour.current_behaviour {
|
||||||
WindowContainerBehaviour::Create => {
|
WindowContainerBehaviour::Create => {
|
||||||
match workspace.container_idx_from_current_point() {
|
match workspace.container_idx_from_current_point() {
|
||||||
Some(target_idx) => {
|
Some(target_idx) => {
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ use crate::core::OperationBehaviour;
|
|||||||
use crate::core::Rect;
|
use crate::core::Rect;
|
||||||
use crate::core::SocketMessage;
|
use crate::core::SocketMessage;
|
||||||
use crate::core::WindowContainerBehaviour;
|
use crate::core::WindowContainerBehaviour;
|
||||||
|
use crate::core::WindowManagementBehaviour;
|
||||||
use color_eyre::Result;
|
use color_eyre::Result;
|
||||||
use crossbeam_channel::Receiver;
|
use crossbeam_channel::Receiver;
|
||||||
use hotwatch::EventKind;
|
use hotwatch::EventKind;
|
||||||
@@ -235,6 +236,10 @@ pub struct StaticConfig {
|
|||||||
/// Determine what happens when a new window is opened (default: Create)
|
/// Determine what happens when a new window is opened (default: Create)
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub window_container_behaviour: Option<WindowContainerBehaviour>,
|
pub window_container_behaviour: Option<WindowContainerBehaviour>,
|
||||||
|
/// Enable or disable float override, which makes it so every new window opens in floating mode
|
||||||
|
/// (default: false)
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub float_override: Option<bool>,
|
||||||
/// Determine what happens when a window is moved across a monitor boundary (default: Swap)
|
/// Determine what happens when a window is moved across a monitor boundary (default: Swap)
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub cross_monitor_move_behaviour: Option<MoveBehaviour>,
|
pub cross_monitor_move_behaviour: Option<MoveBehaviour>,
|
||||||
@@ -520,7 +525,8 @@ impl From<&WindowManager> for StaticConfig {
|
|||||||
Self {
|
Self {
|
||||||
invisible_borders: None,
|
invisible_borders: None,
|
||||||
resize_delta: Option::from(value.resize_delta),
|
resize_delta: Option::from(value.resize_delta),
|
||||||
window_container_behaviour: Option::from(value.window_container_behaviour),
|
window_container_behaviour: Option::from(value.window_management_behaviour.current_behaviour),
|
||||||
|
float_override: Option::from(value.window_management_behaviour.float_override),
|
||||||
cross_monitor_move_behaviour: Option::from(value.cross_monitor_move_behaviour),
|
cross_monitor_move_behaviour: Option::from(value.cross_monitor_move_behaviour),
|
||||||
cross_boundary_behaviour: Option::from(value.cross_boundary_behaviour),
|
cross_boundary_behaviour: Option::from(value.cross_boundary_behaviour),
|
||||||
unmanaged_window_operation_behaviour: Option::from(
|
unmanaged_window_operation_behaviour: Option::from(
|
||||||
@@ -1031,9 +1037,10 @@ impl StaticConfig {
|
|||||||
is_paused: false,
|
is_paused: false,
|
||||||
virtual_desktop_id: current_virtual_desktop(),
|
virtual_desktop_id: current_virtual_desktop(),
|
||||||
work_area_offset: value.global_work_area_offset,
|
work_area_offset: value.global_work_area_offset,
|
||||||
window_container_behaviour: value
|
window_management_behaviour: WindowManagementBehaviour {
|
||||||
.window_container_behaviour
|
current_behaviour: value.window_container_behaviour.unwrap_or(WindowContainerBehaviour::Create),
|
||||||
.unwrap_or(WindowContainerBehaviour::Create),
|
float_override: value.float_override.unwrap_or_default(),
|
||||||
|
},
|
||||||
cross_monitor_move_behaviour: value
|
cross_monitor_move_behaviour: value
|
||||||
.cross_monitor_move_behaviour
|
.cross_monitor_move_behaviour
|
||||||
.unwrap_or(MoveBehaviour::Swap),
|
.unwrap_or(MoveBehaviour::Swap),
|
||||||
@@ -1208,7 +1215,11 @@ impl StaticConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(val) = value.window_container_behaviour {
|
if let Some(val) = value.window_container_behaviour {
|
||||||
wm.window_container_behaviour = val;
|
wm.window_management_behaviour.current_behaviour = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(val) = value.float_override {
|
||||||
|
wm.window_management_behaviour.float_override = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(val) = value.cross_monitor_move_behaviour {
|
if let Some(val) = value.cross_monitor_move_behaviour {
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ use crate::core::Rect;
|
|||||||
use crate::core::Sizing;
|
use crate::core::Sizing;
|
||||||
use crate::core::StackbarLabel;
|
use crate::core::StackbarLabel;
|
||||||
use crate::core::WindowContainerBehaviour;
|
use crate::core::WindowContainerBehaviour;
|
||||||
|
use crate::core::WindowManagementBehaviour;
|
||||||
|
|
||||||
use crate::border_manager;
|
use crate::border_manager;
|
||||||
use crate::border_manager::STYLE;
|
use crate::border_manager::STYLE;
|
||||||
@@ -92,7 +93,7 @@ pub struct WindowManager {
|
|||||||
pub is_paused: bool,
|
pub is_paused: bool,
|
||||||
pub work_area_offset: Option<Rect>,
|
pub work_area_offset: Option<Rect>,
|
||||||
pub resize_delta: i32,
|
pub resize_delta: i32,
|
||||||
pub window_container_behaviour: WindowContainerBehaviour,
|
pub window_management_behaviour: WindowManagementBehaviour,
|
||||||
pub cross_monitor_move_behaviour: MoveBehaviour,
|
pub cross_monitor_move_behaviour: MoveBehaviour,
|
||||||
pub cross_boundary_behaviour: CrossBoundaryBehaviour,
|
pub cross_boundary_behaviour: CrossBoundaryBehaviour,
|
||||||
pub unmanaged_window_operation_behaviour: OperationBehaviour,
|
pub unmanaged_window_operation_behaviour: OperationBehaviour,
|
||||||
@@ -112,6 +113,7 @@ pub struct State {
|
|||||||
pub is_paused: bool,
|
pub is_paused: bool,
|
||||||
pub resize_delta: i32,
|
pub resize_delta: i32,
|
||||||
pub new_window_behaviour: WindowContainerBehaviour,
|
pub new_window_behaviour: WindowContainerBehaviour,
|
||||||
|
pub float_override: bool,
|
||||||
pub cross_monitor_move_behaviour: MoveBehaviour,
|
pub cross_monitor_move_behaviour: MoveBehaviour,
|
||||||
pub unmanaged_window_operation_behaviour: OperationBehaviour,
|
pub unmanaged_window_operation_behaviour: OperationBehaviour,
|
||||||
pub work_area_offset: Option<Rect>,
|
pub work_area_offset: Option<Rect>,
|
||||||
@@ -215,7 +217,8 @@ impl From<&WindowManager> for State {
|
|||||||
is_paused: wm.is_paused,
|
is_paused: wm.is_paused,
|
||||||
work_area_offset: wm.work_area_offset,
|
work_area_offset: wm.work_area_offset,
|
||||||
resize_delta: wm.resize_delta,
|
resize_delta: wm.resize_delta,
|
||||||
new_window_behaviour: wm.window_container_behaviour,
|
new_window_behaviour: wm.window_management_behaviour.current_behaviour,
|
||||||
|
float_override: wm.window_management_behaviour.float_override,
|
||||||
cross_monitor_move_behaviour: wm.cross_monitor_move_behaviour,
|
cross_monitor_move_behaviour: wm.cross_monitor_move_behaviour,
|
||||||
focus_follows_mouse: wm.focus_follows_mouse,
|
focus_follows_mouse: wm.focus_follows_mouse,
|
||||||
mouse_follows_focus: wm.mouse_follows_focus,
|
mouse_follows_focus: wm.mouse_follows_focus,
|
||||||
@@ -275,7 +278,7 @@ impl WindowManager {
|
|||||||
is_paused: false,
|
is_paused: false,
|
||||||
virtual_desktop_id: current_virtual_desktop(),
|
virtual_desktop_id: current_virtual_desktop(),
|
||||||
work_area_offset: None,
|
work_area_offset: None,
|
||||||
window_container_behaviour: WindowContainerBehaviour::Create,
|
window_management_behaviour: WindowManagementBehaviour::default(),
|
||||||
cross_monitor_move_behaviour: MoveBehaviour::Swap,
|
cross_monitor_move_behaviour: MoveBehaviour::Swap,
|
||||||
cross_boundary_behaviour: CrossBoundaryBehaviour::Workspace,
|
cross_boundary_behaviour: CrossBoundaryBehaviour::Workspace,
|
||||||
unmanaged_window_operation_behaviour: OperationBehaviour::Op,
|
unmanaged_window_operation_behaviour: OperationBehaviour::Op,
|
||||||
@@ -308,22 +311,31 @@ impl WindowManager {
|
|||||||
StaticConfig::reload(pathbuf, self)
|
StaticConfig::reload(pathbuf, self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn window_container_behaviour(
|
pub fn window_management_behaviour(
|
||||||
&self,
|
&self,
|
||||||
monitor_idx: usize,
|
monitor_idx: usize,
|
||||||
workspace_idx: usize,
|
workspace_idx: usize,
|
||||||
) -> WindowContainerBehaviour {
|
) -> WindowManagementBehaviour {
|
||||||
if let Some(monitor) = self.monitors().get(monitor_idx) {
|
if let Some(monitor) = self.monitors().get(monitor_idx) {
|
||||||
if let Some(workspace) = monitor.workspaces().get(workspace_idx) {
|
if let Some(workspace) = monitor.workspaces().get(workspace_idx) {
|
||||||
return if workspace.containers().is_empty() {
|
let current_behaviour = if workspace.containers().is_empty() && matches!(self.window_management_behaviour.current_behaviour, WindowContainerBehaviour::Append) {
|
||||||
|
// You can't append to an empty workspace
|
||||||
WindowContainerBehaviour::Create
|
WindowContainerBehaviour::Create
|
||||||
} else {
|
} else {
|
||||||
self.window_container_behaviour
|
self.window_management_behaviour.current_behaviour
|
||||||
|
};
|
||||||
|
|
||||||
|
return WindowManagementBehaviour {
|
||||||
|
current_behaviour,
|
||||||
|
float_override: self.window_management_behaviour.float_override,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowContainerBehaviour::Create
|
WindowManagementBehaviour {
|
||||||
|
current_behaviour: WindowContainerBehaviour::Create,
|
||||||
|
float_override: self.window_management_behaviour.float_override,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip(self))]
|
#[tracing::instrument(skip(self))]
|
||||||
|
|||||||
Reference in New Issue
Block a user