From 83cc7bf7c02ea3d6be626b25ff66a91af5ef0499 Mon Sep 17 00:00:00 2001 From: LGUG2Z Date: Wed, 19 Jun 2024 14:13:53 -0700 Subject: [PATCH] fix(wm): ensure window msg threads are stopped This commit ensures that message handling threads for windows that are created by komorebi are exited properly when the windows are destroyed. For some reason, passing the HWND returned by CreateWindowExW to GetMessageW continues returning TRUE even after the window has been destroyed. If HWND::NULL (via the Default trait) is passed to GetMessageW, which retrieves messages for any window belonging to the current thread (our threads here only own a single window), GetMessageW returns FALSE as expected after the window is destroyed. re #862 --- komorebi/src/border_manager/border.rs | 18 ++++++++++++------ komorebi/src/monitor_reconciliator/hidden.rs | 17 ++++++++++++----- komorebi/src/stackbar_manager/stackbar.rs | 12 +++++++++--- komorebi/src/winevent_listener.rs | 8 ++++++-- 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/komorebi/src/border_manager/border.rs b/komorebi/src/border_manager/border.rs index b5e90752..720a6dbb 100644 --- a/komorebi/src/border_manager/border.rs +++ b/komorebi/src/border_manager/border.rs @@ -98,13 +98,19 @@ impl Border { let hwnd = WindowsApi::create_border_window(PCWSTR(name.as_ptr()), h_module)?; hwnd_sender.send(hwnd)?; - let mut message = MSG::default(); - unsafe { - while GetMessageW(&mut message, HWND(hwnd), 0, 0).into() { - TranslateMessage(&message); - DispatchMessageW(&message); - std::thread::sleep(Duration::from_millis(10)); + let mut msg: MSG = MSG::default(); + + loop { + unsafe { + if !GetMessageW(&mut msg, HWND::default(), 0, 0).as_bool() { + tracing::debug!("border window event processing thread shutdown"); + break; + }; + TranslateMessage(&msg); + DispatchMessageW(&msg); } + + std::thread::sleep(Duration::from_millis(10)) } Ok(()) diff --git a/komorebi/src/monitor_reconciliator/hidden.rs b/komorebi/src/monitor_reconciliator/hidden.rs index ab50f0d1..efef34fc 100644 --- a/komorebi/src/monitor_reconciliator/hidden.rs +++ b/komorebi/src/monitor_reconciliator/hidden.rs @@ -1,4 +1,5 @@ use std::sync::mpsc; +use std::time::Duration; use windows::core::PCWSTR; use windows::Win32::Foundation::HWND; @@ -68,13 +69,19 @@ impl Hidden { let hwnd = WindowsApi::create_hidden_window(PCWSTR(name.as_ptr()), h_module)?; hwnd_sender.send(hwnd)?; - let mut message = MSG::default(); + let mut msg: MSG = MSG::default(); - unsafe { - while GetMessageW(&mut message, HWND(hwnd), 0, 0).into() { - TranslateMessage(&message); - DispatchMessageW(&message); + loop { + unsafe { + if !GetMessageW(&mut msg, HWND::default(), 0, 0).as_bool() { + tracing::debug!("hidden window event processing thread shutdown"); + break; + }; + TranslateMessage(&msg); + DispatchMessageW(&msg); } + + std::thread::sleep(Duration::from_millis(10)) } Ok(()) diff --git a/komorebi/src/stackbar_manager/stackbar.rs b/komorebi/src/stackbar_manager/stackbar.rs index 03ef7702..c8600d23 100644 --- a/komorebi/src/stackbar_manager/stackbar.rs +++ b/komorebi/src/stackbar_manager/stackbar.rs @@ -120,11 +120,17 @@ impl Stackbar { SetLayeredWindowAttributes(hwnd, COLORREF(0), 0, LWA_COLORKEY)?; hwnd_sender.send(hwnd)?; - let mut msg = MSG::default(); - while GetMessageW(&mut msg, hwnd, 0, 0).into() { + let mut msg: MSG = MSG::default(); + + loop { + if !GetMessageW(&mut msg, HWND::default(), 0, 0).as_bool() { + tracing::debug!("stackbar window event processing thread shutdown"); + break; + }; TranslateMessage(&msg); DispatchMessageW(&msg); - std::thread::sleep(Duration::from_millis(10)); + + std::thread::sleep(Duration::from_millis(10)) } } diff --git a/komorebi/src/winevent_listener.rs b/komorebi/src/winevent_listener.rs index 88175c2a..f4477517 100644 --- a/komorebi/src/winevent_listener.rs +++ b/komorebi/src/winevent_listener.rs @@ -1,4 +1,5 @@ use std::sync::OnceLock; +use std::time::Duration; use crossbeam_channel::Receiver; use crossbeam_channel::Sender; @@ -34,16 +35,19 @@ pub fn start() { ) }; + let mut msg: MSG = MSG::default(); + loop { - let mut msg: MSG = MSG::default(); unsafe { if !GetMessageW(&mut msg, HWND(0), 0, 0).as_bool() { - tracing::info!("windows event processing shutdown"); + tracing::debug!("windows event processing thread shutdown"); break; }; TranslateMessage(&msg); DispatchMessageW(&msg); } + + std::thread::sleep(Duration::from_millis(10)) } }) });