Add the ability to open a window on a given screen

This is done by supplying the screen in the `WindowOptions` struct.
Note that it's optional, and we will let the operating system choose
which screen to show the window on when `screen` is not provided, as
we did before this change.
This commit is contained in:
Antonio Scandurra 2022-10-26 12:04:45 +02:00
parent 509c327b3b
commit 5a8061ac7b
6 changed files with 73 additions and 17 deletions

View file

@ -1,10 +1,9 @@
use super::{
event::key_to_native, status_item::StatusItem, BoolExt as _, Dispatcher, FontSystem, Window,
event::key_to_native, screen::Screen, status_item::StatusItem, BoolExt as _, Dispatcher,
FontSystem, Window,
};
use crate::{
executor,
geometry::vector::{vec2f, Vector2F},
keymap,
executor, keymap,
platform::{self, CursorStyle},
Action, AppVersion, ClipboardItem, Event, Menu, MenuItem,
};
@ -14,7 +13,7 @@ use cocoa::{
appkit::{
NSApplication, NSApplicationActivationPolicy::NSApplicationActivationPolicyRegular,
NSEventModifierFlags, NSMenu, NSMenuItem, NSModalResponse, NSOpenPanel, NSPasteboard,
NSPasteboardTypeString, NSSavePanel, NSScreen, NSWindow,
NSPasteboardTypeString, NSSavePanel, NSWindow,
},
base::{id, nil, selector, YES},
foundation::{
@ -488,12 +487,11 @@ impl platform::Platform for MacPlatform {
}
}
fn screen_size(&self) -> Vector2F {
unsafe {
let screen = NSScreen::mainScreen(nil);
let frame = NSScreen::frame(screen);
vec2f(frame.size.width as f32, frame.size.height as f32)
}
fn screens(&self) -> Vec<Rc<dyn platform::Screen>> {
Screen::all()
.into_iter()
.map(|screen| Rc::new(screen) as Rc<_>)
.collect()
}
fn open_window(

View file

@ -0,0 +1,44 @@
use std::any::Any;
use crate::{
geometry::vector::{vec2f, Vector2F},
platform,
};
use cocoa::{
appkit::NSScreen,
base::{id, nil},
foundation::NSArray,
};
#[derive(Debug)]
pub struct Screen {
pub(crate) native_screen: id,
}
impl Screen {
pub fn all() -> Vec<Self> {
let mut screens = Vec::new();
unsafe {
let native_screens = NSScreen::screens(nil);
for ix in 0..native_screens.count() {
screens.push(Screen {
native_screen: native_screens.objectAtIndex(ix),
});
}
}
screens
}
}
impl platform::Screen for Screen {
fn as_any(&self) -> &dyn Any {
self
}
fn size(&self) -> Vector2F {
unsafe {
let frame = self.native_screen.frame();
vec2f(frame.size.width as f32, frame.size.height as f32)
}
}
}

View file

@ -8,7 +8,7 @@ use crate::{
mac::platform::NSViewLayerContentsRedrawDuringViewResize,
platform::{
self,
mac::{geometry::RectFExt, renderer::Renderer},
mac::{geometry::RectFExt, renderer::Renderer, screen::Screen},
Event, WindowBounds,
},
InputHandler, KeyDownEvent, ModifiersChangedEvent, MouseButton, MouseButtonEvent,
@ -377,11 +377,17 @@ impl Window {
msg_send![PANEL_CLASS, alloc]
}
};
let native_window = native_window.initWithContentRect_styleMask_backing_defer_(
let native_window = native_window.initWithContentRect_styleMask_backing_defer_screen_(
RectF::new(Default::default(), vec2f(1024., 768.)).to_ns_rect(),
style_mask,
NSBackingStoreBuffered,
NO,
options
.screen
.and_then(|screen| {
Some(screen.as_any().downcast_ref::<Screen>()?.native_screen)
})
.unwrap_or(nil),
);
assert!(!native_window.is_null());