iOS: Dpi overhaul (#1223)

* 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

* On Windows, make AdjustRect calls DPI-aware when possible (#1015)

* Use AdjustWidowRectExForDPI when available

* Prioritize presevering logical size when handling WM_DPICHANGED

* Format

* Add changelog entry

* macOS: Dpi overhaul (#997)

* 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

* fix app_state errors

* fixes hidpi related errors in window_delegate

* fix bad merge

* dpi_factor edits in window_delegate

* fixes type and lifetime errors in window and window_delegate

* applies fmt

* complies with @aleksijuvani requested changes

* modifies Handler lifetimes

* fixes lifetime isues, adds propper handling for HiDpiChanged

* applies fmt

* restore original lifetimes

* solution is somewhere out there

* applies fmt

* pass as references

* resolves issue with HANDLER

* crate visible type error

* fixes visibility issues

* applies fmt

* deals with warnings

* simplifies new_inner_size setting algorthm

* moves proxy instead of referencing it and removes double deref from proxy.ns_window

* makes @Osspial tests (https://github.com/rust-windowing/winit/pull/997\#discussion_r301852354) pass

* complies with @aleksijuvani suggested changes

* makes max window size std::f32::MAX

* On Windows, fix new DPI API not setting window size properly (#1130)

* First attempt

* Second attempt

* Maintain cursor horizontal ratio

* Fix DPI change handling when maximized

* Revert window example

* Make new DPI code more understandable

* Format

* Implement DPI Usability Upgrades for X11 and Wayland (#1098)

* Fix compile errors

* Use `mio` for the X11 event loop

* Removes `calloop` from the X11 event loop, as the method of draining a
  source using a closure provided to the `calloop::EventLoop` instance
  conflicts with the need to deliver events directly to the callback
  provided to `EventLoop::run`, in order to respond to the value provided by
  `WindowEvent::HiDpiFactorChanged`.

* Implement interactive `HiDpiFactorChanged` event for X11

* Implement interactive `HiDpiFactorChanged` event for Wayland

* Run cargo fmt

* Fix Wayland not processing events from EventQueue

* Backport #981

* some lifetime tinkering

* finishes lifetime tinkering

* fixes all type errors

* adds support ffi functions

* adds wrappers for nonstatic events

* replaces events with event wrappers

* reimplementing hidpichanged event in app_state

* implements HiDpiFactorChanged for iOS

* applies formatter

* complies with @aleksijuvani requested changes

* resolves conflicts

* applies fmt

* removes merge blurp

* corrects state of CHANGELOG

* fix fmt check error

* fixes hidpi_factor for armv7-apple-ios
This commit is contained in:
Bogaevsky 2019-10-18 18:31:26 +03:00 committed by Osspial
parent cbf61e5cb9
commit b16042a047
6 changed files with 267 additions and 117 deletions

View file

@ -10,7 +10,7 @@ use crate::{
platform::ios::MonitorHandleExtIOS,
platform_impl::platform::{
app_state::{self, OSCapabilities},
event_loop,
event_loop::{self, EventProxy, EventWrapper},
ffi::{
id, nil, CGFloat, CGPoint, CGRect, UIForceTouchCapability, UIInterfaceOrientationMask,
UIRectEdge, UITouchPhase, UITouchType,
@ -103,8 +103,8 @@ unsafe fn get_view_class(root_view_class: &'static Class) -> &'static Class {
let window: id = msg_send![object, window];
assert!(!window.is_null());
app_state::handle_nonuser_events(
std::iter::once(Event::RedrawRequested(RootWindowId(window.into())))
.chain(std::iter::once(Event::RedrawEventsCleared)),
std::iter::once(EventWrapper::StaticEvent(Event::RedrawRequested(RootWindowId(window.into()))))
.chain(std::iter::once(EventWrapper::StaticEvent(Event::RedrawEventsCleared))),
);
let superclass: &'static Class = msg_send![object, superclass];
let () = msg_send![super(object, superclass), drawRect: rect];
@ -123,14 +123,16 @@ unsafe fn get_view_class(root_view_class: &'static Class) -> &'static Class {
let screen_space: id = msg_send![screen, coordinateSpace];
let screen_frame: CGRect =
msg_send![object, convertRect:bounds toCoordinateSpace:screen_space];
let dpi_factor: CGFloat = msg_send![screen, scale];
let size = crate::dpi::LogicalSize {
width: screen_frame.size.width as _,
height: screen_frame.size.height as _,
};
app_state::handle_nonuser_event(Event::WindowEvent {
}
.to_physical(dpi_factor.into());
app_state::handle_nonuser_event(EventWrapper::StaticEvent(Event::WindowEvent {
window_id: RootWindowId(window.into()),
event: WindowEvent::Resized(size),
});
}));
}
}
@ -156,14 +158,15 @@ unsafe fn get_view_class(root_view_class: &'static Class) -> &'static Class {
// `setContentScaleFactor` may be called with a value of 0, which means "reset the
// content scale factor to a device-specific default value", so we can't use the
// parameter here. We can query the actual factor using the getter
let hidpi_factor: CGFloat = msg_send![object, contentScaleFactor];
let dpi_factor: CGFloat = msg_send![object, contentScaleFactor];
assert!(
!hidpi_factor.is_nan()
&& hidpi_factor.is_finite()
&& hidpi_factor.is_sign_positive()
&& hidpi_factor > 0.0,
!dpi_factor.is_nan()
&& dpi_factor.is_finite()
&& dpi_factor.is_sign_positive()
&& dpi_factor > 0.0,
"invalid hidpi_factor set on UIView",
);
let hidpi_factor: f64 = dpi_factor.into();
let bounds: CGRect = msg_send![object, bounds];
let screen: id = msg_send![window, screen];
let screen_space: id = msg_send![screen, coordinateSpace];
@ -174,14 +177,19 @@ unsafe fn get_view_class(root_view_class: &'static Class) -> &'static Class {
height: screen_frame.size.height as _,
};
app_state::handle_nonuser_events(
std::iter::once(Event::WindowEvent {
window_id: RootWindowId(window.into()),
event: WindowEvent::HiDpiFactorChanged(hidpi_factor as _),
})
.chain(std::iter::once(Event::WindowEvent {
window_id: RootWindowId(window.into()),
event: WindowEvent::Resized(size),
})),
std::iter::once(EventWrapper::EventProxy(
EventProxy::HiDpiFactorChangedProxy {
window_id: window,
hidpi_factor,
suggested_size: size,
},
))
.chain(std::iter::once(EventWrapper::StaticEvent(
Event::WindowEvent {
window_id: RootWindowId(window.into()),
event: WindowEvent::Resized(size.to_physical(hidpi_factor)),
},
))),
);
}
}
@ -238,7 +246,7 @@ unsafe fn get_view_class(root_view_class: &'static Class) -> &'static Class {
_ => panic!("unexpected touch phase: {:?}", phase as i32),
};
touch_events.push(Event::WindowEvent {
touch_events.push(EventWrapper::StaticEvent(Event::WindowEvent {
window_id: RootWindowId(window.into()),
event: WindowEvent::Touch(Touch {
device_id: RootDeviceId(DeviceId { uiscreen }),
@ -247,7 +255,7 @@ unsafe fn get_view_class(root_view_class: &'static Class) -> &'static Class {
force,
phase,
}),
});
}));
}
app_state::handle_nonuser_events(touch_events);
}
@ -367,20 +375,20 @@ unsafe fn get_window_class() -> &'static Class {
extern "C" fn become_key_window(object: &Object, _: Sel) {
unsafe {
app_state::handle_nonuser_event(Event::WindowEvent {
app_state::handle_nonuser_event(EventWrapper::StaticEvent(Event::WindowEvent {
window_id: RootWindowId(object.into()),
event: WindowEvent::Focused(true),
});
}));
let () = msg_send![super(object, class!(UIWindow)), becomeKeyWindow];
}
}
extern "C" fn resign_key_window(object: &Object, _: Sel) {
unsafe {
app_state::handle_nonuser_event(Event::WindowEvent {
app_state::handle_nonuser_event(EventWrapper::StaticEvent(Event::WindowEvent {
window_id: RootWindowId(object.into()),
event: WindowEvent::Focused(false),
});
}));
let () = msg_send![super(object, class!(UIWindow)), resignKeyWindow];
}
}
@ -500,9 +508,7 @@ pub unsafe fn create_window(
let () = msg_send![uiscreen, setCurrentMode: video_mode.video_mode.screen_mode.0];
msg_send![window, setScreen:video_mode.monitor().ui_screen()]
}
Some(Fullscreen::Borderless(ref monitor)) => {
msg_send![window, setScreen:monitor.ui_screen()]
}
Some(Fullscreen::Borderless(ref monitor)) => msg_send![window, setScreen:monitor.ui_screen()],
None => (),
}
@ -518,11 +524,11 @@ pub fn create_delegate_class() {
}
extern "C" fn did_become_active(_: &Object, _: Sel, _: id) {
unsafe { app_state::handle_nonuser_event(Event::Resumed) }
unsafe { app_state::handle_nonuser_event(EventWrapper::StaticEvent(Event::Resumed)) }
}
extern "C" fn will_resign_active(_: &Object, _: Sel, _: id) {
unsafe { app_state::handle_nonuser_event(Event::Suspended) }
unsafe { app_state::handle_nonuser_event(EventWrapper::StaticEvent(Event::Suspended)) }
}
extern "C" fn will_enter_foreground(_: &Object, _: Sel, _: id) {}
@ -541,10 +547,10 @@ pub fn create_delegate_class() {
}
let is_winit_window: BOOL = msg_send![window, isKindOfClass: class!(WinitUIWindow)];
if is_winit_window == YES {
events.push(Event::WindowEvent {
events.push(EventWrapper::StaticEvent(Event::WindowEvent {
window_id: RootWindowId(window.into()),
event: WindowEvent::Destroyed,
});
}));
}
}
app_state::handle_nonuser_events(events);