Checkpoint
This commit is contained in:
parent
177e385bb9
commit
0d0c760d94
10 changed files with 224 additions and 52 deletions
|
@ -8,8 +8,8 @@ pub use model_context::*;
|
||||||
use refineable::Refineable;
|
use refineable::Refineable;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
current_platform, image_cache::ImageCache, AssetSource, Context, Executor, LayoutId,
|
current_platform, image_cache::ImageCache, AssetSource, Context, DisplayLinker, Executor,
|
||||||
MainThread, MainThreadOnly, Platform, RootView, SvgRenderer, Task, TextStyle,
|
LayoutId, MainThread, MainThreadOnly, Platform, RootView, SvgRenderer, Task, TextStyle,
|
||||||
TextStyleRefinement, TextSystem, Window, WindowContext, WindowHandle, WindowId,
|
TextStyleRefinement, TextSystem, Window, WindowContext, WindowHandle, WindowId,
|
||||||
};
|
};
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
|
@ -51,15 +51,15 @@ impl App {
|
||||||
http_client: Arc<dyn HttpClient>,
|
http_client: Arc<dyn HttpClient>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let executor = platform.executor();
|
let executor = platform.executor();
|
||||||
let text_system = Arc::new(TextSystem::new(platform.text_system()));
|
|
||||||
let entities = EntityMap::new();
|
let entities = EntityMap::new();
|
||||||
let unit_entity = entities.insert(entities.reserve(), ());
|
let unit_entity = entities.insert(entities.reserve(), ());
|
||||||
Self(Arc::new_cyclic(|this| {
|
Self(Arc::new_cyclic(|this| {
|
||||||
Mutex::new(AppContext {
|
Mutex::new(AppContext {
|
||||||
this: this.clone(),
|
this: this.clone(),
|
||||||
|
display_linker: Arc::new(DisplayLinker::new(platform.display_linker())),
|
||||||
|
text_system: Arc::new(TextSystem::new(platform.text_system())),
|
||||||
platform: MainThreadOnly::new(platform, executor.clone()),
|
platform: MainThreadOnly::new(platform, executor.clone()),
|
||||||
executor,
|
executor,
|
||||||
text_system,
|
|
||||||
svg_renderer: SvgRenderer::new(asset_source),
|
svg_renderer: SvgRenderer::new(asset_source),
|
||||||
image_cache: ImageCache::new(http_client),
|
image_cache: ImageCache::new(http_client),
|
||||||
pending_updates: 0,
|
pending_updates: 0,
|
||||||
|
@ -97,6 +97,7 @@ pub struct AppContext {
|
||||||
text_system: Arc<TextSystem>,
|
text_system: Arc<TextSystem>,
|
||||||
pending_updates: usize,
|
pending_updates: usize,
|
||||||
pub(crate) executor: Executor,
|
pub(crate) executor: Executor,
|
||||||
|
pub(crate) display_linker: Arc<DisplayLinker>,
|
||||||
pub(crate) svg_renderer: SvgRenderer,
|
pub(crate) svg_renderer: SvgRenderer,
|
||||||
pub(crate) image_cache: ImageCache,
|
pub(crate) image_cache: ImageCache,
|
||||||
pub(crate) text_style_stack: Vec<TextStyleRefinement>,
|
pub(crate) text_style_stack: Vec<TextStyleRefinement>,
|
||||||
|
@ -359,9 +360,15 @@ impl MainThread<AppContext> {
|
||||||
let id = cx.windows.insert(None);
|
let id = cx.windows.insert(None);
|
||||||
let handle = WindowHandle::new(id);
|
let handle = WindowHandle::new(id);
|
||||||
let mut window = Window::new(handle.into(), options, cx);
|
let mut window = Window::new(handle.into(), options, cx);
|
||||||
|
let display_id = window.display_id;
|
||||||
let root_view = build_root_view(&mut WindowContext::mutable(cx, &mut window));
|
let root_view = build_root_view(&mut WindowContext::mutable(cx, &mut window));
|
||||||
window.root_view.replace(root_view.into_any());
|
window.root_view.replace(root_view.into_any());
|
||||||
cx.windows.get_mut(id).unwrap().replace(window);
|
cx.windows.get_mut(id).unwrap().replace(window);
|
||||||
|
|
||||||
|
cx.display_linker.on_next_frame(display_id, |_, _| {
|
||||||
|
dbg!("next frame");
|
||||||
|
});
|
||||||
|
|
||||||
handle
|
handle
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
55
crates/gpui3/src/display_linker.rs
Normal file
55
crates/gpui3/src/display_linker.rs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
use crate::{DisplayId, PlatformDisplayLinker, VideoTimestamp};
|
||||||
|
use collections::HashMap;
|
||||||
|
use parking_lot::Mutex;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
type FrameCallback = Box<dyn FnOnce(&VideoTimestamp, &VideoTimestamp) + Send>;
|
||||||
|
|
||||||
|
pub struct DisplayLinker {
|
||||||
|
platform_linker: Arc<dyn PlatformDisplayLinker>,
|
||||||
|
next_frame_callbacks: Arc<Mutex<HashMap<DisplayId, Vec<FrameCallback>>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DisplayLinker {
|
||||||
|
pub(crate) fn new(platform_linker: Arc<dyn PlatformDisplayLinker>) -> Self {
|
||||||
|
Self {
|
||||||
|
platform_linker,
|
||||||
|
next_frame_callbacks: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn on_next_frame(
|
||||||
|
&self,
|
||||||
|
display_id: DisplayId,
|
||||||
|
callback: impl FnOnce(&VideoTimestamp, &VideoTimestamp) + Send + 'static,
|
||||||
|
) {
|
||||||
|
let next_frame_callbacks = self.next_frame_callbacks.clone();
|
||||||
|
let callback = Box::new(callback);
|
||||||
|
match self.next_frame_callbacks.lock().entry(display_id) {
|
||||||
|
collections::hash_map::Entry::Occupied(mut entry) => {
|
||||||
|
if entry.get().is_empty() {
|
||||||
|
self.platform_linker.start(display_id)
|
||||||
|
}
|
||||||
|
entry.get_mut().push(callback)
|
||||||
|
}
|
||||||
|
collections::hash_map::Entry::Vacant(entry) => {
|
||||||
|
// let platform_linker = self.platform_linker.clone();
|
||||||
|
self.platform_linker.set_output_callback(
|
||||||
|
display_id,
|
||||||
|
Box::new(move |current_time, output_time| {
|
||||||
|
for callback in next_frame_callbacks
|
||||||
|
.lock()
|
||||||
|
.get_mut(&display_id)
|
||||||
|
.unwrap()
|
||||||
|
.drain(..)
|
||||||
|
{
|
||||||
|
callback(current_time, output_time);
|
||||||
|
}
|
||||||
|
// platform_linker.stop(display_id);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
entry.insert(vec![callback]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
mod app;
|
mod app;
|
||||||
mod assets;
|
mod assets;
|
||||||
mod color;
|
mod color;
|
||||||
|
mod display_linker;
|
||||||
mod element;
|
mod element;
|
||||||
mod elements;
|
mod elements;
|
||||||
mod executor;
|
mod executor;
|
||||||
|
@ -22,6 +23,7 @@ pub use anyhow::Result;
|
||||||
pub use app::*;
|
pub use app::*;
|
||||||
pub use assets::*;
|
pub use assets::*;
|
||||||
pub use color::*;
|
pub use color::*;
|
||||||
|
pub use display_linker::*;
|
||||||
pub use element::*;
|
pub use element::*;
|
||||||
pub use elements::*;
|
pub use elements::*;
|
||||||
pub use executor::*;
|
pub use executor::*;
|
||||||
|
|
|
@ -42,6 +42,7 @@ pub(crate) fn current_platform() -> Arc<dyn Platform> {
|
||||||
|
|
||||||
pub trait Platform: 'static {
|
pub trait Platform: 'static {
|
||||||
fn executor(&self) -> Executor;
|
fn executor(&self) -> Executor;
|
||||||
|
fn display_linker(&self) -> Arc<dyn PlatformDisplayLinker>;
|
||||||
fn text_system(&self) -> Arc<dyn PlatformTextSystem>;
|
fn text_system(&self) -> Arc<dyn PlatformTextSystem>;
|
||||||
|
|
||||||
fn run(&self, on_finish_launching: Box<dyn 'static + FnOnce()>);
|
fn run(&self, on_finish_launching: Box<dyn 'static + FnOnce()>);
|
||||||
|
@ -99,7 +100,6 @@ pub trait PlatformDisplay: Debug {
|
||||||
fn id(&self) -> DisplayId;
|
fn id(&self) -> DisplayId;
|
||||||
fn as_any(&self) -> &dyn Any;
|
fn as_any(&self) -> &dyn Any;
|
||||||
fn bounds(&self) -> Bounds<GlobalPixels>;
|
fn bounds(&self) -> Bounds<GlobalPixels>;
|
||||||
fn link(&self) -> Box<dyn PlatformDisplayLink>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash, Copy, Clone)]
|
#[derive(PartialEq, Eq, Hash, Copy, Clone)]
|
||||||
|
@ -156,10 +156,14 @@ pub trait PlatformDispatcher: Send + Sync {
|
||||||
fn dispatch_on_main_thread(&self, task: Runnable);
|
fn dispatch_on_main_thread(&self, task: Runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PlatformDisplayLink {
|
pub trait PlatformDisplayLinker: Send + Sync {
|
||||||
// fn set_output_callback(&mut self, callback: Box<dyn FnMut(&VideoTimestamp, &VideoTimestamp)>);
|
fn set_output_callback(
|
||||||
fn start(&mut self);
|
&self,
|
||||||
fn stop(&mut self);
|
display_id: DisplayId,
|
||||||
|
callback: Box<dyn FnMut(&VideoTimestamp, &VideoTimestamp)>,
|
||||||
|
);
|
||||||
|
fn start(&self, display_id: DisplayId);
|
||||||
|
fn stop(&self, display_id: DisplayId);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PlatformTextSystem: Send + Sync {
|
pub trait PlatformTextSystem: Send + Sync {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
///! an origin at the bottom left of the main display.
|
///! an origin at the bottom left of the main display.
|
||||||
mod dispatcher;
|
mod dispatcher;
|
||||||
mod display;
|
mod display;
|
||||||
// mod display_link;
|
mod display_linker;
|
||||||
mod events;
|
mod events;
|
||||||
mod metal_atlas;
|
mod metal_atlas;
|
||||||
mod metal_renderer;
|
mod metal_renderer;
|
||||||
|
@ -33,7 +33,7 @@ use std::{
|
||||||
|
|
||||||
pub use dispatcher::*;
|
pub use dispatcher::*;
|
||||||
pub use display::*;
|
pub use display::*;
|
||||||
// pub use display_link::*;
|
pub use display_linker::*;
|
||||||
pub use metal_atlas::*;
|
pub use metal_atlas::*;
|
||||||
pub use platform::*;
|
pub use platform::*;
|
||||||
pub use text_system::*;
|
pub use text_system::*;
|
||||||
|
|
|
@ -98,9 +98,4 @@ impl PlatformDisplay for MacDisplay {
|
||||||
display_bounds_from_native(native_bounds)
|
display_bounds_from_native(native_bounds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn link(&self) -> Box<dyn crate::PlatformDisplayLink> {
|
|
||||||
unimplemented!()
|
|
||||||
// Box::new(unsafe { MacDisplayLink::new(self.0) })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,41 +1,77 @@
|
||||||
use crate::PlatformDisplayLink;
|
|
||||||
use std::ffi::c_void;
|
use std::ffi::c_void;
|
||||||
|
|
||||||
|
use crate::{DisplayId, PlatformDisplayLinker};
|
||||||
|
use collections::HashMap;
|
||||||
|
use parking_lot::Mutex;
|
||||||
pub use sys::CVTimeStamp as VideoTimestamp;
|
pub use sys::CVTimeStamp as VideoTimestamp;
|
||||||
|
|
||||||
pub struct MacDisplayLink {
|
pub struct MacDisplayLinker {
|
||||||
sys_link: sys::DisplayLink,
|
links: Mutex<HashMap<DisplayId, MacDisplayLink>>,
|
||||||
output_callback: Option<Box<dyn FnMut(&VideoTimestamp, &VideoTimestamp)>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MacDisplayLink {
|
struct MacDisplayLink {
|
||||||
pub unsafe fn new(display_id: u32) -> Self {
|
output_callback: Box<dyn FnMut(&VideoTimestamp, &VideoTimestamp)>,
|
||||||
Self {
|
system_link: sys::DisplayLink,
|
||||||
sys_link: sys::DisplayLink::on_display(display_id).unwrap(),
|
}
|
||||||
output_callback: None,
|
|
||||||
|
unsafe impl Send for MacDisplayLink {}
|
||||||
|
|
||||||
|
impl MacDisplayLinker {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
MacDisplayLinker {
|
||||||
|
links: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PlatformDisplayLink for MacDisplayLink {
|
impl PlatformDisplayLinker for MacDisplayLinker {
|
||||||
fn set_output_callback(&mut self, callback: Box<dyn FnMut(&VideoTimestamp, &VideoTimestamp)>) {
|
fn set_output_callback(
|
||||||
unsafe {
|
&self,
|
||||||
self.sys_link.set_output_callback(
|
display_id: DisplayId,
|
||||||
trampoline,
|
mut output_callback: Box<dyn FnMut(&VideoTimestamp, &VideoTimestamp)>,
|
||||||
self.output_callback.as_mut().unwrap()
|
) {
|
||||||
as *mut dyn FnMut(&VideoTimestamp, &VideoTimestamp)
|
if let Some(mut system_link) = unsafe { sys::DisplayLink::on_display(display_id.0) } {
|
||||||
as *mut c_void,
|
unsafe {
|
||||||
|
system_link.set_output_callback(
|
||||||
|
trampoline,
|
||||||
|
output_callback.as_mut() as *mut dyn FnMut(_, _) as *mut c_void,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
let previous = self.links.lock().insert(
|
||||||
|
display_id,
|
||||||
|
MacDisplayLink {
|
||||||
|
output_callback,
|
||||||
|
system_link,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
assert!(
|
||||||
|
previous.is_none(),
|
||||||
|
"You can currently only set an output callback once per display."
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return log::warn!("DisplayLink could not be obtained for {:?}", display_id);
|
||||||
}
|
}
|
||||||
self.output_callback = Some(callback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start(&mut self) {
|
fn start(&self, display_id: DisplayId) {
|
||||||
unsafe { self.sys_link.start() }
|
if let Some(link) = self.links.lock().get_mut(&display_id) {
|
||||||
|
unsafe {
|
||||||
|
link.system_link.start();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log::warn!("No DisplayLink callback registered for {:?}", display_id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stop(&mut self) {
|
fn stop(&self, display_id: DisplayId) {
|
||||||
unsafe { self.sys_link.stop() }
|
if let Some(link) = self.links.lock().get_mut(&display_id) {
|
||||||
|
unsafe {
|
||||||
|
link.system_link.stop();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log::warn!("No DisplayLink callback registered for {:?}", display_id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,11 +84,8 @@ unsafe extern "C" fn trampoline(
|
||||||
context: *mut c_void,
|
context: *mut c_void,
|
||||||
) -> i32 {
|
) -> i32 {
|
||||||
let output_callback = &mut (*(context as *mut MacDisplayLink)).output_callback;
|
let output_callback = &mut (*(context as *mut MacDisplayLink)).output_callback;
|
||||||
if let Some(callback) = output_callback {
|
if let Some((current_time, output_time)) = current_time.as_ref().zip(output_time.as_ref()) {
|
||||||
if let Some((current_time, output_time)) = current_time.as_ref().zip(output_time.as_ref()) {
|
output_callback(¤t_time, &output_time);
|
||||||
// convert sys::CVTimeStamp to VideoTimestamp
|
|
||||||
callback(¤t_time, &output_time);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
@ -61,9 +94,8 @@ mod sys {
|
||||||
//! Derived from display-link crate under the fololwing license:
|
//! Derived from display-link crate under the fololwing license:
|
||||||
//! https://github.com/BrainiumLLC/display-link/blob/master/LICENSE-MIT
|
//! https://github.com/BrainiumLLC/display-link/blob/master/LICENSE-MIT
|
||||||
//! Apple docs: [CVDisplayLink](https://developer.apple.com/documentation/corevideo/cvdisplaylinkoutputcallback?language=objc)
|
//! Apple docs: [CVDisplayLink](https://developer.apple.com/documentation/corevideo/cvdisplaylinkoutputcallback?language=objc)
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code, non_upper_case_globals)]
|
||||||
|
|
||||||
pub use cocoa::quartzcore::CVTimeStamp;
|
|
||||||
use foreign_types::{foreign_type, ForeignType};
|
use foreign_types::{foreign_type, ForeignType};
|
||||||
use std::{
|
use std::{
|
||||||
ffi::c_void,
|
ffi::c_void,
|
||||||
|
@ -90,6 +122,64 @@ mod sys {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct CVTimeStamp {
|
||||||
|
pub version: u32,
|
||||||
|
pub video_time_scale: i32,
|
||||||
|
pub video_time: i64,
|
||||||
|
pub host_time: u64,
|
||||||
|
pub rate_scalar: f64,
|
||||||
|
pub video_refresh_period: i64,
|
||||||
|
pub smpte_time: CVSMPTETime,
|
||||||
|
pub flags: u64,
|
||||||
|
pub reserved: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type CVTimeStampFlags = u64;
|
||||||
|
|
||||||
|
pub const kCVTimeStampVideoTimeValid: CVTimeStampFlags = 1 << 0;
|
||||||
|
pub const kCVTimeStampHostTimeValid: CVTimeStampFlags = 1 << 1;
|
||||||
|
pub const kCVTimeStampSMPTETimeValid: CVTimeStampFlags = 1 << 2;
|
||||||
|
pub const kCVTimeStampVideoRefreshPeriodValid: CVTimeStampFlags = 1 << 3;
|
||||||
|
pub const kCVTimeStampRateScalarValid: CVTimeStampFlags = 1 << 4;
|
||||||
|
pub const kCVTimeStampTopField: CVTimeStampFlags = 1 << 16;
|
||||||
|
pub const kCVTimeStampBottomField: CVTimeStampFlags = 1 << 17;
|
||||||
|
pub const kCVTimeStampVideoHostTimeValid: CVTimeStampFlags =
|
||||||
|
kCVTimeStampVideoTimeValid | kCVTimeStampHostTimeValid;
|
||||||
|
pub const kCVTimeStampIsInterlaced: CVTimeStampFlags =
|
||||||
|
kCVTimeStampTopField | kCVTimeStampBottomField;
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
pub struct CVSMPTETime {
|
||||||
|
pub subframes: i16,
|
||||||
|
pub subframe_divisor: i16,
|
||||||
|
pub counter: u32,
|
||||||
|
pub time_type: u32,
|
||||||
|
pub flags: u32,
|
||||||
|
pub hours: i16,
|
||||||
|
pub minutes: i16,
|
||||||
|
pub seconds: i16,
|
||||||
|
pub frames: i16,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type CVSMPTETimeType = u32;
|
||||||
|
|
||||||
|
pub const kCVSMPTETimeType24: CVSMPTETimeType = 0;
|
||||||
|
pub const kCVSMPTETimeType25: CVSMPTETimeType = 1;
|
||||||
|
pub const kCVSMPTETimeType30Drop: CVSMPTETimeType = 2;
|
||||||
|
pub const kCVSMPTETimeType30: CVSMPTETimeType = 3;
|
||||||
|
pub const kCVSMPTETimeType2997: CVSMPTETimeType = 4;
|
||||||
|
pub const kCVSMPTETimeType2997Drop: CVSMPTETimeType = 5;
|
||||||
|
pub const kCVSMPTETimeType60: CVSMPTETimeType = 6;
|
||||||
|
pub const kCVSMPTETimeType5994: CVSMPTETimeType = 7;
|
||||||
|
|
||||||
|
pub type CVSMPTETimeFlags = u32;
|
||||||
|
|
||||||
|
pub const kCVSMPTETimeValid: CVSMPTETimeFlags = 1 << 0;
|
||||||
|
pub const kCVSMPTETimeRunning: CVSMPTETimeFlags = 1 << 1;
|
||||||
|
|
||||||
pub type CVDisplayLinkOutputCallback = unsafe extern "C" fn(
|
pub type CVDisplayLinkOutputCallback = unsafe extern "C" fn(
|
||||||
display_link_out: *mut CVDisplayLink,
|
display_link_out: *mut CVDisplayLink,
|
||||||
// A pointer to the current timestamp. This represents the timestamp when the callback is called.
|
// A pointer to the current timestamp. This represents the timestamp when the callback is called.
|
|
@ -1,8 +1,9 @@
|
||||||
use super::BoolExt;
|
use super::BoolExt;
|
||||||
use crate::{
|
use crate::{
|
||||||
AnyWindowHandle, ClipboardItem, CursorStyle, DisplayId, Event, Executor, MacDispatcher,
|
AnyWindowHandle, ClipboardItem, CursorStyle, DisplayId, Event, Executor, MacDispatcher,
|
||||||
MacDisplay, MacTextSystem, MacWindow, PathPromptOptions, Platform, PlatformDisplay,
|
MacDisplay, MacDisplayLinker, MacTextSystem, MacWindow, PathPromptOptions, Platform,
|
||||||
PlatformTextSystem, PlatformWindow, Result, SemanticVersion, WindowOptions,
|
PlatformDisplay, PlatformDisplayLinker, PlatformTextSystem, PlatformWindow, Result,
|
||||||
|
SemanticVersion, WindowOptions,
|
||||||
};
|
};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use block::ConcreteBlock;
|
use block::ConcreteBlock;
|
||||||
|
@ -347,6 +348,10 @@ impl Platform for MacPlatform {
|
||||||
self.0.lock().executor.clone()
|
self.0.lock().executor.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn display_linker(&self) -> Arc<dyn PlatformDisplayLinker> {
|
||||||
|
Arc::new(MacDisplayLinker::new())
|
||||||
|
}
|
||||||
|
|
||||||
fn text_system(&self) -> Arc<dyn PlatformTextSystem> {
|
fn text_system(&self) -> Arc<dyn PlatformTextSystem> {
|
||||||
self.0.lock().text_system.clone()
|
self.0.lock().text_system.clone()
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,10 @@ impl Platform for TestPlatform {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn display_linker(&self) -> std::sync::Arc<dyn crate::PlatformDisplayLinker> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
fn text_system(&self) -> std::sync::Arc<dyn crate::PlatformTextSystem> {
|
fn text_system(&self) -> std::sync::Arc<dyn crate::PlatformTextSystem> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
image_cache::RenderImageParams, px, AnyView, AppContext, AsyncWindowContext, AvailableSpace,
|
image_cache::RenderImageParams, px, AnyView, AppContext, AsyncWindowContext, AvailableSpace,
|
||||||
BorrowAppContext, Bounds, Context, Corners, DevicePixels, Effect, Element, EntityId, FontId,
|
BorrowAppContext, Bounds, Context, Corners, DevicePixels, DisplayId, Effect, Element, EntityId,
|
||||||
GlyphId, Handle, Hsla, ImageData, IsZero, LayerId, LayoutId, MainThread, MainThreadOnly,
|
FontId, GlyphId, Handle, Hsla, ImageData, IsZero, LayerId, LayoutId, MainThread,
|
||||||
MonochromeSprite, Pixels, PlatformAtlas, PlatformWindow, Point, PolychromeSprite, Reference,
|
MainThreadOnly, MonochromeSprite, Pixels, PlatformAtlas, PlatformWindow, Point,
|
||||||
RenderGlyphParams, RenderSvgParams, ScaledPixels, Scene, SharedString, Size, Style,
|
PolychromeSprite, Reference, RenderGlyphParams, RenderSvgParams, ScaledPixels, Scene,
|
||||||
TaffyLayoutEngine, Task, WeakHandle, WindowOptions, SUBPIXEL_VARIANTS,
|
SharedString, Size, Style, TaffyLayoutEngine, Task, WeakHandle, WindowOptions,
|
||||||
|
SUBPIXEL_VARIANTS,
|
||||||
};
|
};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
@ -16,6 +17,7 @@ pub struct AnyWindow {}
|
||||||
pub struct Window {
|
pub struct Window {
|
||||||
handle: AnyWindowHandle,
|
handle: AnyWindowHandle,
|
||||||
platform_window: MainThreadOnly<Box<dyn PlatformWindow>>,
|
platform_window: MainThreadOnly<Box<dyn PlatformWindow>>,
|
||||||
|
pub(crate) display_id: DisplayId, // todo!("make private again?")
|
||||||
sprite_atlas: Arc<dyn PlatformAtlas>,
|
sprite_atlas: Arc<dyn PlatformAtlas>,
|
||||||
rem_size: Pixels,
|
rem_size: Pixels,
|
||||||
content_size: Size<Pixels>,
|
content_size: Size<Pixels>,
|
||||||
|
@ -35,6 +37,7 @@ impl Window {
|
||||||
cx: &mut MainThread<AppContext>,
|
cx: &mut MainThread<AppContext>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let platform_window = cx.platform().open_window(handle, options);
|
let platform_window = cx.platform().open_window(handle, options);
|
||||||
|
let display_id = platform_window.display().id();
|
||||||
let sprite_atlas = platform_window.sprite_atlas();
|
let sprite_atlas = platform_window.sprite_atlas();
|
||||||
let mouse_position = platform_window.mouse_position();
|
let mouse_position = platform_window.mouse_position();
|
||||||
let content_size = platform_window.content_size();
|
let content_size = platform_window.content_size();
|
||||||
|
@ -46,6 +49,12 @@ impl Window {
|
||||||
cx.update_window(handle, |cx| {
|
cx.update_window(handle, |cx| {
|
||||||
cx.window.scene = Scene::new(scale_factor);
|
cx.window.scene = Scene::new(scale_factor);
|
||||||
cx.window.content_size = content_size;
|
cx.window.content_size = content_size;
|
||||||
|
cx.window.display_id = cx
|
||||||
|
.window
|
||||||
|
.platform_window
|
||||||
|
.borrow_on_main_thread()
|
||||||
|
.display()
|
||||||
|
.id();
|
||||||
cx.window.dirty = true;
|
cx.window.dirty = true;
|
||||||
})
|
})
|
||||||
.log_err();
|
.log_err();
|
||||||
|
@ -57,6 +66,7 @@ impl Window {
|
||||||
Window {
|
Window {
|
||||||
handle,
|
handle,
|
||||||
platform_window,
|
platform_window,
|
||||||
|
display_id,
|
||||||
sprite_atlas,
|
sprite_atlas,
|
||||||
rem_size: px(16.),
|
rem_size: px(16.),
|
||||||
content_size,
|
content_size,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue