macOS: Dpi overhaul (#997) (and rebase changes)

* 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

Changes from rebasing:

* fixes compile errors

* applies fmt

* reimplements HiDpiFactorChanged after #1173 merge

* uses EventWrappers
This commit is contained in:
Vladimir Bogaevsky 2020-01-04 01:32:34 -05:00 committed by Osspial
parent 7b43b0bc94
commit 077ee4d851
10 changed files with 273 additions and 153 deletions

View file

@ -19,6 +19,7 @@ use crate::{
event::{Event, WindowEvent},
platform_impl::platform::{
app_state::AppState,
event::{EventProxy, EventWrapper},
util::{self, IdRef},
window::{get_window_id, UnownedWindow},
},
@ -47,20 +48,18 @@ pub struct WindowDelegateState {
impl WindowDelegateState {
pub fn new(window: &Arc<UnownedWindow>, initial_fullscreen: bool) -> Self {
let dpi_factor = window.hidpi_factor();
let hidpi_factor = window.hidpi_factor();
let mut delegate_state = WindowDelegateState {
ns_window: window.ns_window.clone(),
ns_view: window.ns_view.clone(),
window: Arc::downgrade(&window),
initial_fullscreen,
previous_position: None,
previous_dpi_factor: dpi_factor,
previous_dpi_factor: hidpi_factor,
};
if dpi_factor != 1.0 {
delegate_state.emit_event(WindowEvent::HiDpiFactorChanged(dpi_factor));
delegate_state.emit_resize_event();
if hidpi_factor != 1.0 {
delegate_state.emit_static_hidpi_factor_changed_event();
}
delegate_state
@ -73,17 +72,34 @@ impl WindowDelegateState {
self.window.upgrade().map(|ref window| callback(window))
}
pub fn emit_event(&mut self, event: WindowEvent) {
pub fn emit_event(&mut self, event: WindowEvent<'static>) {
let event = Event::WindowEvent {
window_id: WindowId(get_window_id(*self.ns_window)),
event,
};
AppState::queue_event(event);
AppState::queue_event(EventWrapper::StaticEvent(event));
}
pub fn emit_static_hidpi_factor_changed_event(&mut self) {
let hidpi_factor = self.get_hidpi_factor();
if hidpi_factor == self.previous_dpi_factor {
return ();
};
self.previous_dpi_factor = hidpi_factor;
let wrapper = EventWrapper::EventProxy(EventProxy::HiDpiFactorChangedProxy {
ns_window: IdRef::retain(*self.ns_window),
suggested_size: self.view_size(),
hidpi_factor,
});
AppState::queue_event(wrapper);
}
pub fn emit_resize_event(&mut self) {
let rect = unsafe { NSView::frame(*self.ns_view) };
let size = LogicalSize::new(rect.size.width as f64, rect.size.height as f64);
let hidpi_factor = self.get_hidpi_factor();
let logical_size = LogicalSize::new(rect.size.width as f64, rect.size.height as f64);
let size = logical_size.to_physical(hidpi_factor);
self.emit_event(WindowEvent::Resized(size));
}
@ -97,6 +113,15 @@ impl WindowDelegateState {
self.emit_event(WindowEvent::Moved((x, y).into()));
}
}
fn get_hidpi_factor(&self) -> f64 {
(unsafe { NSWindow::backingScaleFactor(*self.ns_window) }) as f64
}
fn view_size(&self) -> LogicalSize {
let ns_size = unsafe { NSView::frame(*self.ns_view).size };
LogicalSize::new(ns_size.width as f64, ns_size.height as f64)
}
}
pub fn new_delegate(window: &Arc<UnownedWindow>, initial_fullscreen: bool) -> IdRef {
@ -140,10 +165,6 @@ lazy_static! {
sel!(windowDidMove:),
window_did_move as extern "C" fn(&Object, Sel, id),
);
decl.add_method(
sel!(windowDidChangeScreen:),
window_did_change_screen as extern "C" fn(&Object, Sel, id),
);
decl.add_method(
sel!(windowDidChangeBackingProperties:),
window_did_change_backing_properties as extern "C" fn(&Object, Sel, id),
@ -277,29 +298,10 @@ extern "C" fn window_did_move(this: &Object, _: Sel, _: id) {
trace!("Completed `windowDidMove:`");
}
extern "C" fn window_did_change_screen(this: &Object, _: Sel, _: id) {
trace!("Triggered `windowDidChangeScreen:`");
with_state(this, |state| {
let dpi_factor = unsafe { NSWindow::backingScaleFactor(*state.ns_window) } as f64;
if state.previous_dpi_factor != dpi_factor {
state.previous_dpi_factor = dpi_factor;
state.emit_event(WindowEvent::HiDpiFactorChanged(dpi_factor));
state.emit_resize_event();
}
});
trace!("Completed `windowDidChangeScreen:`");
}
// This will always be called before `window_did_change_screen`.
extern "C" fn window_did_change_backing_properties(this: &Object, _: Sel, _: id) {
trace!("Triggered `windowDidChangeBackingProperties:`");
with_state(this, |state| {
let dpi_factor = unsafe { NSWindow::backingScaleFactor(*state.ns_window) } as f64;
if state.previous_dpi_factor != dpi_factor {
state.previous_dpi_factor = dpi_factor;
state.emit_event(WindowEvent::HiDpiFactorChanged(dpi_factor));
state.emit_resize_event();
}
state.emit_static_hidpi_factor_changed_event();
});
trace!("Completed `windowDidChangeBackingProperties:`");
}