mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-07-11 15:42:43 +02:00
feat(wm): add cmd to toggle new window behaviour
This commit introduces a new command, toggle-new-window-behaviour, which can be used to toggle how new windows on the screen will be handled. The default setting is to add a new window in a dedicated container, but when toggled, new windows will be stacked on top of the currently focused window container. This can be useful if you only want to use a certain number of columns, and when you have enough windows on the screen for them, you can toggle the new window behaviour to start appending to the existing column stacks. This commit also fixes a bug where stacked windows being closed did cause the next window underneath in the stack to be shown. re #72
This commit is contained in:
@@ -328,7 +328,8 @@ workspace-layout Set the layout for the specified workspace
|
|||||||
workspace-custom-layout Set a custom layout for the specified workspace
|
workspace-custom-layout Set a custom layout for the specified workspace
|
||||||
workspace-tiling Enable or disable window tiling for the specified workspace
|
workspace-tiling Enable or disable window tiling for the specified workspace
|
||||||
workspace-name Set the workspace name for the specified workspace
|
workspace-name Set the workspace name for the specified workspace
|
||||||
toggle-pause Toggle the window manager on and off across all monitors
|
toggle-new-window-behaviour Toggle the behaviour for new windows (stacking or dynamic tiling)
|
||||||
|
toggle-pause Toggle window tiling on the focused workspace
|
||||||
toggle-tiling Toggle window tiling on the focused workspace
|
toggle-tiling Toggle window tiling on the focused workspace
|
||||||
toggle-float Toggle floating mode for the focused window
|
toggle-float Toggle floating mode for the focused window
|
||||||
toggle-monocle Toggle monocle mode for the focused container
|
toggle-monocle Toggle monocle mode for the focused container
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ pub enum SocketMessage {
|
|||||||
ToggleFloat,
|
ToggleFloat,
|
||||||
ToggleMonocle,
|
ToggleMonocle,
|
||||||
ToggleMaximize,
|
ToggleMaximize,
|
||||||
|
ToggleNewWindowBehaviour,
|
||||||
// Current Workspace Commands
|
// Current Workspace Commands
|
||||||
ManageFocusedWindow,
|
ManageFocusedWindow,
|
||||||
UnmanageFocusedWindow,
|
UnmanageFocusedWindow,
|
||||||
@@ -139,6 +140,13 @@ pub enum FocusFollowsMouseImplementation {
|
|||||||
Windows,
|
Windows,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ArgEnum)]
|
||||||
|
#[strum(serialize_all = "snake_case")]
|
||||||
|
pub enum NewWindowBehaviour {
|
||||||
|
CreateNewContainer,
|
||||||
|
AppendToFocusedContainer,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ArgEnum)]
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ArgEnum)]
|
||||||
#[strum(serialize_all = "snake_case")]
|
#[strum(serialize_all = "snake_case")]
|
||||||
pub enum Sizing {
|
pub enum Sizing {
|
||||||
|
|||||||
@@ -78,18 +78,18 @@ impl Container {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_window_by_idx(&mut self, idx: usize) -> Option<Window> {
|
pub fn remove_window_by_idx(&mut self, idx: usize) -> Option<Window> {
|
||||||
self.windows_mut().remove(idx)
|
let window = self.windows_mut().remove(idx);
|
||||||
|
|
||||||
|
if idx != 0 {
|
||||||
|
self.focus_window(idx - 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
window
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_focused_window(&mut self) -> Option<Window> {
|
pub fn remove_focused_window(&mut self) -> Option<Window> {
|
||||||
let focused_idx = self.focused_window_idx();
|
let focused_idx = self.focused_window_idx();
|
||||||
let window = self.remove_window_by_idx(focused_idx);
|
self.remove_window_by_idx(focused_idx)
|
||||||
|
|
||||||
if focused_idx != 0 {
|
|
||||||
self.focus_window(focused_idx - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
window
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_window(&mut self, window: Window) {
|
pub fn add_window(&mut self, window: Window) {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ use uds_windows::UnixStream;
|
|||||||
use komorebi_core::Axis;
|
use komorebi_core::Axis;
|
||||||
use komorebi_core::FocusFollowsMouseImplementation;
|
use komorebi_core::FocusFollowsMouseImplementation;
|
||||||
use komorebi_core::Layout;
|
use komorebi_core::Layout;
|
||||||
|
use komorebi_core::NewWindowBehaviour;
|
||||||
use komorebi_core::OperationDirection;
|
use komorebi_core::OperationDirection;
|
||||||
use komorebi_core::Rect;
|
use komorebi_core::Rect;
|
||||||
use komorebi_core::Sizing;
|
use komorebi_core::Sizing;
|
||||||
@@ -547,6 +548,14 @@ impl WindowManager {
|
|||||||
SocketMessage::ResizeDelta(delta) => {
|
SocketMessage::ResizeDelta(delta) => {
|
||||||
self.resize_delta = delta;
|
self.resize_delta = delta;
|
||||||
}
|
}
|
||||||
|
SocketMessage::ToggleNewWindowBehaviour => match self.new_window_behaviour {
|
||||||
|
NewWindowBehaviour::CreateNewContainer => {
|
||||||
|
self.new_window_behaviour = NewWindowBehaviour::AppendToFocusedContainer;
|
||||||
|
}
|
||||||
|
NewWindowBehaviour::AppendToFocusedContainer => {
|
||||||
|
self.new_window_behaviour = NewWindowBehaviour::CreateNewContainer;
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
tracing::info!("processed");
|
tracing::info!("processed");
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use color_eyre::Result;
|
|||||||
use crossbeam_channel::select;
|
use crossbeam_channel::select;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
|
|
||||||
|
use komorebi_core::NewWindowBehaviour;
|
||||||
use komorebi_core::OperationDirection;
|
use komorebi_core::OperationDirection;
|
||||||
use komorebi_core::Rect;
|
use komorebi_core::Rect;
|
||||||
use komorebi_core::Sizing;
|
use komorebi_core::Sizing;
|
||||||
@@ -201,12 +202,24 @@ impl WindowManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let behaviour = self.new_window_behaviour;
|
||||||
let workspace = self.focused_workspace_mut()?;
|
let workspace = self.focused_workspace_mut()?;
|
||||||
|
|
||||||
if !workspace.contains_window(window.hwnd) {
|
if !workspace.contains_window(window.hwnd) {
|
||||||
|
match behaviour {
|
||||||
|
NewWindowBehaviour::CreateNewContainer => {
|
||||||
workspace.new_container_for_window(*window);
|
workspace.new_container_for_window(*window);
|
||||||
self.update_focused_workspace(false)?;
|
self.update_focused_workspace(false)?;
|
||||||
}
|
}
|
||||||
|
NewWindowBehaviour::AppendToFocusedContainer => {
|
||||||
|
workspace
|
||||||
|
.focused_container_mut()
|
||||||
|
.ok_or_else(|| anyhow!("there is no focused container"))?
|
||||||
|
.add_window(*window);
|
||||||
|
self.update_focused_workspace(true)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
WindowManagerEvent::MoveResizeStart(_, _) => {
|
WindowManagerEvent::MoveResizeStart(_, _) => {
|
||||||
let monitor_idx = self.focused_monitor_idx();
|
let monitor_idx = self.focused_monitor_idx();
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ use komorebi_core::CycleDirection;
|
|||||||
use komorebi_core::DefaultLayout;
|
use komorebi_core::DefaultLayout;
|
||||||
use komorebi_core::FocusFollowsMouseImplementation;
|
use komorebi_core::FocusFollowsMouseImplementation;
|
||||||
use komorebi_core::Layout;
|
use komorebi_core::Layout;
|
||||||
|
use komorebi_core::NewWindowBehaviour;
|
||||||
use komorebi_core::OperationDirection;
|
use komorebi_core::OperationDirection;
|
||||||
use komorebi_core::Rect;
|
use komorebi_core::Rect;
|
||||||
use komorebi_core::Sizing;
|
use komorebi_core::Sizing;
|
||||||
@@ -50,6 +51,7 @@ pub struct WindowManager {
|
|||||||
pub invisible_borders: Rect,
|
pub invisible_borders: Rect,
|
||||||
pub work_area_offset: Option<Rect>,
|
pub work_area_offset: Option<Rect>,
|
||||||
pub resize_delta: i32,
|
pub resize_delta: i32,
|
||||||
|
pub new_window_behaviour: NewWindowBehaviour,
|
||||||
pub focus_follows_mouse: Option<FocusFollowsMouseImplementation>,
|
pub focus_follows_mouse: Option<FocusFollowsMouseImplementation>,
|
||||||
pub mouse_follows_focus: bool,
|
pub mouse_follows_focus: bool,
|
||||||
pub hotwatch: Hotwatch,
|
pub hotwatch: Hotwatch,
|
||||||
@@ -64,6 +66,7 @@ pub struct State {
|
|||||||
pub is_paused: bool,
|
pub is_paused: bool,
|
||||||
pub invisible_borders: Rect,
|
pub invisible_borders: Rect,
|
||||||
pub resize_delta: i32,
|
pub resize_delta: i32,
|
||||||
|
pub new_window_behaviour: NewWindowBehaviour,
|
||||||
pub work_area_offset: Option<Rect>,
|
pub work_area_offset: Option<Rect>,
|
||||||
pub focus_follows_mouse: Option<FocusFollowsMouseImplementation>,
|
pub focus_follows_mouse: Option<FocusFollowsMouseImplementation>,
|
||||||
pub mouse_follows_focus: bool,
|
pub mouse_follows_focus: bool,
|
||||||
@@ -83,6 +86,7 @@ impl From<&WindowManager> for State {
|
|||||||
invisible_borders: wm.invisible_borders,
|
invisible_borders: wm.invisible_borders,
|
||||||
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.new_window_behaviour,
|
||||||
focus_follows_mouse: wm.focus_follows_mouse.clone(),
|
focus_follows_mouse: wm.focus_follows_mouse.clone(),
|
||||||
mouse_follows_focus: wm.mouse_follows_focus,
|
mouse_follows_focus: wm.mouse_follows_focus,
|
||||||
has_pending_raise_op: wm.has_pending_raise_op,
|
has_pending_raise_op: wm.has_pending_raise_op,
|
||||||
@@ -156,6 +160,7 @@ impl WindowManager {
|
|||||||
bottom: 7,
|
bottom: 7,
|
||||||
},
|
},
|
||||||
work_area_offset: None,
|
work_area_offset: None,
|
||||||
|
new_window_behaviour: NewWindowBehaviour::CreateNewContainer,
|
||||||
resize_delta: 50,
|
resize_delta: 50,
|
||||||
focus_follows_mouse: None,
|
focus_follows_mouse: None,
|
||||||
mouse_follows_focus: true,
|
mouse_follows_focus: true,
|
||||||
|
|||||||
@@ -456,9 +456,11 @@ impl Workspace {
|
|||||||
if self.resize_dimensions().get(container_idx).is_some() {
|
if self.resize_dimensions().get(container_idx).is_some() {
|
||||||
self.resize_dimensions_mut().remove(container_idx);
|
self.resize_dimensions_mut().remove(container_idx);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
self.focus_previous_container();
|
self.focus_previous_container();
|
||||||
|
} else {
|
||||||
|
container.load_focused_window();
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,6 +184,10 @@ WorkspaceName(monitor, workspace, value) {
|
|||||||
Run, komorebic.exe workspace-name %monitor% %workspace% %value%, , Hide
|
Run, komorebic.exe workspace-name %monitor% %workspace% %value%, , Hide
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ToggleNewWindowBehaviour() {
|
||||||
|
Run, komorebic.exe toggle-new-window-behaviour, , Hide
|
||||||
|
}
|
||||||
|
|
||||||
TogglePause() {
|
TogglePause() {
|
||||||
Run, komorebic.exe toggle-pause, , Hide
|
Run, komorebic.exe toggle-pause, , Hide
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -483,7 +483,9 @@ enum SubCommand {
|
|||||||
/// Set the workspace name for the specified workspace
|
/// Set the workspace name for the specified workspace
|
||||||
#[clap(setting = AppSettings::ArgRequiredElseHelp)]
|
#[clap(setting = AppSettings::ArgRequiredElseHelp)]
|
||||||
WorkspaceName(WorkspaceName),
|
WorkspaceName(WorkspaceName),
|
||||||
/// Toggle the window manager on and off across all monitors
|
/// Toggle the behaviour for new windows (stacking or dynamic tiling)
|
||||||
|
ToggleNewWindowBehaviour,
|
||||||
|
/// Toggle window tiling on the focused workspace
|
||||||
TogglePause,
|
TogglePause,
|
||||||
/// Toggle window tiling on the focused workspace
|
/// Toggle window tiling on the focused workspace
|
||||||
ToggleTiling,
|
ToggleTiling,
|
||||||
@@ -958,6 +960,9 @@ fn main() -> Result<()> {
|
|||||||
SubCommand::ResizeDelta(arg) => {
|
SubCommand::ResizeDelta(arg) => {
|
||||||
send_message(&*SocketMessage::ResizeDelta(arg.pixels).as_bytes()?)?;
|
send_message(&*SocketMessage::ResizeDelta(arg.pixels).as_bytes()?)?;
|
||||||
}
|
}
|
||||||
|
SubCommand::ToggleNewWindowBehaviour => {
|
||||||
|
send_message(&*SocketMessage::ToggleNewWindowBehaviour.as_bytes()?)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
Reference in New Issue
Block a user