mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-02-24 00:37:43 +11:00
feat(Windows): add with_msg_hook
(#2213)
This commit is contained in:
parent
945a9e3122
commit
08de2b3fc4
4 changed files with 59 additions and 7 deletions
|
@ -8,6 +8,7 @@ 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, 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`.
|
||||||
|
|
|
@ -50,7 +50,7 @@ pub struct EventLoopWindowTarget<T: 'static> {
|
||||||
///
|
///
|
||||||
/// This is used to make specifying options that affect the whole application
|
/// This is used to make specifying options that affect the whole application
|
||||||
/// easier. But note that constructing multiple event loops is not supported.
|
/// easier. But note that constructing multiple event loops is not supported.
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Default)]
|
||||||
pub struct EventLoopBuilder<T: 'static> {
|
pub struct EventLoopBuilder<T: 'static> {
|
||||||
pub(crate) platform_specific: platform_impl::PlatformSpecificEventLoopAttributes,
|
pub(crate) platform_specific: platform_impl::PlatformSpecificEventLoopAttributes,
|
||||||
_p: PhantomData<T>,
|
_p: PhantomData<T>,
|
||||||
|
@ -95,7 +95,7 @@ impl<T> EventLoopBuilder<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn build(&mut self) -> EventLoop<T> {
|
pub fn build(&mut self) -> EventLoop<T> {
|
||||||
EventLoop {
|
EventLoop {
|
||||||
event_loop: platform_impl::EventLoop::new(&self.platform_specific),
|
event_loop: platform_impl::EventLoop::new(&mut self.platform_specific),
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#![cfg(target_os = "windows")]
|
#![cfg(target_os = "windows")]
|
||||||
|
|
||||||
use std::path::Path;
|
use std::{ffi::c_void, path::Path};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
dpi::PhysicalSize,
|
dpi::PhysicalSize,
|
||||||
|
@ -56,6 +56,36 @@ pub trait EventLoopBuilderExtWindows {
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
fn with_dpi_aware(&mut self, dpi_aware: bool) -> &mut Self;
|
fn with_dpi_aware(&mut self, dpi_aware: bool) -> &mut Self;
|
||||||
|
|
||||||
|
/// A callback to be executed before dispatching a win32 message to the window procedure.
|
||||||
|
/// Return true to disable winit's internal message dispatching.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use windows_sys::Win32::UI::WindowsAndMessaging::{ACCEL, CreateAcceleratorTableW, TranslateAcceleratorW, DispatchMessageW, TranslateMessage, MSG};
|
||||||
|
/// use winit::event_loop::EventLoopBuilder;
|
||||||
|
/// #[cfg(target_os = "windows")]
|
||||||
|
/// use winit::platform::windows::EventLoopBuilderExtWindows;
|
||||||
|
///
|
||||||
|
/// let mut builder = EventLoopBuilder::new();
|
||||||
|
/// #[cfg(target_os = "windows")]
|
||||||
|
/// builder.with_msg_hook(|msg|{
|
||||||
|
/// let msg = msg as *const MSG;
|
||||||
|
/// # let accels: Vec<ACCEL> = Vec::new();
|
||||||
|
/// let translated = unsafe {
|
||||||
|
/// TranslateAcceleratorW(
|
||||||
|
/// (*msg).hwnd,
|
||||||
|
/// CreateAcceleratorTableW(accels.as_ptr() as _, 1),
|
||||||
|
/// msg,
|
||||||
|
/// ) == 1
|
||||||
|
/// };
|
||||||
|
/// translated
|
||||||
|
/// });
|
||||||
|
/// ```
|
||||||
|
fn with_msg_hook<F>(&mut self, callback: F) -> &mut Self
|
||||||
|
where
|
||||||
|
F: FnMut(*const c_void) -> bool + 'static;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> EventLoopBuilderExtWindows for EventLoopBuilder<T> {
|
impl<T> EventLoopBuilderExtWindows for EventLoopBuilder<T> {
|
||||||
|
@ -70,6 +100,15 @@ impl<T> EventLoopBuilderExtWindows for EventLoopBuilder<T> {
|
||||||
self.platform_specific.dpi_aware = dpi_aware;
|
self.platform_specific.dpi_aware = dpi_aware;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn with_msg_hook<F>(&mut self, callback: F) -> &mut Self
|
||||||
|
where
|
||||||
|
F: FnMut(*const c_void) -> bool + 'static,
|
||||||
|
{
|
||||||
|
self.platform_specific.msg_hook = Some(Box::new(callback));
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Additional methods on `Window` that are specific to Windows.
|
/// Additional methods on `Window` that are specific to Windows.
|
||||||
|
|
|
@ -6,6 +6,7 @@ use parking_lot::Mutex;
|
||||||
use std::{
|
use std::{
|
||||||
cell::Cell,
|
cell::Cell,
|
||||||
collections::VecDeque,
|
collections::VecDeque,
|
||||||
|
ffi::c_void,
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
mem, panic, ptr,
|
mem, panic, ptr,
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
|
@ -150,12 +151,13 @@ impl<T> ThreadMsgTargetData<T> {
|
||||||
pub struct EventLoop<T: 'static> {
|
pub struct EventLoop<T: 'static> {
|
||||||
thread_msg_sender: Sender<T>,
|
thread_msg_sender: Sender<T>,
|
||||||
window_target: RootELW<T>,
|
window_target: RootELW<T>,
|
||||||
|
msg_hook: Option<Box<dyn FnMut(*const c_void) -> bool + 'static>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Hash)]
|
|
||||||
pub(crate) struct PlatformSpecificEventLoopAttributes {
|
pub(crate) struct PlatformSpecificEventLoopAttributes {
|
||||||
pub(crate) any_thread: bool,
|
pub(crate) any_thread: bool,
|
||||||
pub(crate) dpi_aware: bool,
|
pub(crate) dpi_aware: bool,
|
||||||
|
pub(crate) msg_hook: Option<Box<dyn FnMut(*const c_void) -> bool + 'static>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for PlatformSpecificEventLoopAttributes {
|
impl Default for PlatformSpecificEventLoopAttributes {
|
||||||
|
@ -163,6 +165,7 @@ impl Default for PlatformSpecificEventLoopAttributes {
|
||||||
Self {
|
Self {
|
||||||
any_thread: false,
|
any_thread: false,
|
||||||
dpi_aware: true,
|
dpi_aware: true,
|
||||||
|
msg_hook: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,7 +177,7 @@ pub struct EventLoopWindowTarget<T: 'static> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: 'static> EventLoop<T> {
|
impl<T: 'static> EventLoop<T> {
|
||||||
pub(crate) fn new(attributes: &PlatformSpecificEventLoopAttributes) -> Self {
|
pub(crate) fn new(attributes: &mut PlatformSpecificEventLoopAttributes) -> Self {
|
||||||
let thread_id = unsafe { GetCurrentThreadId() };
|
let thread_id = unsafe { GetCurrentThreadId() };
|
||||||
|
|
||||||
if !attributes.any_thread && thread_id != main_thread_id() {
|
if !attributes.any_thread && thread_id != main_thread_id() {
|
||||||
|
@ -211,6 +214,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
},
|
},
|
||||||
_marker: PhantomData,
|
_marker: PhantomData,
|
||||||
},
|
},
|
||||||
|
msg_hook: attributes.msg_hook.take(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,8 +255,16 @@ impl<T: 'static> EventLoop<T> {
|
||||||
if GetMessageW(&mut msg, 0, 0, 0) == false.into() {
|
if GetMessageW(&mut msg, 0, 0, 0) == false.into() {
|
||||||
break 'main 0;
|
break 'main 0;
|
||||||
}
|
}
|
||||||
TranslateMessage(&msg);
|
|
||||||
DispatchMessageW(&msg);
|
let handled = if let Some(callback) = self.msg_hook.as_deref_mut() {
|
||||||
|
callback(&mut msg as *mut _ as *mut _)
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
if !handled {
|
||||||
|
TranslateMessage(&msg);
|
||||||
|
DispatchMessageW(&msg);
|
||||||
|
}
|
||||||
|
|
||||||
if let Err(payload) = runner.take_panic_error() {
|
if let Err(payload) = runner.take_panic_error() {
|
||||||
runner.reset_runner();
|
runner.reset_runner();
|
||||||
|
|
Loading…
Add table
Reference in a new issue