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:
parent
509c327b3b
commit
5a8061ac7b
6 changed files with 73 additions and 17 deletions
|
@ -25,7 +25,7 @@ use postage::oneshot;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::{
|
use std::{
|
||||||
any::Any,
|
any::Any,
|
||||||
fmt::{self, Display},
|
fmt::{self, Debug, Display},
|
||||||
ops::Range,
|
ops::Range,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
|
@ -44,7 +44,7 @@ pub trait Platform: Send + Sync {
|
||||||
fn unhide_other_apps(&self);
|
fn unhide_other_apps(&self);
|
||||||
fn quit(&self);
|
fn quit(&self);
|
||||||
|
|
||||||
fn screen_size(&self) -> Vector2F;
|
fn screens(&self) -> Vec<Rc<dyn Screen>>;
|
||||||
|
|
||||||
fn open_window(
|
fn open_window(
|
||||||
&self,
|
&self,
|
||||||
|
@ -115,6 +115,11 @@ pub trait InputHandler {
|
||||||
fn rect_for_range(&self, range_utf16: Range<usize>) -> Option<RectF>;
|
fn rect_for_range(&self, range_utf16: Range<usize>) -> Option<RectF>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait Screen: Debug {
|
||||||
|
fn as_any(&self) -> &dyn Any;
|
||||||
|
fn size(&self) -> Vector2F;
|
||||||
|
}
|
||||||
|
|
||||||
pub trait Window {
|
pub trait Window {
|
||||||
fn as_any_mut(&mut self) -> &mut dyn Any;
|
fn as_any_mut(&mut self) -> &mut dyn Any;
|
||||||
fn on_event(&mut self, callback: Box<dyn FnMut(Event) -> bool>);
|
fn on_event(&mut self, callback: Box<dyn FnMut(Event) -> bool>);
|
||||||
|
@ -149,6 +154,7 @@ pub struct WindowOptions<'a> {
|
||||||
pub center: bool,
|
pub center: bool,
|
||||||
pub kind: WindowKind,
|
pub kind: WindowKind,
|
||||||
pub is_movable: bool,
|
pub is_movable: bool,
|
||||||
|
pub screen: Option<Rc<dyn Screen>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -292,6 +298,7 @@ impl<'a> Default for WindowOptions<'a> {
|
||||||
center: false,
|
center: false,
|
||||||
kind: WindowKind::Normal,
|
kind: WindowKind::Normal,
|
||||||
is_movable: true,
|
is_movable: true,
|
||||||
|
screen: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ mod geometry;
|
||||||
mod image_cache;
|
mod image_cache;
|
||||||
mod platform;
|
mod platform;
|
||||||
mod renderer;
|
mod renderer;
|
||||||
|
mod screen;
|
||||||
mod sprite_cache;
|
mod sprite_cache;
|
||||||
mod status_item;
|
mod status_item;
|
||||||
mod window;
|
mod window;
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
use super::{
|
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::{
|
use crate::{
|
||||||
executor,
|
executor, keymap,
|
||||||
geometry::vector::{vec2f, Vector2F},
|
|
||||||
keymap,
|
|
||||||
platform::{self, CursorStyle},
|
platform::{self, CursorStyle},
|
||||||
Action, AppVersion, ClipboardItem, Event, Menu, MenuItem,
|
Action, AppVersion, ClipboardItem, Event, Menu, MenuItem,
|
||||||
};
|
};
|
||||||
|
@ -14,7 +13,7 @@ use cocoa::{
|
||||||
appkit::{
|
appkit::{
|
||||||
NSApplication, NSApplicationActivationPolicy::NSApplicationActivationPolicyRegular,
|
NSApplication, NSApplicationActivationPolicy::NSApplicationActivationPolicyRegular,
|
||||||
NSEventModifierFlags, NSMenu, NSMenuItem, NSModalResponse, NSOpenPanel, NSPasteboard,
|
NSEventModifierFlags, NSMenu, NSMenuItem, NSModalResponse, NSOpenPanel, NSPasteboard,
|
||||||
NSPasteboardTypeString, NSSavePanel, NSScreen, NSWindow,
|
NSPasteboardTypeString, NSSavePanel, NSWindow,
|
||||||
},
|
},
|
||||||
base::{id, nil, selector, YES},
|
base::{id, nil, selector, YES},
|
||||||
foundation::{
|
foundation::{
|
||||||
|
@ -488,12 +487,11 @@ impl platform::Platform for MacPlatform {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn screen_size(&self) -> Vector2F {
|
fn screens(&self) -> Vec<Rc<dyn platform::Screen>> {
|
||||||
unsafe {
|
Screen::all()
|
||||||
let screen = NSScreen::mainScreen(nil);
|
.into_iter()
|
||||||
let frame = NSScreen::frame(screen);
|
.map(|screen| Rc::new(screen) as Rc<_>)
|
||||||
vec2f(frame.size.width as f32, frame.size.height as f32)
|
.collect()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_window(
|
fn open_window(
|
||||||
|
|
44
crates/gpui/src/platform/mac/screen.rs
Normal file
44
crates/gpui/src/platform/mac/screen.rs
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ use crate::{
|
||||||
mac::platform::NSViewLayerContentsRedrawDuringViewResize,
|
mac::platform::NSViewLayerContentsRedrawDuringViewResize,
|
||||||
platform::{
|
platform::{
|
||||||
self,
|
self,
|
||||||
mac::{geometry::RectFExt, renderer::Renderer},
|
mac::{geometry::RectFExt, renderer::Renderer, screen::Screen},
|
||||||
Event, WindowBounds,
|
Event, WindowBounds,
|
||||||
},
|
},
|
||||||
InputHandler, KeyDownEvent, ModifiersChangedEvent, MouseButton, MouseButtonEvent,
|
InputHandler, KeyDownEvent, ModifiersChangedEvent, MouseButton, MouseButtonEvent,
|
||||||
|
@ -377,11 +377,17 @@ impl Window {
|
||||||
msg_send![PANEL_CLASS, alloc]
|
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(),
|
RectF::new(Default::default(), vec2f(1024., 768.)).to_ns_rect(),
|
||||||
style_mask,
|
style_mask,
|
||||||
NSBackingStoreBuffered,
|
NSBackingStoreBuffered,
|
||||||
NO,
|
NO,
|
||||||
|
options
|
||||||
|
.screen
|
||||||
|
.and_then(|screen| {
|
||||||
|
Some(screen.as_any().downcast_ref::<Screen>()?.native_screen)
|
||||||
|
})
|
||||||
|
.unwrap_or(nil),
|
||||||
);
|
);
|
||||||
assert!(!native_window.is_null());
|
assert!(!native_window.is_null());
|
||||||
|
|
||||||
|
|
|
@ -131,8 +131,8 @@ impl super::Platform for Platform {
|
||||||
|
|
||||||
fn quit(&self) {}
|
fn quit(&self) {}
|
||||||
|
|
||||||
fn screen_size(&self) -> Vector2F {
|
fn screens(&self) -> Vec<Rc<dyn crate::Screen>> {
|
||||||
vec2f(1024., 768.)
|
Default::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_window(
|
fn open_window(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue