From 6e3f148e3403a011b9a7e16de9b7f785873fd4be Mon Sep 17 00:00:00 2001 From: amrbashir Date: Tue, 19 Jul 2022 16:01:33 +0200 Subject: [PATCH] On Windows, apply skip taskbr state when taskbar is restarted --- src/platform_impl/windows/event_loop.rs | 10 ++++ src/platform_impl/windows/window.rs | 69 ++++++++++++----------- src/platform_impl/windows/window_state.rs | 4 ++ 3 files changed, 50 insertions(+), 33 deletions(-) diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 870f323d96..2423a732ba 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -93,6 +93,8 @@ use crate::{ }; use runner::{EventLoopRunner, EventLoopRunnerShared}; +use super::window::set_skip_taskbar; + type GetPointerFrameInfoHistory = unsafe extern "system" fn( pointerId: u32, entriesCount: *mut u32, @@ -610,6 +612,10 @@ pub static SET_RETAIN_STATE_ON_SIZE_MSG_ID: Lazy = Lazy::new(|| unsafe { RegisterWindowMessageA("Winit::SetRetainMaximized\0".as_ptr()) }); static THREAD_EVENT_TARGET_WINDOW_CLASS: Lazy> = Lazy::new(|| util::encode_wide("Winit Thread Event Target")); +/// When the taskbar is created, it registers a message with the "TaskbarCreated" string and then broadcasts this message to all top-level windows +/// https://docs.microsoft.com/en-us/windows/win32/shell/taskbar#taskbar-creation-notification +pub static TASKBAR_CREATED: Lazy = + Lazy::new(|| unsafe { RegisterWindowMessageA("TaskbarCreated\0".as_ptr()) }); fn create_event_target_window() -> HWND { unsafe { @@ -2175,6 +2181,10 @@ unsafe fn public_window_callback_inner( f.set(WindowFlags::MARKER_RETAIN_STATE_ON_SIZE, wparam != 0) }); 0 + } else if msg == *TASKBAR_CREATED { + let window_state = userdata.window_state.lock(); + set_skip_taskbar(window, window_state.skip_taskbar); + DefWindowProcW(window, msg, wparam, lparam) } else { DefWindowProcW(window, msg, wparam, lparam) } diff --git a/src/platform_impl/windows/window.rs b/src/platform_impl/windows/window.rs index bc55a2a4b1..0d16cc79b6 100644 --- a/src/platform_impl/windows/window.rs +++ b/src/platform_impl/windows/window.rs @@ -680,39 +680,8 @@ impl Window { #[inline] pub fn set_skip_taskbar(&self, skip: bool) { - com_initialized(); - unsafe { - TASKBAR_LIST.with(|task_bar_list_ptr| { - let mut task_bar_list = task_bar_list_ptr.get(); - - if task_bar_list.is_null() { - let hr = CoCreateInstance( - &CLSID_TaskbarList, - ptr::null_mut(), - CLSCTX_ALL, - &IID_ITaskbarList, - &mut task_bar_list as *mut _ as *mut _, - ); - - let hr_init = (*(*task_bar_list).lpVtbl).HrInit; - - if hr != S_OK || hr_init(task_bar_list.cast()) != S_OK { - // In some old windows, the taskbar object could not be created, we just ignore it - return; - } - task_bar_list_ptr.set(task_bar_list) - } - - task_bar_list = task_bar_list_ptr.get(); - if skip { - let delete_tab = (*(*task_bar_list).lpVtbl).DeleteTab; - delete_tab(task_bar_list, self.window.0); - } else { - let add_tab = (*(*task_bar_list).lpVtbl).AddTab; - add_tab(task_bar_list, self.window.0); - } - }); - } + self.window_state.lock().skip_taskbar = skip; + unsafe { set_skip_taskbar(self.hwnd(), skip) }; } #[inline] @@ -1099,6 +1068,40 @@ unsafe fn taskbar_mark_fullscreen(handle: HWND, fullscreen: bool) { }) } +pub(crate) unsafe fn set_skip_taskbar(hwnd: HWND, skip: bool) { + com_initialized(); + TASKBAR_LIST.with(|task_bar_list_ptr| { + let mut task_bar_list = task_bar_list_ptr.get(); + + if task_bar_list.is_null() { + let hr = CoCreateInstance( + &CLSID_TaskbarList, + ptr::null_mut(), + CLSCTX_ALL, + &IID_ITaskbarList, + &mut task_bar_list as *mut _ as *mut _, + ); + + let hr_init = (*(*task_bar_list).lpVtbl).HrInit; + + if hr != S_OK || hr_init(task_bar_list.cast()) != S_OK { + // In some old windows, the taskbar object could not be created, we just ignore it + return; + } + task_bar_list_ptr.set(task_bar_list) + } + + task_bar_list = task_bar_list_ptr.get(); + if skip { + let delete_tab = (*(*task_bar_list).lpVtbl).DeleteTab; + delete_tab(task_bar_list, hwnd); + } else { + let add_tab = (*(*task_bar_list).lpVtbl).AddTab; + add_tab(task_bar_list, hwnd); + } + }); +} + unsafe fn force_window_active(handle: HWND) { // In some situation, calling SetForegroundWindow could not bring up the window, // This is a little hack which can "steal" the foreground window permission diff --git a/src/platform_impl/windows/window_state.rs b/src/platform_impl/windows/window_state.rs index 35a8f0d51e..242d701da5 100644 --- a/src/platform_impl/windows/window_state.rs +++ b/src/platform_impl/windows/window_state.rs @@ -49,6 +49,8 @@ pub struct WindowState { // Used by WM_NCACTIVATE, WM_SETFOCUS and WM_KILLFOCUS pub is_active: bool, pub is_focused: bool, + + pub skip_taskbar: bool, } #[derive(Clone)] @@ -152,6 +154,8 @@ impl WindowState { is_active: false, is_focused: false, + + skip_taskbar: false, } }