mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 06:11:30 +11:00
feat(Windows): add skip taskbar methods (#2177)
This commit is contained in:
parent
52c4670237
commit
ab1f636960
|
@ -8,7 +8,8 @@ And please only add new entries to the top of this list, right below the `# Unre
|
|||
|
||||
# Unreleased
|
||||
|
||||
- On Windows, Added `EventLoopBuilderExtWindows::with_msg_hook`
|
||||
- On Windows, added `WindowExtWindows::set_skip_taskbar` and `WindowBuilderExtWindows::with_skip_taskbar`.
|
||||
- On Windows, added `EventLoopBuilderExtWindows::with_msg_hook`.
|
||||
- On Windows, remove internally unique DC per window.
|
||||
- macOS: Remove the need to call `set_ime_position` after moving the window.
|
||||
- Added `Window::is_visible`.
|
||||
|
|
|
@ -140,6 +140,9 @@ pub trait WindowExtWindows {
|
|||
|
||||
/// Returns the current window theme.
|
||||
fn theme(&self) -> Theme;
|
||||
|
||||
/// Whether to show or hide the window icon in the taskbar.
|
||||
fn set_skip_taskbar(&self, skip: bool);
|
||||
}
|
||||
|
||||
impl WindowExtWindows for Window {
|
||||
|
@ -167,6 +170,11 @@ impl WindowExtWindows for Window {
|
|||
fn theme(&self) -> Theme {
|
||||
self.window.theme()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn set_skip_taskbar(&self, skip: bool) {
|
||||
self.window.set_skip_taskbar(skip)
|
||||
}
|
||||
}
|
||||
|
||||
/// Additional methods on `WindowBuilder` that are specific to Windows.
|
||||
|
@ -218,6 +226,9 @@ pub trait WindowBuilderExtWindows {
|
|||
|
||||
/// Forces a theme or uses the system settings if `None` was provided.
|
||||
fn with_theme(self, theme: Option<Theme>) -> WindowBuilder;
|
||||
|
||||
/// Whether show or hide the window icon in the taskbar.
|
||||
fn with_skip_taskbar(self, skip: bool) -> WindowBuilder;
|
||||
}
|
||||
|
||||
impl WindowBuilderExtWindows for WindowBuilder {
|
||||
|
@ -262,6 +273,12 @@ impl WindowBuilderExtWindows for WindowBuilder {
|
|||
self.platform_specific.preferred_theme = theme;
|
||||
self
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn with_skip_taskbar(mut self, skip: bool) -> WindowBuilder {
|
||||
self.platform_specific.skip_taskbar = skip;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Additional methods on `MonitorHandle` that are specific to Windows.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 });
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue