mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-03-22 17:39:20 +01:00
feat(wm): add configuration option for async window handling
Add configuration option for enabling/disabling the asynchronous window handling. The feature might cause unforeseen issues, so by default it is off. It can be enabled with setting the option async_window_handling to true.
This commit is contained in:
@@ -240,6 +240,8 @@ pub static REMOVE_TITLEBARS: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
pub static SLOW_APPLICATION_COMPENSATION_TIME: AtomicU64 = AtomicU64::new(20);
|
||||
|
||||
pub static ASYNC_WINDOW_HANDLING_ENABLED: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
shadow_rs::shadow!(build);
|
||||
|
||||
#[must_use]
|
||||
|
||||
@@ -63,6 +63,7 @@ use crate::FloatingLayerBehaviour;
|
||||
use crate::Placement;
|
||||
use crate::PredefinedAspectRatio;
|
||||
use crate::ResolvedPathBuf;
|
||||
use crate::ASYNC_WINDOW_HANDLING_ENABLED;
|
||||
use crate::DATA_DIR;
|
||||
use crate::DEFAULT_CONTAINER_PADDING;
|
||||
use crate::DEFAULT_WORKSPACE_PADDING;
|
||||
@@ -560,6 +561,9 @@ pub struct StaticConfig {
|
||||
/// Aspect ratio to resize with when toggling floating mode for a window
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub floating_window_aspect_ratio: Option<AspectRatio>,
|
||||
/// Use asynchronous window handling to avoid blocking the main thread when a window is not responding (default: false)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub async_window_handling: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
@@ -921,6 +925,7 @@ impl From<&WindowManager> for StaticConfig {
|
||||
bar_configurations: None,
|
||||
remove_titlebar_applications: Option::from(NO_TITLEBAR.lock().clone()),
|
||||
floating_window_aspect_ratio: Option::from(*FLOATING_WINDOW_TOGGLE_ASPECT_RATIO.lock()),
|
||||
async_window_handling: Option::from(false),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1208,6 +1213,10 @@ impl StaticConfig {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(async_enabled) = self.async_window_handling {
|
||||
ASYNC_WINDOW_HANDLING_ENABLED.store(async_enabled, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ use std::collections::VecDeque;
|
||||
use std::convert::TryFrom;
|
||||
use std::mem::size_of;
|
||||
use std::path::Path;
|
||||
use std::sync::atomic::Ordering;
|
||||
use windows::core::Result as WindowsCrateResult;
|
||||
use windows::core::PCWSTR;
|
||||
use windows::core::PWSTR;
|
||||
@@ -105,6 +106,7 @@ use windows::Win32::UI::WindowsAndMessaging::SetForegroundWindow;
|
||||
use windows::Win32::UI::WindowsAndMessaging::SetLayeredWindowAttributes;
|
||||
use windows::Win32::UI::WindowsAndMessaging::SetWindowLongPtrW;
|
||||
use windows::Win32::UI::WindowsAndMessaging::SetWindowPos;
|
||||
use windows::Win32::UI::WindowsAndMessaging::ShowWindow;
|
||||
use windows::Win32::UI::WindowsAndMessaging::ShowWindowAsync;
|
||||
use windows::Win32::UI::WindowsAndMessaging::SystemParametersInfoW;
|
||||
use windows::Win32::UI::WindowsAndMessaging::WindowFromPoint;
|
||||
@@ -159,6 +161,7 @@ use crate::set_window_position::SetWindowPosition;
|
||||
use crate::windows_callbacks;
|
||||
use crate::Window;
|
||||
use crate::WindowManager;
|
||||
use crate::ASYNC_WINDOW_HANDLING_ENABLED;
|
||||
use crate::DISPLAY_INDEX_PREFERENCES;
|
||||
use crate::DUPLICATE_MONITOR_SERIAL_IDS;
|
||||
use crate::MONITOR_INDEX_PREFERENCES;
|
||||
@@ -494,7 +497,7 @@ impl WindowsApi {
|
||||
// By default SetWindowPos waits for target window's WindowProc thread
|
||||
// to process the message, so we have to use ASYNC_WINDOW_POS to avoid
|
||||
// blocking our thread in case the target window is not responding.
|
||||
if async_window_pos {
|
||||
if async_window_pos && ASYNC_WINDOW_HANDLING_ENABLED.load(Ordering::SeqCst) {
|
||||
flags |= SetWindowPosition::ASYNC_WINDOW_POS;
|
||||
}
|
||||
|
||||
@@ -532,11 +535,14 @@ impl WindowsApi {
|
||||
/// Raise the window to the top of the Z order, but do not activate or focus
|
||||
/// it. Use raise_and_focus_window to activate and focus a window.
|
||||
pub fn raise_window(hwnd: isize) -> Result<()> {
|
||||
let flags = SetWindowPosition::NO_MOVE
|
||||
let mut flags = SetWindowPosition::NO_MOVE
|
||||
| SetWindowPosition::NO_SIZE
|
||||
| SetWindowPosition::NO_ACTIVATE
|
||||
| SetWindowPosition::SHOW_WINDOW
|
||||
| SetWindowPosition::ASYNC_WINDOW_POS;
|
||||
| SetWindowPosition::SHOW_WINDOW;
|
||||
|
||||
if ASYNC_WINDOW_HANDLING_ENABLED.load(Ordering::SeqCst) {
|
||||
flags |= SetWindowPosition::ASYNC_WINDOW_POS;
|
||||
}
|
||||
|
||||
let position = HWND_TOP;
|
||||
Self::set_window_pos(
|
||||
@@ -550,11 +556,14 @@ impl WindowsApi {
|
||||
/// Lower the window to the bottom of the Z order, but do not activate or focus
|
||||
/// it.
|
||||
pub fn lower_window(hwnd: isize) -> Result<()> {
|
||||
let flags = SetWindowPosition::NO_MOVE
|
||||
let mut flags = SetWindowPosition::NO_MOVE
|
||||
| SetWindowPosition::NO_SIZE
|
||||
| SetWindowPosition::NO_ACTIVATE
|
||||
| SetWindowPosition::SHOW_WINDOW
|
||||
| SetWindowPosition::ASYNC_WINDOW_POS;
|
||||
| SetWindowPosition::SHOW_WINDOW;
|
||||
|
||||
if ASYNC_WINDOW_HANDLING_ENABLED.load(Ordering::SeqCst) {
|
||||
flags |= SetWindowPosition::ASYNC_WINDOW_POS;
|
||||
}
|
||||
|
||||
let position = HWND_BOTTOM;
|
||||
Self::set_window_pos(
|
||||
@@ -566,13 +575,14 @@ impl WindowsApi {
|
||||
}
|
||||
|
||||
pub fn set_border_pos(hwnd: isize, layout: &Rect, position: isize) -> Result<()> {
|
||||
let flags = {
|
||||
SetWindowPosition::NO_SEND_CHANGING
|
||||
| SetWindowPosition::NO_ACTIVATE
|
||||
| SetWindowPosition::NO_REDRAW
|
||||
| SetWindowPosition::SHOW_WINDOW
|
||||
| SetWindowPosition::ASYNC_WINDOW_POS
|
||||
};
|
||||
let mut flags = SetWindowPosition::NO_SEND_CHANGING
|
||||
| SetWindowPosition::NO_ACTIVATE
|
||||
| SetWindowPosition::NO_REDRAW
|
||||
| SetWindowPosition::SHOW_WINDOW;
|
||||
|
||||
if ASYNC_WINDOW_HANDLING_ENABLED.load(Ordering::SeqCst) {
|
||||
flags |= SetWindowPosition::ASYNC_WINDOW_POS;
|
||||
}
|
||||
|
||||
Self::set_window_pos(
|
||||
HWND(as_ptr!(hwnd)),
|
||||
@@ -616,9 +626,15 @@ impl WindowsApi {
|
||||
// BOOL is returned but does not signify whether or not the operation was succesful
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow
|
||||
// TODO: error handling
|
||||
unsafe {
|
||||
let _ = ShowWindowAsync(HWND(as_ptr!(hwnd)), command);
|
||||
};
|
||||
if ASYNC_WINDOW_HANDLING_ENABLED.load(Ordering::SeqCst) {
|
||||
unsafe {
|
||||
let _ = ShowWindowAsync(HWND(as_ptr!(hwnd)), command);
|
||||
};
|
||||
} else {
|
||||
unsafe {
|
||||
let _ = ShowWindow(HWND(as_ptr!(hwnd)), command);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn minimize_window(hwnd: isize) {
|
||||
|
||||
@@ -217,6 +217,10 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"async_window_handling": {
|
||||
"description": "Use asynchronous window handling to avoid blocking the main thread when a window is not responding (default: false)",
|
||||
"type": "boolean"
|
||||
},
|
||||
"bar_configurations": {
|
||||
"description": "Komorebi status bar configuration files for multiple instances on different monitors",
|
||||
"type": "array",
|
||||
|
||||
Reference in New Issue
Block a user