Skip to content

Commit 07b8f01

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 b1b5aef commit 07b8f01

15 files changed

+351
-343
lines changed

examples/multithreaded.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,21 @@ extern crate winit;
44
use std::{collections::HashMap, sync::mpsc, thread, time::Duration};
55

66
use winit::{
7+
dpi::{PhysicalPosition, PhysicalSize},
78
event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent},
89
event_loop::{ControlFlow, EventLoop}, window::{CursorIcon, WindowBuilder},
910
};
1011

1112
const WINDOW_COUNT: usize = 3;
12-
const WINDOW_SIZE: (u32, u32) = (600, 400);
13+
const WINDOW_SIZE: PhysicalSize = PhysicalSize::new(600, 400);
1314

1415
fn main() {
1516
env_logger::init();
1617
let event_loop = EventLoop::new();
1718
let mut window_senders = HashMap::with_capacity(WINDOW_COUNT);
1819
for _ in 0..WINDOW_COUNT {
1920
let window = WindowBuilder::new()
20-
.with_inner_size(WINDOW_SIZE.into())
21+
.with_inner_size(WINDOW_SIZE)
2122
.build(&event_loop)
2223
.unwrap();
2324
let (tx, rx) = mpsc::channel();
@@ -55,7 +56,7 @@ fn main() {
5556
println!("-> inner_size : {:?}", window.inner_size());
5657
},
5758
L => window.set_min_inner_size(match state {
58-
true => Some(WINDOW_SIZE.into()),
59+
true => Some(WINDOW_SIZE),
5960
false => None,
6061
}),
6162
M => window.set_maximized(state),
@@ -69,13 +70,13 @@ fn main() {
6970
Q => window.request_redraw(),
7071
R => window.set_resizable(state),
7172
S => window.set_inner_size(match state {
72-
true => (WINDOW_SIZE.0 + 100, WINDOW_SIZE.1 + 100),
73+
true => PhysicalSize::new(WINDOW_SIZE.width + 100, WINDOW_SIZE.height + 100),
7374
false => WINDOW_SIZE,
74-
}.into()),
75-
W => window.set_cursor_position((
76-
WINDOW_SIZE.0 as i32 / 2,
77-
WINDOW_SIZE.1 as i32 / 2,
78-
).into()).unwrap(),
75+
}),
76+
W => window.set_cursor_position(PhysicalPosition::new(
77+
WINDOW_SIZE.width as f64 / 2.0,
78+
WINDOW_SIZE.height as f64 / 2.0,
79+
)).unwrap(),
7980
Z => {
8081
window.set_visible(false);
8182
thread::sleep(Duration::from_secs(1));
@@ -105,7 +106,9 @@ fn main() {
105106
window_senders.remove(&window_id);
106107
},
107108
_ => if let Some(tx) = window_senders.get(&window_id) {
108-
tx.send(event).unwrap();
109+
if let Some(event) = event.to_static() {
110+
tx.send(event).unwrap();
111+
}
109112
},
110113
}
111114
}

examples/resizable.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
extern crate winit;
22
use winit::window::WindowBuilder;
3+
use winit::dpi::LogicalSize;
34
use winit::event::{Event, WindowEvent, VirtualKeyCode, ElementState, KeyboardInput};
45
use winit::event_loop::{EventLoop, ControlFlow};
56

@@ -10,7 +11,7 @@ fn main() {
1011

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

examples/window.rs

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

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

src/dpi.rs

+91-26
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ pub struct LogicalPosition {
100100

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

@@ -161,7 +161,7 @@ pub struct PhysicalPosition {
161161

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

@@ -222,7 +222,7 @@ pub struct LogicalSize {
222222

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

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

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

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

284280
impl PhysicalSize {
285281
#[inline]
286-
pub fn new(width: f64, height: f64) -> Self {
282+
pub const fn new(width: u32, height: u32) -> Self {
287283
PhysicalSize { width, height }
288284
}
289285

@@ -295,37 +291,106 @@ impl PhysicalSize {
295291
#[inline]
296292
pub fn to_logical(&self, dpi_factor: f64) -> LogicalSize {
297293
assert!(validate_hidpi_factor(dpi_factor));
298-
let width = self.width / dpi_factor;
299-
let height = self.height / dpi_factor;
294+
let width = self.width as f64 / dpi_factor;
295+
let height = self.height as f64 / dpi_factor;
300296
LogicalSize::new(width, height)
301297
}
302298
}
303299

304-
impl From<(f64, f64)> for PhysicalSize {
300+
impl From<(u32, u32)> for PhysicalSize {
305301
#[inline]
306-
fn from((width, height): (f64, f64)) -> Self {
302+
fn from((width, height): (u32, u32)) -> Self {
307303
Self::new(width, height)
308304
}
309305
}
310306

311-
impl From<(u32, u32)> for PhysicalSize {
307+
impl Into<(u32, u32)> for PhysicalSize {
308+
/// Note that this rounds instead of truncating.
312309
#[inline]
313-
fn from((width, height): (u32, u32)) -> Self {
314-
Self::new(width as f64, height as f64)
310+
fn into(self) -> (u32, u32) {
311+
(self.width, self.height)
312+
}
313+
}
314+
315+
#[derive(Debug, Copy, Clone, PartialEq)]
316+
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
317+
pub enum Size {
318+
Physical(PhysicalSize),
319+
Logical(LogicalSize),
320+
}
321+
322+
impl Size {
323+
pub fn new<S: Into<Size>>(size: S) -> Size {
324+
size.into()
325+
}
326+
327+
pub fn to_logical(&self, dpi_factor: f64) -> LogicalSize {
328+
match *self {
329+
Size::Physical(size) => size.to_logical(dpi_factor),
330+
Size::Logical(size) => size,
331+
}
332+
}
333+
334+
pub fn to_physical(&self, dpi_factor: f64) -> PhysicalSize {
335+
match *self {
336+
Size::Physical(size) => size,
337+
Size::Logical(size) => size.to_physical(dpi_factor),
338+
}
315339
}
316340
}
317341

318-
impl Into<(f64, f64)> for PhysicalSize {
342+
impl From<PhysicalSize> for Size {
319343
#[inline]
320-
fn into(self) -> (f64, f64) {
321-
(self.width, self.height)
344+
fn from(size: PhysicalSize) -> Size {
345+
Size::Physical(size)
322346
}
323347
}
324348

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

0 commit comments

Comments
 (0)