Skip to content

Commit da2611e

Browse files
committed
WIP - Make EL2 DPI changes and implement on Windows (#895)
* Modify DPI API publicly and on Windows * Add generic Position and make dpi creation functions const * Make examples work * Fix fullscreen windows not appearing * Replace Logical coordinates in window events with Physical coordinates * Update HiDpiFactorChanged * Document to_static
1 parent 8d6e8bb commit da2611e

15 files changed

+427
-363
lines changed

examples/multithreaded.rs

+20-14
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,22 @@ extern crate env_logger;
22
use std::{collections::HashMap, sync::mpsc, thread, time::Duration};
33

44
use winit::{
5+
dpi::{PhysicalPosition, PhysicalSize},
56
event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent},
67
event_loop::{ControlFlow, EventLoop},
78
window::{CursorIcon, WindowBuilder},
89
};
910

1011
const WINDOW_COUNT: usize = 3;
11-
const WINDOW_SIZE: (u32, u32) = (600, 400);
12+
const WINDOW_SIZE: PhysicalSize = PhysicalSize::new(600, 400);
1213

1314
fn main() {
1415
env_logger::init();
1516
let event_loop = EventLoop::new();
1617
let mut window_senders = HashMap::with_capacity(WINDOW_COUNT);
1718
for _ in 0..WINDOW_COUNT {
1819
let window = WindowBuilder::new()
19-
.with_inner_size(WINDOW_SIZE.into())
20+
.with_inner_size(WINDOW_SIZE)
2021
.build(&event_loop)
2122
.unwrap();
2223
let (tx, rx) = mpsc::channel();
@@ -63,7 +64,7 @@ fn main() {
6364
},
6465
L => {
6566
window.set_min_inner_size(match state {
66-
true => Some(WINDOW_SIZE.into()),
67+
true => Some(WINDOW_SIZE),
6768
false => None,
6869
})
6970
},
@@ -80,19 +81,22 @@ fn main() {
8081
Q => window.request_redraw(),
8182
R => window.set_resizable(state),
8283
S => {
83-
window.set_inner_size(
84-
match state {
85-
true => (WINDOW_SIZE.0 + 100, WINDOW_SIZE.1 + 100),
86-
false => WINDOW_SIZE,
87-
}
88-
.into(),
89-
)
84+
window.set_inner_size(match state {
85+
true => {
86+
PhysicalSize::new(
87+
WINDOW_SIZE.width + 100,
88+
WINDOW_SIZE.height + 100,
89+
)
90+
},
91+
false => WINDOW_SIZE,
92+
})
9093
},
9194
W => {
9295
window
93-
.set_cursor_position(
94-
(WINDOW_SIZE.0 as i32 / 2, WINDOW_SIZE.1 as i32 / 2).into(),
95-
)
96+
.set_cursor_position(PhysicalPosition::new(
97+
WINDOW_SIZE.width as f64 / 2.0,
98+
WINDOW_SIZE.height as f64 / 2.0,
99+
))
96100
.unwrap()
97101
},
98102
Z => {
@@ -130,7 +134,9 @@ fn main() {
130134
},
131135
_ => {
132136
if let Some(tx) = window_senders.get(&window_id) {
133-
tx.send(event).unwrap();
137+
if let Some(event) = event.to_static() {
138+
tx.send(event).unwrap();
139+
}
134140
}
135141
},
136142
}

examples/resizable.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use winit::{
2+
dpi::LogicalSize,
23
event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent},
34
event_loop::{ControlFlow, EventLoop},
45
window::WindowBuilder,
@@ -11,7 +12,7 @@ fn main() {
1112

1213
let window = WindowBuilder::new()
1314
.with_title("Hit space to toggle resizability.")
14-
.with_inner_size((400, 200).into())
15+
.with_inner_size(LogicalSize::new(400.0, 200.0))
1516
.with_resizable(resizable)
1617
.build(&event_loop)
1718
.unwrap();

examples/window.rs

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ fn main() {
99

1010
let window = WindowBuilder::new()
1111
.with_title("A fantastic window!")
12+
.with_inner_size(winit::dpi::LogicalSize::new(128.0, 128.0))
1213
.build(&event_loop)
1314
.unwrap();
1415

src/dpi.rs

+90-26
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ pub struct LogicalPosition {
9999

100100
impl LogicalPosition {
101101
#[inline]
102-
pub fn new(x: f64, y: f64) -> Self {
102+
pub const fn new(x: f64, y: f64) -> Self {
103103
LogicalPosition { x, y }
104104
}
105105

@@ -160,7 +160,7 @@ pub struct PhysicalPosition {
160160

161161
impl PhysicalPosition {
162162
#[inline]
163-
pub fn new(x: f64, y: f64) -> Self {
163+
pub const fn new(x: f64, y: f64) -> Self {
164164
PhysicalPosition { x, y }
165165
}
166166

@@ -221,7 +221,7 @@ pub struct LogicalSize {
221221

222222
impl LogicalSize {
223223
#[inline]
224-
pub fn new(width: f64, height: f64) -> Self {
224+
pub const fn new(width: f64, height: f64) -> Self {
225225
LogicalSize { width, height }
226226
}
227227

@@ -235,7 +235,7 @@ impl LogicalSize {
235235
assert!(validate_hidpi_factor(dpi_factor));
236236
let width = self.width * dpi_factor;
237237
let height = self.height * dpi_factor;
238-
PhysicalSize::new(width, height)
238+
PhysicalSize::new(width.round() as _, height.round() as _)
239239
}
240240
}
241241

@@ -269,20 +269,16 @@ impl Into<(u32, u32)> for LogicalSize {
269269
}
270270

271271
/// A size represented in physical pixels.
272-
///
273-
/// The size is stored as floats, so please be careful. Casting floats to integers truncates the fractional part,
274-
/// which can cause noticable issues. To help with that, an `Into<(u32, u32)>` implementation is provided which
275-
/// does the rounding for you.
276-
#[derive(Debug, Copy, Clone, PartialEq)]
272+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
277273
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
278274
pub struct PhysicalSize {
279-
pub width: f64,
280-
pub height: f64,
275+
pub width: u32,
276+
pub height: u32,
281277
}
282278

283279
impl PhysicalSize {
284280
#[inline]
285-
pub fn new(width: f64, height: f64) -> Self {
281+
pub const fn new(width: u32, height: u32) -> Self {
286282
PhysicalSize { width, height }
287283
}
288284

@@ -294,37 +290,105 @@ impl PhysicalSize {
294290
#[inline]
295291
pub fn to_logical(&self, dpi_factor: f64) -> LogicalSize {
296292
assert!(validate_hidpi_factor(dpi_factor));
297-
let width = self.width / dpi_factor;
298-
let height = self.height / dpi_factor;
293+
let width = self.width as f64 / dpi_factor;
294+
let height = self.height as f64 / dpi_factor;
299295
LogicalSize::new(width, height)
300296
}
301297
}
302298

303-
impl From<(f64, f64)> for PhysicalSize {
299+
impl From<(u32, u32)> for PhysicalSize {
304300
#[inline]
305-
fn from((width, height): (f64, f64)) -> Self {
301+
fn from((width, height): (u32, u32)) -> Self {
306302
Self::new(width, height)
307303
}
308304
}
309305

310-
impl From<(u32, u32)> for PhysicalSize {
306+
impl Into<(u32, u32)> for PhysicalSize {
307+
/// Note that this rounds instead of truncating.
311308
#[inline]
312-
fn from((width, height): (u32, u32)) -> Self {
313-
Self::new(width as f64, height as f64)
309+
fn into(self) -> (u32, u32) {
310+
(self.width, self.height)
314311
}
315312
}
316313

317-
impl Into<(f64, f64)> for PhysicalSize {
314+
#[derive(Debug, Copy, Clone, PartialEq)]
315+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
316+
pub enum Size {
317+
Physical(PhysicalSize),
318+
Logical(LogicalSize),
319+
}
320+
321+
impl Size {
322+
pub fn new<S: Into<Size>>(size: S) -> Size {
323+
size.into()
324+
}
325+
326+
pub fn to_logical(&self, dpi_factor: f64) -> LogicalSize {
327+
match *self {
328+
Size::Physical(size) => size.to_logical(dpi_factor),
329+
Size::Logical(size) => size,
330+
}
331+
}
332+
333+
pub fn to_physical(&self, dpi_factor: f64) -> PhysicalSize {
334+
match *self {
335+
Size::Physical(size) => size,
336+
Size::Logical(size) => size.to_physical(dpi_factor),
337+
}
338+
}
339+
}
340+
341+
impl From<PhysicalSize> for Size {
318342
#[inline]
319-
fn into(self) -> (f64, f64) {
320-
(self.width, self.height)
343+
fn from(size: PhysicalSize) -> Size {
344+
Size::Physical(size)
321345
}
322346
}
323347

324-
impl Into<(u32, u32)> for PhysicalSize {
325-
/// Note that this rounds instead of truncating.
348+
impl From<LogicalSize> for Size {
326349
#[inline]
327-
fn into(self) -> (u32, u32) {
328-
(self.width.round() as _, self.height.round() as _)
350+
fn from(size: LogicalSize) -> Size {
351+
Size::Logical(size)
352+
}
353+
}
354+
355+
#[derive(Debug, Copy, Clone, PartialEq)]
356+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
357+
pub enum Position {
358+
Physical(PhysicalPosition),
359+
Logical(LogicalPosition),
360+
}
361+
362+
impl Position {
363+
pub fn new<S: Into<Position>>(position: S) -> Position {
364+
position.into()
365+
}
366+
367+
pub fn to_logical(&self, dpi_factor: f64) -> LogicalPosition {
368+
match *self {
369+
Position::Physical(position) => position.to_logical(dpi_factor),
370+
Position::Logical(position) => position,
371+
}
372+
}
373+
374+
pub fn to_physical(&self, dpi_factor: f64) -> PhysicalPosition {
375+
match *self {
376+
Position::Physical(position) => position,
377+
Position::Logical(position) => position.to_physical(dpi_factor),
378+
}
379+
}
380+
}
381+
382+
impl From<PhysicalPosition> for Position {
383+
#[inline]
384+
fn from(position: PhysicalPosition) -> Position {
385+
Position::Physical(position)
386+
}
387+
}
388+
389+
impl From<LogicalPosition> for Position {
390+
#[inline]
391+
fn from(position: LogicalPosition) -> Position {
392+
Position::Logical(position)
329393
}
330394
}

0 commit comments

Comments
 (0)