mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-04-24 01:28:39 +02:00
feat(wm): add native window maximization toggle
Windows that have been maximized do not retain their maximized state across workspaces as workspaces are built on top of sending SW_HIDE and SW_SHOW events which at various points of the event loop end up overriding SW_SHOWMAXIMIZED and SW_SHOWMAXIMIZE. To handle this use case, I have added a new 'komorebic toggle-maximize' command which sends SW_MAXIMIZE for a window and keeps a record of the window in the focused workspace in the same way that monocle windows are tracked. In this way, komorebi can know when switching to a workspace if it has to restore a window to a native maximized state. Some additional edge cases are caught in this commit in showing and hiding workspaces, to also account for floating windows and monocle containers. resolve #12
This commit is contained in:
42
README.md
42
README.md
@@ -133,6 +133,47 @@ You can run `komorebic.exe` to get a full list of the commands that you can use
|
|||||||
keybindings with. You can run `komorebic.exe <COMMAND> --help` to get a full explanation of the arguments required for
|
keybindings with. You can run `komorebic.exe <COMMAND> --help` to get a full explanation of the arguments required for
|
||||||
each command.
|
each command.
|
||||||
|
|
||||||
|
```
|
||||||
|
start Start komorebi.exe as a background process
|
||||||
|
stop Stop the komorebi.exe process and restore all hidden windows
|
||||||
|
state Show a JSON representation of the current window manager state
|
||||||
|
log Tail komorebi.exe's process logs (cancel with Ctrl-C)
|
||||||
|
focus Change focus to the window in the specified direction
|
||||||
|
move Move the focused window in the specified direction
|
||||||
|
stack Stack the focused window in the specified direction
|
||||||
|
resize Resize the focused window in the specified direction
|
||||||
|
unstack Unstack the focused window
|
||||||
|
cycle-stack Cycle the focused stack in the specified cycle direction
|
||||||
|
move-to-monitor Move the focused window to the specified monitor
|
||||||
|
move-to-workspace Move the focused window to the specified workspace
|
||||||
|
focus-monitor Focus the specified monitor
|
||||||
|
focus-workspace Focus the specified workspace on the focused monitor
|
||||||
|
new-workspace Create and append a new workspace on the focused monitor
|
||||||
|
adjust-container-padding Adjust container padding on the focused workspace
|
||||||
|
adjust-workspace-padding Adjust workspace padding on the focused workspace
|
||||||
|
flip-layout Flip the layout on the focused workspace (BSP only)
|
||||||
|
promote Promote the focused window to the top of the tree
|
||||||
|
retile Force the retiling of all managed windows
|
||||||
|
ensure-workspaces Create at least this many workspaces for the specified monitor
|
||||||
|
container-padding Set the container padding for the specified workspace
|
||||||
|
workspace-padding Set the workspace padding for the specified workspace
|
||||||
|
workspace-layout Set the layout 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
|
||||||
|
toggle-pause Toggle the window manager on and off across all monitors
|
||||||
|
toggle-tiling Toggle window tiling on the focused workspace
|
||||||
|
toggle-float Toggle floating mode for the focused window
|
||||||
|
toggle-monocle Toggle monocle mode for the focused container
|
||||||
|
toggle-maximize Toggle native window fullscreen for the focused window
|
||||||
|
restore-windows Restore all hidden windows (debugging command)
|
||||||
|
reload-configuration Reload ~/komorebi.ahk (if it exists)
|
||||||
|
watch-configuration Toggle the automatic reloading of ~/komorebi.ahk (if it exists)
|
||||||
|
float-rule Add a rule to always float the specified application
|
||||||
|
identify-tray-application Identify an application that closes to the system tray
|
||||||
|
focus-follows-mouse Enable or disable focus follows mouse for the operating system
|
||||||
|
help Print this message or the help of the given subcommand(s)
|
||||||
|
```
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- [x] Multi-monitor
|
- [x] Multi-monitor
|
||||||
@@ -158,6 +199,7 @@ each command.
|
|||||||
- [x] Identify 'close/minimize to tray' applications
|
- [x] Identify 'close/minimize to tray' applications
|
||||||
- [x] Toggle floating windows
|
- [x] Toggle floating windows
|
||||||
- [x] Toggle monocle window
|
- [x] Toggle monocle window
|
||||||
|
- [x] Toggle native maximization
|
||||||
- [x] Toggle focus follows mouse
|
- [x] Toggle focus follows mouse
|
||||||
- [x] Toggle automatic tiling
|
- [x] Toggle automatic tiling
|
||||||
- [x] Pause all window management
|
- [x] Pause all window management
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ pub enum SocketMessage {
|
|||||||
Promote,
|
Promote,
|
||||||
ToggleFloat,
|
ToggleFloat,
|
||||||
ToggleMonocle,
|
ToggleMonocle,
|
||||||
|
ToggleMaximize,
|
||||||
// Current Workspace Commands
|
// Current Workspace Commands
|
||||||
AdjustContainerPadding(Sizing, i32),
|
AdjustContainerPadding(Sizing, i32),
|
||||||
AdjustWorkspacePadding(Sizing, i32),
|
AdjustWorkspacePadding(Sizing, i32),
|
||||||
|
|||||||
@@ -129,6 +129,11 @@ return
|
|||||||
Run, komorebic.exe toggle-monocle, , Hide
|
Run, komorebic.exe toggle-monocle, , Hide
|
||||||
return
|
return
|
||||||
|
|
||||||
|
; Toggle native maximize for the focused window, Alt + Shift + =
|
||||||
|
!+=::
|
||||||
|
Run, komorebic.exe toggle-maximize, , Hide
|
||||||
|
return
|
||||||
|
|
||||||
; Flip horizontally, Alt + X
|
; Flip horizontally, Alt + X
|
||||||
!x::
|
!x::
|
||||||
Run, komorebic.exe flip-layout horizontal, , Hide
|
Run, komorebic.exe flip-layout horizontal, , Hide
|
||||||
|
|||||||
@@ -70,14 +70,23 @@ impl Monitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self))]
|
||||||
pub fn move_container_to_workspace(
|
pub fn move_container_to_workspace(
|
||||||
&mut self,
|
&mut self,
|
||||||
target_workspace_idx: usize,
|
target_workspace_idx: usize,
|
||||||
follow: bool,
|
follow: bool,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let container = self
|
let workspace = self
|
||||||
.focused_workspace_mut()
|
.focused_workspace_mut()
|
||||||
.context("there is no workspace")?
|
.context("there is no workspace")?;
|
||||||
|
|
||||||
|
if workspace.maximized_window().is_some() {
|
||||||
|
return Err(eyre::anyhow!(
|
||||||
|
"cannot move native maximized window to another monitor or workspace"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let container = workspace
|
||||||
.remove_focused_container()
|
.remove_focused_container()
|
||||||
.context("there is no container")?;
|
.context("there is no container")?;
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ impl WindowManager {
|
|||||||
}
|
}
|
||||||
SocketMessage::ToggleFloat => self.toggle_float()?,
|
SocketMessage::ToggleFloat => self.toggle_float()?,
|
||||||
SocketMessage::ToggleMonocle => self.toggle_monocle()?,
|
SocketMessage::ToggleMonocle => self.toggle_monocle()?,
|
||||||
|
SocketMessage::ToggleMaximize => self.toggle_maximize()?,
|
||||||
SocketMessage::ContainerPadding(monitor_idx, workspace_idx, size) => {
|
SocketMessage::ContainerPadding(monitor_idx, workspace_idx, size) => {
|
||||||
self.set_container_padding(monitor_idx, workspace_idx, size)?;
|
self.set_container_padding(monitor_idx, workspace_idx, size)?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ impl WindowManager {
|
|||||||
|
|
||||||
let workspace = self.focused_workspace_mut()?;
|
let workspace = self.focused_workspace_mut()?;
|
||||||
|
|
||||||
if workspace.containers().is_empty() || !workspace.contains_window(window.hwnd) {
|
if !workspace.contains_window(window.hwnd) {
|
||||||
workspace.new_container_for_window(*window);
|
workspace.new_container_for_window(*window);
|
||||||
self.update_focused_workspace(false)?;
|
self.update_focused_workspace(false)?;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,6 +130,18 @@ impl Window {
|
|||||||
WindowsApi::restore_window(self.hwnd());
|
WindowsApi::restore_window(self.hwnd());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn maximize(self) {
|
||||||
|
let mut programmatically_hidden_hwnds = HIDDEN_HWNDS.lock().unwrap();
|
||||||
|
if let Some(idx) = programmatically_hidden_hwnds
|
||||||
|
.iter()
|
||||||
|
.position(|&hwnd| hwnd == self.hwnd)
|
||||||
|
{
|
||||||
|
programmatically_hidden_hwnds.remove(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowsApi::maximize_window(self.hwnd());
|
||||||
|
}
|
||||||
|
|
||||||
pub fn focus(self) -> Result<()> {
|
pub fn focus(self) -> Result<()> {
|
||||||
// Attach komorebi thread to Window thread
|
// Attach komorebi thread to Window thread
|
||||||
let (_, window_thread_id) = WindowsApi::window_thread_process_id(self.hwnd());
|
let (_, window_thread_id) = WindowsApi::window_thread_process_id(self.hwnd());
|
||||||
|
|||||||
@@ -196,7 +196,9 @@ impl WindowManager {
|
|||||||
.update_focused_workspace()?;
|
.update_focused_workspace()?;
|
||||||
|
|
||||||
if mouse_follows_focus {
|
if mouse_follows_focus {
|
||||||
if let Ok(window) = self.focused_window_mut() {
|
if let Some(window) = self.focused_workspace()?.maximized_window() {
|
||||||
|
window.focus()?;
|
||||||
|
} else if let Ok(window) = self.focused_window_mut() {
|
||||||
window.focus()?;
|
window.focus()?;
|
||||||
} else {
|
} else {
|
||||||
let desktop_window = Window {
|
let desktop_window = Window {
|
||||||
@@ -310,9 +312,17 @@ impl WindowManager {
|
|||||||
tracing::info!("moving container");
|
tracing::info!("moving container");
|
||||||
|
|
||||||
let monitor = self.focused_monitor_mut().context("there is no monitor")?;
|
let monitor = self.focused_monitor_mut().context("there is no monitor")?;
|
||||||
let container = monitor
|
let workspace = monitor
|
||||||
.focused_workspace_mut()
|
.focused_workspace_mut()
|
||||||
.context("there is no workspace")?
|
.context("there is no workspace")?;
|
||||||
|
|
||||||
|
if workspace.maximized_window().is_some() {
|
||||||
|
return Err(eyre::anyhow!(
|
||||||
|
"cannot move native maximized window to another monitor or workspace"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let container = workspace
|
||||||
.remove_focused_container()
|
.remove_focused_container()
|
||||||
.context("there is no container")?;
|
.context("there is no container")?;
|
||||||
|
|
||||||
@@ -541,6 +551,34 @@ impl WindowManager {
|
|||||||
workspace.reintegrate_monocle_container()
|
workspace.reintegrate_monocle_container()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self))]
|
||||||
|
pub fn toggle_maximize(&mut self) -> Result<()> {
|
||||||
|
let workspace = self.focused_workspace_mut()?;
|
||||||
|
|
||||||
|
match workspace.maximized_window() {
|
||||||
|
None => self.maximize_window()?,
|
||||||
|
Some(_) => self.unmaximize_window()?,
|
||||||
|
}
|
||||||
|
|
||||||
|
self.update_focused_workspace(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self))]
|
||||||
|
pub fn maximize_window(&mut self) -> Result<()> {
|
||||||
|
tracing::info!("maximizing windowj");
|
||||||
|
|
||||||
|
let workspace = self.focused_workspace_mut()?;
|
||||||
|
workspace.new_maximized_window()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tracing::instrument(skip(self))]
|
||||||
|
pub fn unmaximize_window(&mut self) -> Result<()> {
|
||||||
|
tracing::info!("unmaximizing window");
|
||||||
|
|
||||||
|
let workspace = self.focused_workspace_mut()?;
|
||||||
|
workspace.reintegrate_maximized_window()
|
||||||
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip(self))]
|
#[tracing::instrument(skip(self))]
|
||||||
pub fn flip_layout(&mut self, layout_flip: LayoutFlip) -> Result<()> {
|
pub fn flip_layout(&mut self, layout_flip: LayoutFlip) -> Result<()> {
|
||||||
tracing::info!("flipping layout");
|
tracing::info!("flipping layout");
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ use bindings::Windows::Win32::UI::WindowsAndMessaging::SHOW_WINDOW_CMD;
|
|||||||
use bindings::Windows::Win32::UI::WindowsAndMessaging::SPIF_SENDCHANGE;
|
use bindings::Windows::Win32::UI::WindowsAndMessaging::SPIF_SENDCHANGE;
|
||||||
use bindings::Windows::Win32::UI::WindowsAndMessaging::SPI_SETACTIVEWINDOWTRACKING;
|
use bindings::Windows::Win32::UI::WindowsAndMessaging::SPI_SETACTIVEWINDOWTRACKING;
|
||||||
use bindings::Windows::Win32::UI::WindowsAndMessaging::SW_HIDE;
|
use bindings::Windows::Win32::UI::WindowsAndMessaging::SW_HIDE;
|
||||||
|
use bindings::Windows::Win32::UI::WindowsAndMessaging::SW_MAXIMIZE;
|
||||||
use bindings::Windows::Win32::UI::WindowsAndMessaging::SW_RESTORE;
|
use bindings::Windows::Win32::UI::WindowsAndMessaging::SW_RESTORE;
|
||||||
use bindings::Windows::Win32::UI::WindowsAndMessaging::SYSTEM_PARAMETERS_INFO_ACTION;
|
use bindings::Windows::Win32::UI::WindowsAndMessaging::SYSTEM_PARAMETERS_INFO_ACTION;
|
||||||
use bindings::Windows::Win32::UI::WindowsAndMessaging::SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS;
|
use bindings::Windows::Win32::UI::WindowsAndMessaging::SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS;
|
||||||
@@ -259,6 +260,10 @@ impl WindowsApi {
|
|||||||
Self::show_window(hwnd, SW_RESTORE);
|
Self::show_window(hwnd, SW_RESTORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn maximize_window(hwnd: HWND) {
|
||||||
|
Self::show_window(hwnd, SW_MAXIMIZE);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_foreground_window(hwnd: HWND) -> Result<()> {
|
pub fn set_foreground_window(hwnd: HWND) -> Result<()> {
|
||||||
match WindowsResult::from(unsafe { SetForegroundWindow(hwnd) }) {
|
match WindowsResult::from(unsafe { SetForegroundWindow(hwnd) }) {
|
||||||
WindowsResult::Ok(_) => Ok(()),
|
WindowsResult::Ok(_) => Ok(()),
|
||||||
|
|||||||
@@ -28,7 +28,12 @@ pub struct Workspace {
|
|||||||
monocle_container: Option<Container>,
|
monocle_container: Option<Container>,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
#[getset(get_copy = "pub", set = "pub")]
|
#[getset(get_copy = "pub", set = "pub")]
|
||||||
monocle_restore_idx: Option<usize>,
|
monocle_container_restore_idx: Option<usize>,
|
||||||
|
#[getset(get = "pub", get_mut = "pub", set = "pub")]
|
||||||
|
maximized_window: Option<Window>,
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
#[getset(get_copy = "pub", set = "pub")]
|
||||||
|
maximized_window_restore_idx: Option<usize>,
|
||||||
#[getset(get = "pub", get_mut = "pub")]
|
#[getset(get = "pub", get_mut = "pub")]
|
||||||
floating_windows: Vec<Window>,
|
floating_windows: Vec<Window>,
|
||||||
#[getset(get_copy = "pub", set = "pub")]
|
#[getset(get_copy = "pub", set = "pub")]
|
||||||
@@ -57,7 +62,9 @@ impl Default for Workspace {
|
|||||||
name: None,
|
name: None,
|
||||||
containers: Ring::default(),
|
containers: Ring::default(),
|
||||||
monocle_container: None,
|
monocle_container: None,
|
||||||
monocle_restore_idx: None,
|
maximized_window: None,
|
||||||
|
maximized_window_restore_idx: None,
|
||||||
|
monocle_container_restore_idx: None,
|
||||||
floating_windows: Vec::default(),
|
floating_windows: Vec::default(),
|
||||||
layout: Layout::BSP,
|
layout: Layout::BSP,
|
||||||
layout_flip: None,
|
layout_flip: None,
|
||||||
@@ -77,6 +84,20 @@ impl Workspace {
|
|||||||
window.hide();
|
window.hide();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(window) = self.maximized_window() {
|
||||||
|
window.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(container) = self.monocle_container_mut() {
|
||||||
|
for window in container.windows_mut() {
|
||||||
|
window.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for window in self.floating_windows() {
|
||||||
|
window.hide();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn restore(&mut self) -> Result<()> {
|
pub fn restore(&mut self) -> Result<()> {
|
||||||
@@ -87,14 +108,31 @@ impl Workspace {
|
|||||||
window.restore();
|
window.restore();
|
||||||
|
|
||||||
if idx == i {
|
if idx == i {
|
||||||
to_focus = Option::from(window);
|
to_focus = Option::from(*window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(window) = self.maximized_window() {
|
||||||
|
window.maximize();
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(container) = self.monocle_container_mut() {
|
||||||
|
for window in container.windows_mut() {
|
||||||
|
window.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for window in self.floating_windows() {
|
||||||
|
window.restore();
|
||||||
|
}
|
||||||
|
|
||||||
// Do this here to make sure that an error doesn't stop the restoration of other windows
|
// Do this here to make sure that an error doesn't stop the restoration of other windows
|
||||||
|
// Maximised windows should always be drawn at the top of the Z order
|
||||||
if let Some(window) = to_focus {
|
if let Some(window) = to_focus {
|
||||||
window.focus()?;
|
if self.maximized_window().is_none() {
|
||||||
|
window.focus()?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -110,7 +148,9 @@ impl Workspace {
|
|||||||
if let Some(container) = self.monocle_container_mut() {
|
if let Some(container) = self.monocle_container_mut() {
|
||||||
if let Some(window) = container.focused_window_mut() {
|
if let Some(window) = container.focused_window_mut() {
|
||||||
window.set_position(&adjusted_work_area, true)?;
|
window.set_position(&adjusted_work_area, true)?;
|
||||||
}
|
};
|
||||||
|
} else if let Some(window) = self.maximized_window_mut() {
|
||||||
|
window.maximize();
|
||||||
} else if !self.containers().is_empty() {
|
} else if !self.containers().is_empty() {
|
||||||
let layouts = self.layout().calculate(
|
let layouts = self.layout().calculate(
|
||||||
&adjusted_work_area,
|
&adjusted_work_area,
|
||||||
@@ -223,8 +263,26 @@ impl Workspace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn contains_window(&self, hwnd: isize) -> bool {
|
pub fn contains_window(&self, hwnd: isize) -> bool {
|
||||||
for x in self.containers() {
|
for container in self.containers() {
|
||||||
if x.contains_window(hwnd) {
|
if container.contains_window(hwnd) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(window) = self.maximized_window() {
|
||||||
|
if hwnd == window.hwnd {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(container) = self.monocle_container() {
|
||||||
|
if container.contains_window(hwnd) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for window in self.floating_windows() {
|
||||||
|
if hwnd == window.hwnd {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -497,7 +555,7 @@ impl Workspace {
|
|||||||
// it had before
|
// it had before
|
||||||
|
|
||||||
self.set_monocle_container(Option::from(container));
|
self.set_monocle_container(Option::from(container));
|
||||||
self.set_monocle_restore_idx(Option::from(focused_idx));
|
self.set_monocle_container_restore_idx(Option::from(focused_idx));
|
||||||
|
|
||||||
if focused_idx != 0 {
|
if focused_idx != 0 {
|
||||||
self.focus_container(focused_idx - 1);
|
self.focus_container(focused_idx - 1);
|
||||||
@@ -513,7 +571,7 @@ impl Workspace {
|
|||||||
|
|
||||||
pub fn reintegrate_monocle_container(&mut self) -> Result<()> {
|
pub fn reintegrate_monocle_container(&mut self) -> Result<()> {
|
||||||
let restore_idx = self
|
let restore_idx = self
|
||||||
.monocle_restore_idx()
|
.monocle_container_restore_idx()
|
||||||
.context("there is no monocle restore index")?;
|
.context("there is no monocle restore index")?;
|
||||||
|
|
||||||
let container = self
|
let container = self
|
||||||
@@ -534,6 +592,71 @@ impl Workspace {
|
|||||||
.load_focused_window();
|
.load_focused_window();
|
||||||
|
|
||||||
self.set_monocle_container(None);
|
self.set_monocle_container(None);
|
||||||
|
self.set_monocle_container_restore_idx(None);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_maximized_window(&mut self) -> Result<()> {
|
||||||
|
let focused_idx = self.focused_container_idx();
|
||||||
|
|
||||||
|
let container = self
|
||||||
|
.focused_container_mut()
|
||||||
|
.context("there is no container")?;
|
||||||
|
|
||||||
|
let window = container
|
||||||
|
.remove_focused_window()
|
||||||
|
.context("there is no window")?;
|
||||||
|
|
||||||
|
if container.windows().is_empty() {
|
||||||
|
self.containers_mut().remove(focused_idx);
|
||||||
|
self.resize_dimensions_mut().remove(focused_idx);
|
||||||
|
} else {
|
||||||
|
container.load_focused_window();
|
||||||
|
}
|
||||||
|
|
||||||
|
self.set_maximized_window(Option::from(window));
|
||||||
|
self.set_maximized_window_restore_idx(Option::from(focused_idx));
|
||||||
|
|
||||||
|
if let Some(window) = self.maximized_window() {
|
||||||
|
window.maximize();
|
||||||
|
}
|
||||||
|
|
||||||
|
if focused_idx != 0 {
|
||||||
|
self.focus_container(focused_idx - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reintegrate_maximized_window(&mut self) -> Result<()> {
|
||||||
|
let restore_idx = self
|
||||||
|
.maximized_window_restore_idx()
|
||||||
|
.context("there is no monocle restore index")?;
|
||||||
|
|
||||||
|
let window = self
|
||||||
|
.maximized_window()
|
||||||
|
.as_ref()
|
||||||
|
.context("there is no monocle container")?;
|
||||||
|
|
||||||
|
let window = *window;
|
||||||
|
if !self.containers().is_empty() && restore_idx > self.containers().len() - 1 {
|
||||||
|
self.containers_mut()
|
||||||
|
.resize(restore_idx, Container::default());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut container = Container::default();
|
||||||
|
container.windows_mut().push_back(window);
|
||||||
|
self.containers_mut().insert(restore_idx, container);
|
||||||
|
|
||||||
|
self.focus_container(restore_idx);
|
||||||
|
|
||||||
|
self.focused_container_mut()
|
||||||
|
.context("there is no container")?
|
||||||
|
.load_focused_window();
|
||||||
|
|
||||||
|
self.set_maximized_window(None);
|
||||||
|
self.set_maximized_window_restore_idx(None);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -250,6 +250,8 @@ enum SubCommand {
|
|||||||
ToggleFloat,
|
ToggleFloat,
|
||||||
/// Toggle monocle mode for the focused container
|
/// Toggle monocle mode for the focused container
|
||||||
ToggleMonocle,
|
ToggleMonocle,
|
||||||
|
/// Toggle native maximization for the focused window
|
||||||
|
ToggleMaximize,
|
||||||
/// Restore all hidden windows (debugging command)
|
/// Restore all hidden windows (debugging command)
|
||||||
RestoreWindows,
|
RestoreWindows,
|
||||||
/// Reload ~/komorebi.ahk (if it exists)
|
/// Reload ~/komorebi.ahk (if it exists)
|
||||||
@@ -341,6 +343,9 @@ fn main() -> Result<()> {
|
|||||||
SubCommand::ToggleMonocle => {
|
SubCommand::ToggleMonocle => {
|
||||||
send_message(&*SocketMessage::ToggleMonocle.as_bytes()?)?;
|
send_message(&*SocketMessage::ToggleMonocle.as_bytes()?)?;
|
||||||
}
|
}
|
||||||
|
SubCommand::ToggleMaximize => {
|
||||||
|
send_message(&*SocketMessage::ToggleMaximize.as_bytes()?)?;
|
||||||
|
}
|
||||||
SubCommand::WorkspaceLayout(arg) => {
|
SubCommand::WorkspaceLayout(arg) => {
|
||||||
send_message(
|
send_message(
|
||||||
&*SocketMessage::WorkspaceLayout(arg.monitor, arg.workspace, arg.value)
|
&*SocketMessage::WorkspaceLayout(arg.monitor, arg.workspace, arg.value)
|
||||||
|
|||||||
Reference in New Issue
Block a user