Skip to content

Commit 750e916

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 6f5e7e1 commit 750e916

15 files changed

+424
-372
lines changed

examples/multithreaded.rs

+18-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, Fullscreen, 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

@@ -99,7 +100,7 @@ fn main() {
99100
println!("-> fullscreen : {:?}", window.fullscreen());
100101
}
101102
L => window.set_min_inner_size(match state {
102-
true => Some(WINDOW_SIZE.into()),
103+
true => Some(WINDOW_SIZE),
103104
false => None,
104105
}),
105106
M => window.set_maximized(state),
@@ -112,17 +113,18 @@ fn main() {
112113
}),
113114
Q => window.request_redraw(),
114115
R => window.set_resizable(state),
115-
S => window.set_inner_size(
116-
match state {
117-
true => (WINDOW_SIZE.0 + 100, WINDOW_SIZE.1 + 100),
118-
false => WINDOW_SIZE,
119-
}
120-
.into(),
121-
),
116+
S => window.set_inner_size(match state {
117+
true => PhysicalSize::new(
118+
WINDOW_SIZE.width + 100,
119+
WINDOW_SIZE.height + 100,
120+
),
121+
false => WINDOW_SIZE,
122+
}),
122123
W => window
123-
.set_cursor_position(
124-
(WINDOW_SIZE.0 as i32 / 2, WINDOW_SIZE.1 as i32 / 2).into(),
125-
)
124+
.set_cursor_position(PhysicalPosition::new(
125+
WINDOW_SIZE.width as f64 / 2.0,
126+
WINDOW_SIZE.height as f64 / 2.0,
127+
))
126128
.unwrap(),
127129
Z => {
128130
window.set_visible(false);
@@ -159,7 +161,9 @@ fn main() {
159161
}
160162
_ => {
161163
if let Some(tx) = window_senders.get(&window_id) {
162-
tx.send(event).unwrap();
164+
if let Some(event) = event.to_static() {
165+
tx.send(event).unwrap();
166+
}
163167
}
164168
}
165169
},

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)