feat(wm): add option to either minimize or hide

This commit adds a command to let the user decide if they want windows
to be hidden with SW_HIDE or minimized with SW_MINIMIZE when workspaces
are changed or window container stacks are cycled.

After a modest amount of local testing, SW_MINIMIZE does not appear to
introduce any regressions, and given that alt-tabbing is a common
workflow on Windows, it makes sense to have minimizing be the default
setting to ease the onboarding experience for new users.

resolve #72
This commit is contained in:
LGUG2Z
2021-11-18 16:59:51 -08:00
parent 0519ebddbf
commit f9785bef55
10 changed files with 127 additions and 72 deletions

View File

@@ -328,7 +328,7 @@ workspace-layout Set the 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-name Set the workspace name for the specified workspace
toggle-new-window-behaviour Toggle the behaviour for new windows (stacking or dynamic tiling)
toggle-window-container-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-float Toggle floating mode for the focused window
@@ -339,6 +339,7 @@ manage Force komorebi to manage the focused window
unmanage Unmanage a window that was forcibly managed
reload-configuration Reload ~/komorebi.ahk (if it exists)
watch-configuration Enable or disable watching of ~/komorebi.ahk (if it exists)
window-hiding-behaviour Set the window behaviour when switching workspaces / cycling stacks
float-rule Add a rule to always float the specified application
manage-rule Add a rule to always manage the specified application
workspace-rule Add a rule to associate an application with a workspace

View File

@@ -52,6 +52,7 @@ pub enum SocketMessage {
ToggleMonocle,
ToggleMaximize,
ToggleWindowContainerBehaviour,
WindowHidingBehaviour(HidingBehaviour),
// Current Workspace Commands
ManageFocusedWindow,
UnmanageFocusedWindow,
@@ -147,6 +148,13 @@ pub enum WindowContainerBehaviour {
Append,
}
#[derive(Clone, Debug, Serialize, Deserialize, Display, EnumString, ArgEnum)]
#[strum(serialize_all = "snake_case")]
pub enum HidingBehaviour {
Hide,
Minimize,
}
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Display, EnumString, ArgEnum)]
#[strum(serialize_all = "snake_case")]
pub enum Sizing {

View File

@@ -1,6 +1,9 @@
#SingleInstance Force
#Include %A_ScriptDir%\komorebic.lib.ahk
; Default to minimizing windows when switching workspaces
WindowHidingBehaviour("minimize")
; Enable hot reloading of changes to this file
WatchConfiguration("enable")

View File

@@ -29,6 +29,7 @@ use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::EnvFilter;
use which::which;
use komorebi_core::HidingBehaviour;
use komorebi_core::SocketMessage;
use crate::process_command::listen_for_commands;
@@ -92,6 +93,8 @@ lazy_static! {
]));
static ref SUBSCRIPTION_PIPES: Arc<Mutex<HashMap<String, File>>> =
Arc::new(Mutex::new(HashMap::new()));
static ref HIDING_BEHAVIOUR: Arc<Mutex<HidingBehaviour>> =
Arc::new(Mutex::new(HidingBehaviour::Minimize));
}
pub static CUSTOM_FFM: AtomicBool = AtomicBool::new(false);

View File

@@ -34,6 +34,7 @@ use crate::NotificationEvent;
use crate::BORDER_OVERFLOW_IDENTIFIERS;
use crate::CUSTOM_FFM;
use crate::FLOAT_IDENTIFIERS;
use crate::HIDING_BEHAVIOUR;
use crate::MANAGE_IDENTIFIERS;
use crate::SUBSCRIPTION_PIPES;
use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS;
@@ -559,6 +560,10 @@ impl WindowManager {
}
}
}
SocketMessage::WindowHidingBehaviour(behaviour) => {
let mut hiding_behaviour = HIDING_BEHAVIOUR.lock();
*hiding_behaviour = behaviour;
}
};
tracing::info!("processed");

View File

