From 046fe3fff9f087fb671b1cb7f010ff456131d8fb Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sun, 21 Mar 2021 11:38:23 -0600 Subject: [PATCH] Dispatch keystrokes and fix rerendering when window invalidated Co-Authored-By: Antonio Scandurra --- gpui/src/app.rs | 19 ++++++++++--- gpui/src/elements/container.rs | 2 +- gpui/src/platform/mac/renderer.rs | 1 + gpui/src/platform/mac/window.rs | 41 ++++++++++++++++------------- gpui/src/platform/mod.rs | 2 +- gpui/src/presenter.rs | 11 ++++++++ gpui/src/scene.rs | 2 +- zed/src/file_finder.rs | 3 --- zed/src/workspace/workspace_view.rs | 1 + 9 files changed, 55 insertions(+), 27 deletions(-) diff --git a/gpui/src/app.rs b/gpui/src/app.rs index 6025aed576..c4e5f789c1 100644 --- a/gpui/src/app.rs +++ b/gpui/src/app.rs @@ -11,6 +11,7 @@ use anyhow::{anyhow, Result}; use keymap::MatchResult; use parking_lot::Mutex; use pathfinder_geometry::{rect::RectF, vector::vec2f}; +use platform::Event; use smol::{channel, prelude::*}; use std::{ any::{type_name, Any, TypeId}, @@ -639,10 +640,22 @@ impl MutableAppContext { { let mut app = self.upgrade(); let presenter = presenter.clone(); - window.on_event(Box::new(move |event, window| { + window.on_event(Box::new(move |event| { log::info!("event {:?}", event); app.update(|ctx| { - ctx.pending_flushes += 1; + if let Event::KeyDown { keystroke, .. } = &event { + if ctx + .dispatch_keystroke( + window_id, + presenter.borrow().dispatch_path(ctx.downgrade()), + keystroke, + ) + .unwrap() + { + return; + } + } + let actions = presenter .borrow_mut() .dispatch_event(event, ctx.downgrade()); @@ -654,7 +667,6 @@ impl MutableAppContext { action.arg.as_ref(), ); } - ctx.flush_effects(); }) })); } @@ -675,6 +687,7 @@ impl MutableAppContext { } self.on_window_invalidated(window_id, move |invalidation, ctx| { + log::info!("window invalidated"); let mut presenter = presenter.borrow_mut(); presenter.invalidate(invalidation, ctx.downgrade()); let scene = presenter.build_scene(window.size(), window.scale_factor(), ctx); diff --git a/gpui/src/elements/container.rs b/gpui/src/elements/container.rs index eca434e383..0fbd48be1f 100644 --- a/gpui/src/elements/container.rs +++ b/gpui/src/elements/container.rs @@ -148,7 +148,7 @@ impl Element for Container { bounds: RectF::new(origin, self.size.unwrap()), background: self.background_color, border: self.border, - corder_radius: self.corner_radius, + corner_radius: self.corner_radius, }); self.child.paint(origin, ctx, app); } diff --git a/gpui/src/platform/mac/renderer.rs b/gpui/src/platform/mac/renderer.rs index ba207544db..857f23fc75 100644 --- a/gpui/src/platform/mac/renderer.rs +++ b/gpui/src/platform/mac/renderer.rs @@ -97,6 +97,7 @@ impl Renderer { for quad_batch in layer.quads().chunks(batch_size) { for (ix, quad) in quad_batch.iter().enumerate() { let bounds = quad.bounds * scene.scale_factor(); + log::info!("render quad {:?}", quad); let shader_quad = shaders::GPUIQuad { origin: bounds.origin().to_float2(), size: bounds.size().to_float2(), diff --git a/gpui/src/platform/mac/window.rs b/gpui/src/platform/mac/window.rs index 1277b747ac..2b489f3cd6 100644 --- a/gpui/src/platform/mac/window.rs +++ b/gpui/src/platform/mac/window.rs @@ -2,7 +2,6 @@ use crate::{ executor, geometry::vector::Vector2F, platform::{self, Event, WindowContext}, - util::post_inc, Scene, }; use anyhow::{anyhow, Result}; @@ -12,7 +11,7 @@ use cocoa::{ NSWindow, NSWindowStyleMask, }, base::{id, nil}, - foundation::{NSAutoreleasePool, NSSize, NSString}, + foundation::{NSAutoreleasePool, NSInteger, NSSize, NSString}, quartzcore::AutoresizingMask, }; use ctor::ctor; @@ -42,6 +41,9 @@ const WINDOW_STATE_IVAR: &'static str = "windowState"; static mut WINDOW_CLASS: *const Class = ptr::null(); static mut VIEW_CLASS: *const Class = ptr::null(); +#[allow(non_upper_case_globals)] +const NSViewLayerContentsRedrawDuringViewResize: NSInteger = 2; + #[ctor] unsafe fn build_classes() { WINDOW_CLASS = { @@ -117,7 +119,7 @@ pub struct Window(Rc>); struct WindowState { native_window: id, - event_callback: Option>, + event_callback: Option>, resize_callback: Option>, synthetic_drag_counter: usize, executor: Rc, @@ -219,10 +221,10 @@ impl Window { // on we explicitly make the view layer-backed up front so that AppKit doesn't do it // itself and break the association with its context. native_view.setWantsLayer(YES); - - native_view.layer().setBackgroundColor_( - msg_send![class!(NSColor), colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0], - ); + let _: () = msg_send![ + native_view, + setLayerContentsRedrawPolicy: NSViewLayerContentsRedrawDuringViewResize + ]; native_window.setContentView_(native_view.autorelease()); native_window.makeFirstResponder_(native_view); @@ -252,7 +254,7 @@ impl Drop for Window { } impl platform::Window for Window { - fn on_event(&mut self, callback: Box) { + fn on_event(&mut self, callback: Box) { self.0.as_ref().borrow_mut().event_callback = Some(callback); } @@ -290,6 +292,7 @@ impl platform::WindowContext for WindowState { } fn present_scene(&mut self, scene: Scene) { + log::info!("present scene"); self.scene_to_render = Some(scene); unsafe { let _: () = msg_send![self.native_window.contentView(), setNeedsDisplay: YES]; @@ -331,32 +334,33 @@ extern "C" fn dealloc_view(this: &Object, _: Sel) { extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) { let window_state = unsafe { get_window_state(this) }; let weak_window_state = Rc::downgrade(&window_state); - let mut window_state = window_state.as_ref().borrow_mut(); + let mut window_state_borrow = window_state.as_ref().borrow_mut(); - let event = unsafe { Event::from_native(native_event, Some(window_state.size().y())) }; + let event = unsafe { Event::from_native(native_event, Some(window_state_borrow.size().y())) }; if let Some(event) = event { match event { Event::LeftMouseDragged { position } => { - window_state.synthetic_drag_counter += 1; - window_state + window_state_borrow.synthetic_drag_counter += 1; + window_state_borrow .executor .spawn(synthetic_drag( weak_window_state, - window_state.synthetic_drag_counter, + window_state_borrow.synthetic_drag_counter, position, )) .detach(); } Event::LeftMouseUp { .. } => { - window_state.synthetic_drag_counter += 1; + window_state_borrow.synthetic_drag_counter += 1; } _ => {} } - if let Some(mut callback) = window_state.event_callback.take() { - callback(event, &mut *window_state); - window_state.event_callback = Some(callback); + if let Some(mut callback) = window_state_borrow.event_callback.take() { + drop(window_state_borrow); + callback(event); + window_state.borrow_mut().event_callback = Some(callback); } } } @@ -417,6 +421,7 @@ extern "C" fn set_frame_size(this: &Object, _: Sel, size: NSSize) { } extern "C" fn display_layer(this: &Object, _: Sel, _: id) { + log::info!("display layer"); unsafe { let window_state = get_window_state(this); let mut window_state = window_state.as_ref().borrow_mut(); @@ -470,7 +475,7 @@ async fn synthetic_drag( let mut window_state = window_state.borrow_mut(); if window_state.synthetic_drag_counter == drag_id { if let Some(mut callback) = window_state.event_callback.take() { - callback(Event::LeftMouseDragged { position }, &mut *window_state); + callback(Event::LeftMouseDragged { position }); window_state.event_callback = Some(callback); } } else { diff --git a/gpui/src/platform/mod.rs b/gpui/src/platform/mod.rs index cc69be5f70..6ab2146225 100644 --- a/gpui/src/platform/mod.rs +++ b/gpui/src/platform/mod.rs @@ -41,7 +41,7 @@ pub trait Dispatcher: Send + Sync { } pub trait Window: WindowContext { - fn on_event(&mut self, callback: Box); + fn on_event(&mut self, callback: Box); fn on_resize(&mut self, callback: Box); } diff --git a/gpui/src/presenter.rs b/gpui/src/presenter.rs index 0b8dd7f3b3..016f49987f 100644 --- a/gpui/src/presenter.rs +++ b/gpui/src/presenter.rs @@ -35,6 +35,17 @@ impl Presenter { } } + pub fn dispatch_path(&self, app: &AppContext) -> Vec { + let mut view_id = app.focused_view_id(self.window_id).unwrap(); + let mut path = vec![view_id]; + while let Some(parent_id) = self.parents.get(&view_id).copied() { + path.push(parent_id); + view_id = parent_id; + } + path.reverse(); + path + } + pub fn invalidate(&mut self, invalidation: WindowInvalidation, app: &AppContext) { for view_id in invalidation.updated { self.rendered_views diff --git a/gpui/src/scene.rs b/gpui/src/scene.rs index 62d074a472..1ca393e733 100644 --- a/gpui/src/scene.rs +++ b/gpui/src/scene.rs @@ -18,7 +18,7 @@ pub struct Quad { pub bounds: RectF, pub background: Option, pub border: Border, - pub corder_radius: f32, + pub corner_radius: f32, } #[derive(Clone, Copy, Default, Debug)] diff --git a/zed/src/file_finder.rs b/zed/src/file_finder.rs index 312c3dff4b..e75a2ba0ff 100644 --- a/zed/src/file_finder.rs +++ b/zed/src/file_finder.rs @@ -346,13 +346,10 @@ impl FileFinder { fn select(&mut self, entry: &(usize, usize), ctx: &mut ViewContext) { let (tree_id, entry_id) = *entry; - log::info!("selected item! {} {}", tree_id, entry_id); ctx.emit(Event::Selected(tree_id, entry_id)); } fn spawn_search(&mut self, query: String, ctx: &mut ViewContext) { - log::info!("spawn search!"); - let worktrees = self.worktrees(ctx.app()); let search_id = util::post_inc(&mut self.search_count); let task = ctx.background_executor().spawn(async move { diff --git a/zed/src/workspace/workspace_view.rs b/zed/src/workspace/workspace_view.rs index a509c4a587..8445f4eb7a 100644 --- a/zed/src/workspace/workspace_view.rs +++ b/zed/src/workspace/workspace_view.rs @@ -141,6 +141,7 @@ impl WorkspaceView { ctx.focus(&modal); self.modal = Some(modal.into()); } + log::info!("toggle modal notify"); ctx.notify(); }