Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows: apply skip taskbar state when taskbar is restarted #2380

Merged
merged 3 commits into from Jul 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/platform_impl/windows/event_loop.rs
Expand Up @@ -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,
Expand Down Expand Up @@ -610,6 +612,10 @@ pub static SET_RETAIN_STATE_ON_SIZE_MSG_ID: Lazy<u32> =
Lazy::new(|| unsafe { RegisterWindowMessageA("Winit::SetRetainMaximized\0".as_ptr()) });
static THREAD_EVENT_TARGET_WINDOW_CLASS: Lazy<Vec<u16>> =
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<u32> =
Lazy::new(|| unsafe { RegisterWindowMessageA("TaskbarCreated\0".as_ptr()) });

fn create_event_target_window<T: 'static>() -> HWND {
unsafe {
Expand Down Expand Up @@ -2175,6 +2181,10 @@ unsafe fn public_window_callback_inner<T: 'static>(
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)
}
Expand Down
69 changes: 36 additions & 33 deletions src/platform_impl/windows/window.rs
Expand Up @@ -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]
Expand Down Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions src/platform_impl/windows/window_state.rs
Expand Up @@ -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)]
Expand Down Expand Up @@ -152,6 +154,8 @@ impl WindowState {

is_active: false,
is_focused: false,

skip_taskbar: false,
}
}

Expand Down