fix(wm): improve maximized window handling

This commit addresses a few bugs with regards to maximized window
handling.

- Correctly restoring and focusing when switching to a workspace
  containing a window previously maximized with the toggle-maximize
  command

- Unmaximizing a window during the initial window scan when the wm
  initializes so that windows that are maximized before running komorebi
  will no longer have the ugly white bar at the top

- When updating workspace layouts, windows that have been maximized
  without using the komorebic toggle-maximize command will be
  unmaximized to prevent the wm state drifting out of sync with what is
  happening on the screen
This commit is contained in:
LGUG2Z
2024-02-24 19:19:44 -08:00
parent dee5842c9c
commit 8642ac0946
5 changed files with 35 additions and 0 deletions

View File

@@ -179,6 +179,14 @@ impl Window {
WindowsApi::position_window(self.hwnd(), &rect, top)
}
pub fn is_maximized(self) -> bool {
WindowsApi::is_zoomed(self.hwnd())
}
pub fn is_miminized(self) -> bool {
WindowsApi::is_iconic(self.hwnd())
}
pub fn hide(self) {
let mut programmatically_hidden_hwnds = HIDDEN_HWNDS.lock();
if !programmatically_hidden_hwnds.contains(&self.hwnd) {

View File

@@ -880,6 +880,15 @@ impl WindowManager {
}
};
// This is to correctly restore and focus when switching to a workspace which
// contains a managed maximized window
if !follow_focus {
if let Some(window) = self.focused_workspace()?.maximized_window() {
window.restore();
window.focus(self.mouse_follows_focus)?;
}
}
Ok(())
}

View File

@@ -82,6 +82,7 @@ use windows::Win32::UI::WindowsAndMessaging::GetWindowThreadProcessId;
use windows::Win32::UI::WindowsAndMessaging::IsIconic;
use windows::Win32::UI::WindowsAndMessaging::IsWindow;
use windows::Win32::UI::WindowsAndMessaging::IsWindowVisible;
use windows::Win32::UI::WindowsAndMessaging::IsZoomed;
use windows::Win32::UI::WindowsAndMessaging::PostMessageW;
use windows::Win32::UI::WindowsAndMessaging::RealGetWindowClassW;
use windows::Win32::UI::WindowsAndMessaging::RegisterClassW;
@@ -677,6 +678,10 @@ impl WindowsApi {
unsafe { IsIconic(hwnd) }.into()
}
pub fn is_zoomed(hwnd: HWND) -> bool {
unsafe { IsZoomed(hwnd) }.into()
}
pub fn monitor_info_w(hmonitor: HMONITOR) -> Result<MONITORINFOEXW> {
let mut ex_info = MONITORINFOEXW::default();
ex_info.monitorInfo.cbSize = u32::try_from(std::mem::size_of::<MONITORINFOEXW>())?;

View File

@@ -146,12 +146,17 @@ pub extern "system" fn enum_window(hwnd: HWND, lparam: LPARAM) -> BOOL {
let is_visible = WindowsApi::is_window_visible(hwnd);
let is_window = WindowsApi::is_window(hwnd);
let is_minimized = WindowsApi::is_iconic(hwnd);
let is_maximized = WindowsApi::is_zoomed(hwnd);
if is_visible && is_window && !is_minimized {
let window = Window { hwnd: hwnd.0 };
if let Ok(should_manage) = window.should_manage(None) {
if should_manage {
if is_maximized {
WindowsApi::restore_window(hwnd);
}
let mut container = Container::default();
container.windows_mut().push_back(window);
containers.push_back(container);

View File

@@ -247,6 +247,8 @@ impl Workspace {
}
}
let managed_maximized_window = self.maximized_window().is_some();
if *self.tile() {
if let Some(container) = self.monocle_container_mut() {
if let Some(window) = container.focused_window_mut() {
@@ -280,6 +282,12 @@ impl Workspace {
window.add_title_bar()?;
}
// If a window has been unmaximized via toggle-maximize, this block
// will make sure that it is unmaximized via restore_window
if window.is_maximized() && !managed_maximized_window {
WindowsApi::restore_window(window.hwnd());
}
window.set_position(layout, invisible_borders, false)?;
}
}