Skip to content

Commit f07fe27

Browse files
committed
wip
1 parent 5f52d7c commit f07fe27

7 files changed

Lines changed: 144 additions & 59 deletions

File tree

examples/dpi.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
use winit::dpi::PhysicalSize;
2+
use winit::{
3+
event::{Event, WindowEvent},
4+
event_loop::{ControlFlow, EventLoop},
5+
window::WindowBuilder,
6+
};
7+
8+
/// Change the DPI settings in Windows while running this.
9+
fn main() {
10+
simple_logger::init().unwrap();
11+
let event_loop = EventLoop::new();
12+
13+
let window = WindowBuilder::new()
14+
.with_title("A fantastic window!")
15+
.with_inner_size(winit::dpi::LogicalSize::new(128.0, 128.0))
16+
.build(&event_loop)
17+
.unwrap();
18+
19+
event_loop.run(move |event, _, control_flow| {
20+
*control_flow = ControlFlow::Wait;
21+
22+
match event {
23+
Event::WindowEvent {
24+
event: WindowEvent::CloseRequested,
25+
window_id,
26+
} if window_id == window.id() => *control_flow = ControlFlow::Exit,
27+
Event::MainEventsCleared => {
28+
window.request_redraw();
29+
}
30+
31+
// DPI changed happened!
32+
Event::WindowEvent {
33+
event: WindowEvent::ScaleFactorChanged(state),
34+
..
35+
} => {
36+
dbg!(state.inner_size());
37+
38+
state.set_inner_size(PhysicalSize {
39+
width: 100,
40+
height: 200,
41+
});
42+
}
43+
44+
_ => (),
45+
}
46+
});
47+
}

