mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 22:31: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
|
# 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.
|
- On Windows, remove internally unique DC per window.
|
||||||
- macOS: Remove the need to call `set_ime_position` after moving the window.
|
- macOS: Remove the need to call `set_ime_position` after moving the window.
|
||||||
- Added `Window::is_visible`.
|
- Added `Window::is_visible`.
|
||||||
|
|
|
@ -140,6 +140,9 @@ pub trait WindowExtWindows {
|
||||||
|
|
||||||
/// Returns the current window theme.
|
/// Returns the current window theme.
|
||||||
fn theme(&self) -> 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 {
|
impl WindowExtWindows for Window {
|
||||||
|
@ -167,6 +170,11 @@ impl WindowExtWindows for Window {
|
||||||
fn theme(&self) -> Theme {
|
fn theme(&self) -> Theme {
|
||||||
self.window.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.
|
/// 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.
|
/// Forces a theme or uses the system settings if `None` was provided.
|
||||||
fn with_theme(self, theme: Option<Theme>) -> WindowBuilder;
|
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 {
|
impl WindowBuilderExtWindows for WindowBuilder {
|
||||||
|
@ -262,6 +273,12 @@ impl WindowBuilderExtWindows for WindowBuilder {
|
||||||
self.platform_specific.preferred_theme = theme;
|
self.platform_specific.preferred_theme = theme;
|
||||||
self
|
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.
|
/// Additional methods on `MonitorHandle` that are specific to Windows.
|
||||||
|
|
|
@ -10,7 +10,6 @@ use windows_sys::{
|
||||||
System::Com::{
|
System::Com::{
|
||||||
IAdviseSink, IDataObject, IEnumFORMATETC, IEnumSTATDATA, FORMATETC, STGMEDIUM,
|
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,
|
pub SetActiveAlt: unsafe extern "system" fn(This: *mut ITaskbarList, hwnd: HWND) -> HRESULT,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct ITaskbarList {
|
||||||
|
pub lpVtbl: *const ITaskbarListVtbl,
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct ITaskbarList2Vtbl {
|
pub struct ITaskbarList2Vtbl {
|
||||||
pub parent: ITaskbarListVtbl,
|
pub parent: ITaskbarListVtbl,
|
||||||
|
@ -120,6 +124,7 @@ pub struct ITaskbarList2Vtbl {
|
||||||
fFullscreen: BOOL,
|
fFullscreen: BOOL,
|
||||||
) -> HRESULT,
|
) -> HRESULT,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct ITaskbarList2 {
|
pub struct ITaskbarList2 {
|
||||||
pub lpVtbl: *const ITaskbarList2Vtbl,
|
pub lpVtbl: *const ITaskbarList2Vtbl,
|
||||||
|
@ -132,6 +137,13 @@ pub const CLSID_TaskbarList: GUID = GUID {
|
||||||
data4: [0x95, 0x8a, 0x00, 0x60, 0x97, 0xc9, 0xa0, 0x90],
|
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 {
|
pub const IID_ITaskbarList2: GUID = GUID {
|
||||||
data1: 0x602d4995,
|
data1: 0x602d4995,
|
||||||
data2: 0xb13a,
|
data2: 0xb13a,
|
||||||
|
|
|
@ -35,6 +35,7 @@ pub struct PlatformSpecificWindowBuilderAttributes {
|
||||||
pub no_redirection_bitmap: bool,
|
pub no_redirection_bitmap: bool,
|
||||||
pub drag_and_drop: bool,
|
pub drag_and_drop: bool,
|
||||||
pub preferred_theme: Option<Theme>,
|
pub preferred_theme: Option<Theme>,
|
||||||
|
pub skip_taskbar: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for PlatformSpecificWindowBuilderAttributes {
|
impl Default for PlatformSpecificWindowBuilderAttributes {
|
||||||
|
@ -46,6 +47,7 @@ impl Default for PlatformSpecificWindowBuilderAttributes {
|
||||||
no_redirection_bitmap: false,
|
no_redirection_bitmap: false,
|
||||||
drag_and_drop: true,
|
drag_and_drop: true,
|
||||||
preferred_theme: None,
|
preferred_theme: None,
|
||||||
|
skip_taskbar: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,9 @@ use crate::{
|
||||||
monitor::MonitorHandle as RootMonitorHandle,
|
monitor::MonitorHandle as RootMonitorHandle,
|
||||||
platform_impl::platform::{
|
platform_impl::platform::{
|
||||||
dark_mode::try_theme,
|
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},
|
dpi::{dpi_to_scale_factor, enable_non_client_dpi_scaling, hwnd_dpi},
|
||||||
drop_handler::FileDropHandler,
|
drop_handler::FileDropHandler,
|
||||||
event_loop::{self, EventLoopWindowTarget, DESTROY_MSG_ID},
|
event_loop::{self, EventLoopWindowTarget, DESTROY_MSG_ID},
|
||||||
|
@ -665,6 +667,43 @@ impl Window {
|
||||||
self.window_state.lock().current_theme
|
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]
|
#[inline]
|
||||||
pub fn focus_window(&self) {
|
pub fn focus_window(&self) {
|
||||||
let window = self.window.clone();
|
let window = self.window.clone();
|
||||||
|
@ -839,6 +878,8 @@ impl<'a, T: 'static> InitData<'a, T> {
|
||||||
DeleteObject(region);
|
DeleteObject(region);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
win.set_skip_taskbar(self.pl_attribs.skip_taskbar);
|
||||||
|
|
||||||
let attributes = self.attributes.clone();
|
let attributes = self.attributes.clone();
|
||||||
|
|
||||||
// Set visible before setting the size to ensure the
|
// 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() {
|
pub fn com_initialized() {
|
||||||
|
@ -1017,30 +1059,30 @@ pub fn com_initialized() {
|
||||||
unsafe fn taskbar_mark_fullscreen(handle: HWND, fullscreen: bool) {
|
unsafe fn taskbar_mark_fullscreen(handle: HWND, fullscreen: bool) {
|
||||||
com_initialized();
|
com_initialized();
|
||||||
|
|
||||||
TASKBAR_LIST.with(|task_bar_list_ptr| {
|
TASKBAR_LIST2.with(|task_bar_list2_ptr| {
|
||||||
let mut task_bar_list = task_bar_list_ptr.get();
|
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(
|
let hr = CoCreateInstance(
|
||||||
&CLSID_TaskbarList,
|
&CLSID_TaskbarList,
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
CLSCTX_ALL,
|
CLSCTX_ALL,
|
||||||
&IID_ITaskbarList2,
|
&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
|
// In some old windows, the taskbar object could not be created, we just ignore it
|
||||||
return;
|
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();
|
task_bar_list2 = task_bar_list2_ptr.get();
|
||||||
let mark_fullscreen_window = (*(*task_bar_list).lpVtbl).MarkFullscreenWindow;
|
let mark_fullscreen_window = (*(*task_bar_list2).lpVtbl).MarkFullscreenWindow;
|
||||||
mark_fullscreen_window(task_bar_list, handle, if fullscreen { 1 } else { 0 });
|
mark_fullscreen_window(task_bar_list2, handle, if fullscreen { 1 } else { 0 });
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue