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:
parent
cbf61e5cb9
commit
b16042a047
6 changed files with 267 additions and 117 deletions
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue