diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index 0ef345d98d1de34bbb7c6b567b4716608e2e6dbf..c41bf998f698443d5b6ca93dee2966206596d533 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -44,8 +44,6 @@ pub(crate) fn current_platform() -> Rc { Rc::new(MacPlatform::new()) } -pub type DrawWindow = Box Result>; - pub(crate) trait Platform: 'static { fn background_executor(&self) -> BackgroundExecutor; fn foreground_executor(&self) -> ForegroundExecutor; @@ -66,7 +64,6 @@ pub(crate) trait Platform: 'static { &self, handle: AnyWindowHandle, options: WindowOptions, - draw: DrawWindow, ) -> Box; fn set_display_link_output_callback( @@ -157,6 +154,7 @@ pub trait PlatformWindow { fn minimize(&self); fn zoom(&self); fn toggle_full_screen(&self); + fn on_request_frame(&self, callback: Box); fn on_input(&self, callback: Box bool>); fn on_active_status_change(&self, callback: Box); fn on_resize(&self, callback: Box, f32)>); @@ -167,6 +165,7 @@ pub trait PlatformWindow { fn on_appearance_changed(&self, callback: Box); fn is_topmost_for_position(&self, position: Point) -> bool; fn invalidate(&self); + fn draw(&self, scene: &Scene); fn sprite_atlas(&self) -> Arc; diff --git a/crates/gpui/src/platform/mac/platform.rs b/crates/gpui/src/platform/mac/platform.rs index 8370e2a4953c1280a59d4a9cb74a93ae97214db2..78c2a0738127e43f36d48f60553a1f854b8ec761 100644 --- a/crates/gpui/src/platform/mac/platform.rs +++ b/crates/gpui/src/platform/mac/platform.rs @@ -3,8 +3,7 @@ use crate::{ Action, AnyWindowHandle, BackgroundExecutor, ClipboardItem, CursorStyle, DisplayId, ForegroundExecutor, InputEvent, Keymap, MacDispatcher, MacDisplay, MacDisplayLinker, MacTextSystem, MacWindow, Menu, MenuItem, PathPromptOptions, Platform, PlatformDisplay, - PlatformTextSystem, PlatformWindow, Result, Scene, SemanticVersion, VideoTimestamp, - WindowOptions, + PlatformTextSystem, PlatformWindow, Result, SemanticVersion, VideoTimestamp, WindowOptions, }; use anyhow::anyhow; use block::ConcreteBlock; @@ -498,14 +497,8 @@ impl Platform for MacPlatform { &self, handle: AnyWindowHandle, options: WindowOptions, - draw: Box Result>, ) -> Box { - Box::new(MacWindow::open( - handle, - options, - draw, - self.foreground_executor(), - )) + Box::new(MacWindow::open(handle, options, self.foreground_executor())) } fn set_display_link_output_callback( diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index 2beac528c18f53cfa9a39b008dbebf3825502b30..6f15a7d1acddad42b3427ddf2129d26b4519dd92 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -1,6 +1,6 @@ use super::{display_bounds_from_native, ns_string, MacDisplay, MetalRenderer, NSRange}; use crate::{ - display_bounds_to_native, point, px, size, AnyWindowHandle, Bounds, DrawWindow, ExternalPaths, + display_bounds_to_native, point, px, size, AnyWindowHandle, Bounds, ExternalPaths, FileDropEvent, ForegroundExecutor, GlobalPixels, InputEvent, KeyDownEvent, Keystroke, Modifiers, ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Pixels, PlatformAtlas, PlatformDisplay, PlatformInputHandler, PlatformWindow, Point, @@ -46,7 +46,6 @@ use std::{ sync::{Arc, Weak}, time::Duration, }; -use util::ResultExt; const WINDOW_STATE_IVAR: &str = "windowState"; @@ -317,8 +316,8 @@ struct MacWindowState { executor: ForegroundExecutor, native_window: id, renderer: MetalRenderer, - draw: Option, kind: WindowKind, + request_frame_callback: Option>, event_callback: Option bool>>, activate_callback: Option>, resize_callback: Option, f32)>>, @@ -453,7 +452,6 @@ impl MacWindow { pub fn open( handle: AnyWindowHandle, options: WindowOptions, - draw: DrawWindow, executor: ForegroundExecutor, ) -> Self { unsafe { @@ -545,8 +543,8 @@ impl MacWindow { executor, native_window, renderer: MetalRenderer::new(true), - draw: Some(draw), kind: options.kind, + request_frame_callback: None, event_callback: None, activate_callback: None, resize_callback: None, @@ -926,6 +924,10 @@ impl PlatformWindow for MacWindow { .detach(); } + fn on_request_frame(&self, callback: Box) { + self.0.as_ref().lock().request_frame_callback = Some(callback); + } + fn on_input(&self, callback: Box bool>) { self.0.as_ref().lock().event_callback = Some(callback); } @@ -990,6 +992,11 @@ impl PlatformWindow for MacWindow { } } + fn draw(&self, scene: &crate::Scene) { + let mut this = self.0.lock(); + this.renderer.draw(scene); + } + fn sprite_atlas(&self) -> Arc { self.0.lock().renderer.sprite_atlas().clone() } @@ -1462,15 +1469,12 @@ extern "C" fn set_frame_size(this: &Object, _: Sel, size: NSSize) { } extern "C" fn display_layer(this: &Object, _: Sel, _: id) { - unsafe { - let window_state = get_window_state(this); - let mut draw = window_state.lock().draw.take().unwrap(); - let scene = draw().log_err(); - let mut window_state = window_state.lock(); - window_state.draw = Some(draw); - if let Some(scene) = scene { - window_state.renderer.draw(&scene); - } + let window_state = unsafe { get_window_state(this) }; + let mut lock = window_state.lock(); + if let Some(mut callback) = lock.request_frame_callback.take() { + drop(lock); + callback(); + window_state.lock().request_frame_callback = Some(callback); } } diff --git a/crates/gpui/src/platform/test/platform.rs b/crates/gpui/src/platform/test/platform.rs index 695323e9c46b8e2a8f4260a682d8e214f58c43f4..5067f6a4b3417853a9fe36b59681ddfc5984437f 100644 --- a/crates/gpui/src/platform/test/platform.rs +++ b/crates/gpui/src/platform/test/platform.rs @@ -1,7 +1,6 @@ use crate::{ AnyWindowHandle, BackgroundExecutor, ClipboardItem, CursorStyle, DisplayId, ForegroundExecutor, - Keymap, Platform, PlatformDisplay, PlatformTextSystem, Scene, TestDisplay, TestWindow, - WindowOptions, + Keymap, Platform, PlatformDisplay, PlatformTextSystem, TestDisplay, TestWindow, WindowOptions, }; use anyhow::{anyhow, Result}; use collections::VecDeque; @@ -162,7 +161,6 @@ impl Platform for TestPlatform { &self, handle: AnyWindowHandle, options: WindowOptions, - _draw: Box Result>, ) -> Box { let window = TestWindow::new( options, diff --git a/crates/gpui/src/platform/test/window.rs b/crates/gpui/src/platform/test/window.rs index 91f965c10ac2987f4f6c8c15cb40a7cd94171370..029fd7300998f55f089696d6e01199b9c687ddfd 100644 --- a/crates/gpui/src/platform/test/window.rs +++ b/crates/gpui/src/platform/test/window.rs @@ -218,6 +218,8 @@ impl PlatformWindow for TestWindow { unimplemented!() } + fn on_request_frame(&self, _callback: Box) {} + fn on_input(&self, callback: Box bool>) { self.0.lock().input_callback = Some(callback) } @@ -254,9 +256,9 @@ impl PlatformWindow for TestWindow { unimplemented!() } - fn invalidate(&self) { - // (self.draw.lock())().unwrap(); - } + fn invalidate(&self) {} + + fn draw(&self, _scene: &crate::Scene) {} fn sprite_atlas(&self) -> sync::Arc { self.0.lock().sprite_atlas.clone() diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index 2748ebed8489a35025a89ac35ab22311522e8c28..8f9a82672da6a3c006d788a3e10782403f7c0a17 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -337,14 +337,7 @@ impl Window { options: WindowOptions, cx: &mut AppContext, ) -> Self { - let platform_window = cx.platform.open_window( - handle, - options, - Box::new({ - let mut cx = cx.to_async(); - move || handle.update(&mut cx, |_, cx| cx.draw()) - }), - ); + let platform_window = cx.platform.open_window(handle, options); let display_id = platform_window.display().id(); let sprite_atlas = platform_window.sprite_atlas(); let mouse_position = platform_window.mouse_position(); @@ -353,6 +346,12 @@ impl Window { let scale_factor = platform_window.scale_factor(); let bounds = platform_window.bounds(); + platform_window.on_request_frame(Box::new({ + let mut cx = cx.to_async(); + move || { + handle.update(&mut cx, |_, cx| cx.draw()).log_err(); + } + })); platform_window.on_resize(Box::new({ let mut cx = cx.to_async(); move |_, _| { @@ -1358,7 +1357,7 @@ impl<'a> WindowContext<'a> { } /// Draw pixels to the display for this window based on the contents of its scene. - pub(crate) fn draw(&mut self) -> Scene { + pub(crate) fn draw(&mut self) { println!("====================="); self.window.dirty = false; self.window.drawing = true; @@ -1470,7 +1469,7 @@ impl<'a> WindowContext<'a> { self.window.drawing = false; ELEMENT_ARENA.with_borrow_mut(|element_arena| element_arena.clear()); - scene + self.window.platform_window.draw(&scene); } /// Dispatch a mouse or keyboard event on the window.