feat(Windows): add skip taskbar methods (#2177)

This commit is contained in:
Amr Bashir 2022-04-01 20:21:09 +02:00 committed by GitHub
parent 52c4670237
commit ab1f636960
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 88 additions and 14 deletions

View file

@ -10,7 +10,6 @@ use windows_sys::{
System::Com::{
IAdviseSink, IDataObject, IEnumFORMATETC, IEnumSTATDATA, FORMATETC, STGMEDIUM,
},
UI::Shell::ITaskbarList,
},
};
@ -111,6 +110,11 @@ pub struct ITaskbarListVtbl {
pub SetActiveAlt: unsafe extern "system" fn(This: *mut ITaskbarList, hwnd: HWND) -> HRESULT,
}
#[repr(C)]
pub struct ITaskbarList {
pub lpVtbl: *const ITaskbarListVtbl,
}
#[repr(C)]
pub struct ITaskbarList2Vtbl {
pub parent: ITaskbarListVtbl,
@ -120,6 +124,7 @@ pub struct ITaskbarList2Vtbl {
fFullscreen: BOOL,
) -> HRESULT,
}
#[repr(C)]
pub struct ITaskbarList2 {
pub lpVtbl: *const ITaskbarList2Vtbl,
@ -132,6 +137,13 @@ pub const CLSID_TaskbarList: GUID = GUID {
data4: [0x95, 0x8a, 0x00, 0x60, 0x97, 0xc9, 0xa0, 0x90],
};
pub const IID_ITaskbarList: GUID = GUID {
data1: 0x56FDF342,
data2: 0xFD6D,
data3: 0x11D0,
data4: [0x95, 0x8A, 0x00, 0x60, 0x97, 0xC9, 0xA0, 0x90],
};
pub const IID_ITaskbarList2: GUID = GUID {
data1: 0x602d4995,
data2: 0xb13a,

View file

@ -35,6 +35,7 @@ pub struct PlatformSpecificWindowBuilderAttributes {
pub no_redirection_bitmap: bool,
pub drag_and_drop: bool,
pub preferred_theme: Option<Theme>,
pub skip_taskbar: bool,
}
impl Default for PlatformSpecificWindowBuilderAttributes {
@ -46,6 +47,7 @@ impl Default for PlatformSpecificWindowBuilderAttributes {
no_redirection_bitmap: false,
drag_and_drop: true,
preferred_theme: None,
skip_taskbar: false,
}
}
}

View file

@ -62,7 +62,9 @@ use crate::{
monitor::MonitorHandle as RootMonitorHandle,
platform_impl::platform::{
dark_mode::try_theme,
definitions::{CLSID_TaskbarList, IID_ITaskbarList2, ITaskbarList2},
definitions::{
CLSID_TaskbarList, IID_ITaskbarList, IID_ITaskbarList2, ITaskbarList, ITaskbarList2,
},
dpi::{dpi_to_scale_factor, enable_non_client_dpi_scaling, hwnd_dpi},
drop_handler::FileDropHandler,
event_loop::{self, EventLoopWindowTarget, DESTROY_MSG_ID},
@ -665,6 +667,43 @@ impl Window {
self.window_state.lock().current_theme
}
#[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);
}
});
}
}
#[inline]
pub fn focus_window(&self) {
let window = self.window.clone();
@ -839,6 +878,8 @@ impl<'a, T: 'static> InitData<'a, T> {
DeleteObject(region);
}
win.set_skip_taskbar(self.pl_attribs.skip_taskbar);
let attributes = self.attributes.clone();
// Set visible before setting the size to ensure the
@ -999,7 +1040,8 @@ thread_local! {
}
};
static TASKBAR_LIST: Cell<*mut ITaskbarList2> = Cell::new(ptr::null_mut());
static TASKBAR_LIST: Cell<*mut ITaskbarList> = Cell::new(ptr::null_mut());
static TASKBAR_LIST2: Cell<*mut ITaskbarList2> = Cell::new(ptr::null_mut());
}
pub fn com_initialized() {
@ -1017,30 +1059,30 @@ pub fn com_initialized() {
unsafe fn taskbar_mark_fullscreen(handle: HWND, fullscreen: bool) {
com_initialized();
TASKBAR_LIST.with(|task_bar_list_ptr| {
let mut task_bar_list = task_bar_list_ptr.get();
TASKBAR_LIST2.with(|task_bar_list2_ptr| {
let mut task_bar_list2 = task_bar_list2_ptr.get();
if task_bar_list.is_null() {
if task_bar_list2.is_null() {
let hr = CoCreateInstance(
&CLSID_TaskbarList,
ptr::null_mut(),
CLSCTX_ALL,
&IID_ITaskbarList2,
&mut task_bar_list as *mut _ as *mut _,
&mut task_bar_list2 as *mut _ as *mut _,
);
let hr_init = (*(*task_bar_list).lpVtbl).parent.HrInit;
let hr_init = (*(*task_bar_list2).lpVtbl).parent.HrInit;
if hr != S_OK || hr_init(task_bar_list.cast()) != S_OK {
if hr != S_OK || hr_init(task_bar_list2.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_list2_ptr.set(task_bar_list2)
}
task_bar_list = task_bar_list_ptr.get();
let mark_fullscreen_window = (*(*task_bar_list).lpVtbl).MarkFullscreenWindow;
mark_fullscreen_window(task_bar_list, handle, if fullscreen { 1 } else { 0 });
task_bar_list2 = task_bar_list2_ptr.get();
let mark_fullscreen_window = (*(*task_bar_list2).lpVtbl).MarkFullscreenWindow;
mark_fullscreen_window(task_bar_list2, handle, if fullscreen { 1 } else { 0 });
})
}