src/event.rs

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,10 @@ use crate::{
4545
/// Describes a generic event.
4646
///
4747
/// See the module-level docs for more information on the event loop manages each event.
48+
///
49+
/// `T` is a user-defined custom event type.
4850
#[derive(Debug, PartialEq)]
49-
pub enum Event<'a, T: 'static> {
51+
pub enum Event<T: 'static> {
5052
/// Emitted when new events arrive from the OS to be processed.
5153
///
5254
/// This event type is useful as a place to put code that should be done before you start
@@ -58,7 +60,7 @@ pub enum Event<'a, T: 'static> {
5860
/// Emitted when the OS sends an event to a winit window.
5961
WindowEvent {
6062
window_id: WindowId,
61-
event: WindowEvent<'a>,
63+
event: WindowEvent,
6264
},
6365

6466
/// Emitted when the OS sends an event to a device.
@@ -114,8 +116,8 @@ pub enum Event<'a, T: 'static> {
114116
LoopDestroyed,
115117
}
116118

117-
impl<'a, T> Event<'a, T> {
118-
pub fn map_nonuser_event<U>(self) -> Result<Event<'a, U>, Event<'a, T>> {
119+
impl<T> Event<T> {
120+
pub fn map_nonuser_event<U>(self) -> Result<Event<U>, Event<T>> {
119121
use self::Event::*;
120122
match self {
121123
UserEvent(_) => Err(self),
@@ -133,7 +135,7 @@ impl<'a, T> Event<'a, T> {
133135

134136
/// If the event doesn't contain a reference, turn it into an event with a `'static` lifetime.
135137
/// Otherwise, return `None`.
136-
pub fn to_static(self) -> Option<Event<'static, T>> {
138+
pub fn to_static(self) -> Option<Event<T>> {
137139
use self::Event::*;
138140
match self {
139141
WindowEvent { window_id, event } => event
@@ -180,7 +182,7 @@ pub enum StartCause {
180182

181183
/// Describes an event from a `Window`.
182184
#[derive(Debug, PartialEq)]
183-
pub enum WindowEvent<'a> {
185+
pub enum WindowEvent {
184186
/// The size of the window has changed. Contains the client area's new dimensions.
185187
Resized(PhysicalSize<u32>),
186188

@@ -305,10 +307,7 @@ pub enum WindowEvent<'a> {
305307
/// by the OS, but it can be changed to any value.
306308
///
307309
/// For more information about DPI in general, see the [`dpi`](crate::dpi) module.
308-
ScaleFactorChanged {
309-
scale_factor: f64,
310-
new_inner_size: &'a mut PhysicalSize<u32>,
311-
},
310+
ScaleFactorChanged(ScaleFactorChangedState),
312311

313312
/// The system window theme has changed.
314313
///
@@ -319,8 +318,38 @@ pub enum WindowEvent<'a> {
319318
ThemeChanged(Theme),
320319
}
321320

322-
impl<'a> WindowEvent<'a> {
323-
pub fn to_static(self) -> Option<WindowEvent<'static>> {
321+
use std::sync::Arc;
322+
use std::sync::Mutex;
323+
324+
#[derive(Debug)]
325+
pub struct ScaleFactorChangedState {
326+
pub scale_factor: f64,
327+
pub(crate) new_inner_size: Arc<Mutex<PhysicalSize<u32>>>,
328+
}
329+
330+
impl PartialEq<ScaleFactorChangedState> for ScaleFactorChangedState {
331+
fn eq(&self, other: &ScaleFactorChangedState) -> bool {
332+
use std::ops::Deref;
333+
334+
self.scale_factor == other.scale_factor
335+
&& self.new_inner_size.lock().unwrap().deref()
336+
== other.new_inner_size.lock().unwrap().deref()
337+
}
338+
}
339+
340+
impl ScaleFactorChangedState {
341+
pub fn inner_size(&self) -> PhysicalSize<u32> {
342+
*self.new_inner_size.lock().unwrap()
343+
}
344+
345+
pub fn set_inner_size(&self, new_size: PhysicalSize<u32>) {
346+
*self.new_inner_size.lock().unwrap() = new_size;
347+
}
348+
}
349+
350+
impl WindowEvent {
351+
// TODO remove?
352+
pub fn to_static(self) -> Option<WindowEvent> {
324353
use self::WindowEvent::*;
325354
match self {
326355
Resized(size) => Some(Resized(size)),

src/event_loop.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ impl<T> EventLoop<T> {
143143
#[inline]
144144
pub fn run<F>(self, event_handler: F) -> !
145145
where
146-
F: 'static + FnMut(Event<'_, T>, &EventLoopWindowTarget<T>, &mut ControlFlow),
146+
F: 'static + FnMut(Event<T>, &EventLoopWindowTarget<T>, &mut ControlFlow),
147147
{
148148
self.event_loop.run(event_handler)
149149
}

src/platform/desktop.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
#![cfg(any(
22
target_os = "windows",
33
target_os = "macos",
4-
target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"
4+
target_os = "linux",
5+
target_os = "dragonfly",
6+
target_os = "freebsd",
7+
target_os = "netbsd",
8+
target_os = "openbsd"
59
))]
610

711
use crate::{
@@ -30,23 +34,15 @@ pub trait EventLoopExtDesktop {
3034
/// You are strongly encouraged to use `run`, unless the use of this is absolutely necessary.
3135
fn run_return<F>(&mut self, event_handler: F)
3236
where
33-
F: FnMut(
34-
Event<'_, Self::UserEvent>,
35-
&EventLoopWindowTarget<Self::UserEvent>,
36-
&mut ControlFlow,
37-
);
37+
F: FnMut(Event<Self::UserEvent>, &EventLoopWindowTarget<Self::UserEvent>, &mut ControlFlow);
3838
}
3939

4040
impl<T> EventLoopExtDesktop for EventLoop<T> {
4141
type UserEvent = T;
4242

4343
fn run_return<F>(&mut self, event_handler: F)
4444
where
45-
F: FnMut(
46-
Event<'_, Self::UserEvent>,
47-
&EventLoopWindowTarget<Self::UserEvent>,
48-
&mut ControlFlow,
49-
),
45+
F: FnMut(Event<Self::UserEvent>, &EventLoopWindowTarget<Self::UserEvent>, &mut ControlFlow),
5046
{
5147
self.event_loop.run_return(event_handler)
5248
}

src/platform_impl/windows/drop_handler.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pub struct FileDropHandlerData {
3131
pub interface: IDropTarget,
3232
refcount: AtomicUsize,
3333
window: HWND,
34-
send_event: Box<dyn Fn(Event<'static, ()>)>,
34+
send_event: Box<dyn Fn(Event<()>)>,
3535
cursor_effect: DWORD,
3636
hovered_is_valid: bool, /* If the currently hovered item is not valid there must not be any `HoveredFileCancelled` emitted */
3737
}
@@ -42,7 +42,7 @@ pub struct FileDropHandler {
4242

4343
#[allow(non_snake_case)]
4444
impl FileDropHandler {
45-
pub fn new(window: HWND, send_event: Box<dyn Fn(Event<'static, ()>)>) -> FileDropHandler {
45+
pub fn new(window: HWND, send_event: Box<dyn Fn(Event<()>)>) -> FileDropHandler {
4646
let data = Box::new(FileDropHandlerData {
4747
interface: IDropTarget {
4848
lpVtbl: &DROP_TARGET_VTBL as *const IDropTargetVtbl,
@@ -227,7 +227,7 @@ impl FileDropHandler {
227227
}
228228

229229
impl FileDropHandlerData {
230-
fn send_event(&self, event: Event<'static, ()>) {
230+
fn send_event(&self, event: Event<()>) {
231231
(self.send_event)(event);
232232
}
233233
}

src/platform_impl/windows/event_loop.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ use winapi::{
4444
use self::runner::{ELRShared, EventLoopRunnerShared};
4545
use crate::{
4646
dpi::{PhysicalPosition, PhysicalSize},
47-
event::{DeviceEvent, Event, Force, KeyboardInput, Touch, TouchPhase, WindowEvent},
47+
event::{
48+
DeviceEvent, Event, Force, KeyboardInput, ScaleFactorChangedState, Touch, TouchPhase,
49+
WindowEvent,
50+
},
4851
event_loop::{ControlFlow, EventLoopClosed, EventLoopWindowTarget as RootELW},
4952
platform_impl::platform::{
5053
dark_mode::try_dark_mode,
@@ -100,7 +103,7 @@ pub(crate) struct SubclassInput<T: 'static> {
100103
}
101104

102105
impl<T> SubclassInput<T> {
103-
unsafe fn send_event(&self, event: Event<'_, T>) {
106+
unsafe fn send_event(&self, event: Event<T>) {
104107
self.event_loop_runner.send_event(event);
105108
}
106109
}
@@ -112,7 +115,7 @@ struct ThreadMsgTargetSubclassInput<T: 'static> {
112115
}
113116

114117
impl<T> ThreadMsgTargetSubclassInput<T> {
115-
unsafe fn send_event(&self, event: Event<'_, T>) {
118+
unsafe fn send_event(&self, event: Event<T>) {
116119
self.event_loop_runner.send_event(event);
117120
}
118121
}
@@ -187,15 +190,15 @@ impl<T: 'static> EventLoop<T> {
187190

188191
pub fn run<F>(mut self, event_handler: F) -> !
189192
where
190-
F: 'static + FnMut(Event<'_, T>, &RootELW<T>, &mut ControlFlow),
193+
F: 'static + FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
191194
{
192195
self.run_return(event_handler);
193196
::std::process::exit(0);
194197
}
195198

196199
pub fn run_return<F>(&mut self, mut event_handler: F)
197200
where
198-
F: FnMut(Event<'_, T>, &RootELW<T>, &mut ControlFlow),
201+
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
199202
{
200203
let event_loop_windows_ref = &self.window_target;
201204

@@ -1512,7 +1515,7 @@ unsafe extern "system" fn public_window_callback<T: 'static>(
15121515

15131516
// `allow_resize` prevents us from re-applying DPI adjustment to the restored size after
15141517
// exiting fullscreen (the restored size is already DPI adjusted).
1515-
let mut new_physical_inner_size = match allow_resize {
1518+
let new_physical_inner_size = match allow_resize {
15161519
// We calculate our own size because the default suggested rect doesn't do a great job
15171520
// of preserving the window's logical size.
15181521
true => old_physical_inner_size
@@ -1521,14 +1524,18 @@ unsafe extern "system" fn public_window_callback<T: 'static>(
15211524
false => old_physical_inner_size,
15221525
};
15231526

1527+
let cell = std::sync::Arc::new(std::sync::Mutex::new(new_physical_inner_size));
1528+
15241529
let _ = subclass_input.send_event(Event::WindowEvent {
15251530
window_id: RootWindowId(WindowId(window)),
1526-
event: ScaleFactorChanged {
1531+
event: ScaleFactorChanged(ScaleFactorChangedState {
15271532
scale_factor: new_dpi_factor,
1528-
new_inner_size: &mut new_physical_inner_size,
1529-
},
1533+
new_inner_size: cell.clone(),
1534+
}),
15301535
});
15311536

1537+
let new_physical_inner_size = *std::ops::Deref::deref(&cell.lock().unwrap());
1538+
15321539
// Unset maximized if we're changing the window's size.
15331540
if new_physical_inner_size != old_physical_inner_size {
15341541
WindowState::set_window_flags(subclass_input.window_state.lock(), window, |f| {

0 commit comments

Comments
 (0)