@@ -103,13 +103,25 @@ impl WindowManager {
window.raise()?;
self.has_pending_raise_op = false;
}
WindowManagerEvent::Minimize(_, window)
| WindowManagerEvent::Destroy(_, window)
| WindowManagerEvent::Unmanage(window) => {
WindowManagerEvent::Destroy(_, window) | WindowManagerEvent::Unmanage(window) => {
self.focused_workspace_mut()?.remove_window(window.hwnd)?;
self.update_focused_workspace(false)?;
}
WindowManagerEvent::Minimize(_, window) => {
let mut hide = false;
{
let programmatically_hidden_hwnds = HIDDEN_HWNDS.lock();
if !programmatically_hidden_hwnds.contains(&window.hwnd) {
hide = true;
}
}
if hide {
self.focused_workspace_mut()?.remove_window(window.hwnd)?;
self.update_focused_workspace(false)?;
}
}
WindowManagerEvent::Hide(_, window) => {
let mut hide = false;
// Some major applications unfortunately send the HIDE signal when they are being

View File

@@ -10,6 +10,7 @@ use serde::Serialize;
use serde::Serializer;
use windows::Win32::Foundation::HWND;
use komorebi_core::HidingBehaviour;
use komorebi_core::Rect;
use crate::styles::ExtendedWindowStyle;
@@ -19,6 +20,7 @@ use crate::windows_api::WindowsApi;
use crate::BORDER_OVERFLOW_IDENTIFIERS;
use crate::FLOAT_IDENTIFIERS;
use crate::HIDDEN_HWNDS;
use crate::HIDING_BEHAVIOUR;
use crate::LAYERED_EXE_WHITELIST;
use crate::MANAGE_IDENTIFIERS;
use crate::WSL2_UI_PROCESSES;
@@ -139,7 +141,11 @@ impl Window {
programmatically_hidden_hwnds.push(self.hwnd);
}
WindowsApi::hide_window(self.hwnd());
let hiding_behaviour = HIDING_BEHAVIOUR.lock();
match *hiding_behaviour {
HidingBehaviour::Hide => WindowsApi::hide_window(self.hwnd()),
HidingBehaviour::Minimize => WindowsApi::minimize_window(self.hwnd()),
}
}
pub fn restore(self) {

View File

@@ -74,6 +74,7 @@ use windows::Win32::UI::WindowsAndMessaging::SPI_GETACTIVEWINDOWTRACKING;
use windows::Win32::UI::WindowsAndMessaging::SPI_SETACTIVEWINDOWTRACKING;
use windows::Win32::UI::WindowsAndMessaging::SW_HIDE;
use windows::Win32::UI::WindowsAndMessaging::SW_MAXIMIZE;
use windows::Win32::UI::WindowsAndMessaging::SW_MINIMIZE;
use windows::Win32::UI::WindowsAndMessaging::SW_RESTORE;
use windows::Win32::UI::WindowsAndMessaging::SYSTEM_PARAMETERS_INFO_ACTION;
use windows::Win32::UI::WindowsAndMessaging::SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS;
@@ -279,6 +280,10 @@ impl WindowsApi {
unsafe { ShowWindow(hwnd, command) };
}
pub fn minimize_window(hwnd: HWND) {
Self::show_window(hwnd, SW_MINIMIZE);
}
pub fn hide_window(hwnd: HWND) {
Self::show_window(hwnd, SW_HIDE);
}

View File

@@ -228,6 +228,10 @@ WatchConfiguration(boolean_state) {
Run, komorebic.exe watch-configuration %boolean_state%, , Hide
}
WindowHidingBehaviour(hiding_behaviour) {
Run, komorebic.exe window-hiding-behaviour %hiding_behaviour%, , Hide
}
FloatRule(identifier, id) {
Run, komorebic.exe float-rule %identifier% %id%, , Hide
}

View File

@@ -32,6 +32,7 @@ use komorebi_core::Axis;
use komorebi_core::CycleDirection;
use komorebi_core::DefaultLayout;
use komorebi_core::FocusFollowsMouseImplementation;
use komorebi_core::HidingBehaviour;
use komorebi_core::OperationDirection;
use komorebi_core::Rect;
use komorebi_core::Sizing;
@@ -90,6 +91,7 @@ gen_enum_subcommand_args! {
WatchConfiguration: BooleanState,
MouseFollowsFocus: BooleanState,
Query: StateQuery,
WindowHidingBehaviour: HidingBehaviour,
}
macro_rules! gen_target_subcommand_args {
@@ -506,6 +508,9 @@ enum SubCommand {
/// Enable or disable watching of ~/komorebi.ahk (if it exists)
#[clap(setting = AppSettings::ArgRequiredElseHelp)]
WatchConfiguration(WatchConfiguration),
/// Set the window behaviour when switching workspaces / cycling stacks
#[clap(setting = AppSettings::ArgRequiredElseHelp)]
WindowHidingBehaviour(WindowHidingBehaviour),
/// Add a rule to always float the specified application
#[clap(setting = AppSettings::ArgRequiredElseHelp)]
FloatRule(FloatRule),
@@ -963,6 +968,9 @@ fn main() -> Result<()> {
SubCommand::ToggleWindowContainerBehaviour => {
send_message(&*SocketMessage::ToggleWindowContainerBehaviour.as_bytes()?)?;
}
SubCommand::WindowHidingBehaviour(arg) => {
send_message(&*SocketMessage::WindowHidingBehaviour(arg.hiding_behaviour).as_bytes()?)?;
}
}
Ok(())