From 008f2b905b1b28dfc17e9ad6d3095f3f8be7cf3a Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 6 May 2021 15:13:01 -0600 Subject: [PATCH] Hold a WeakViewHandle in BufferElement Otherwise, the element never goes away because the view never goes away because the element is holding a strong reference. Co-Authored-By: Max Brunsfeld --- zed/src/editor/buffer_element.rs | 34 +++++++++++++++++++------------- zed/src/editor/buffer_view.rs | 4 ++-- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/zed/src/editor/buffer_element.rs b/zed/src/editor/buffer_element.rs index 8a49c208f3..8ceb72c1e9 100644 --- a/zed/src/editor/buffer_element.rs +++ b/zed/src/editor/buffer_element.rs @@ -9,7 +9,7 @@ use gpui::{ json::{self, ToJson}, text_layout::{self, TextLayoutCache}, AfterLayoutContext, AppContext, Border, Element, Event, EventContext, FontCache, LayoutContext, - PaintContext, Quad, Scene, SizeConstraint, ViewHandle, + PaintContext, Quad, Scene, SizeConstraint, WeakViewHandle, }; use json::json; use smallvec::SmallVec; @@ -20,14 +20,18 @@ use std::{ }; pub struct BufferElement { - view: ViewHandle, + view: WeakViewHandle, } impl BufferElement { - pub fn new(view: ViewHandle) -> Self { + pub fn new(view: WeakViewHandle) -> Self { Self { view } } + fn view<'a>(&self, ctx: &'a AppContext) -> &'a BufferView { + self.view.upgrade(ctx).unwrap().read(ctx) + } + fn mouse_down( &self, position: Vector2F, @@ -37,7 +41,7 @@ impl BufferElement { ctx: &mut EventContext, ) -> bool { if paint.text_bounds.contains_point(position) { - let view = self.view.read(ctx.app); + let view = self.view(ctx.app); let position = paint.point_for_position(view, layout, position, ctx.font_cache, ctx.app); ctx.dispatch_action("buffer:select", SelectAction::Begin { position, add: cmd }); @@ -48,7 +52,7 @@ impl BufferElement { } fn mouse_up(&self, _position: Vector2F, ctx: &mut EventContext) -> bool { - if self.view.read(ctx.app).is_selecting() { + if self.view(ctx.app).is_selecting() { ctx.dispatch_action("buffer:select", SelectAction::End); true } else { @@ -63,7 +67,7 @@ impl BufferElement { paint: &mut PaintState, ctx: &mut EventContext, ) -> bool { - let view = self.view.read(ctx.app); + let view = self.view(ctx.app); if view.is_selecting() { let rect = paint.text_bounds; @@ -116,7 +120,9 @@ impl BufferElement { } fn key_down(&self, chars: &str, ctx: &mut EventContext) -> bool { - if self.view.is_focused(ctx.app) { + let view = self.view.upgrade(ctx.app).unwrap(); + + if view.is_focused(ctx.app) { if chars.is_empty() { false } else { @@ -145,7 +151,7 @@ impl BufferElement { return false; } - let view = self.view.read(ctx.app); + let view = self.view(ctx.app); let font_cache = &ctx.font_cache; let layout_cache = &ctx.text_layout_cache; let max_glyph_width = view.em_width(font_cache); @@ -167,7 +173,7 @@ impl BufferElement { } fn paint_gutter(&mut self, rect: RectF, layout: &LayoutState, ctx: &mut PaintContext) { - let view = self.view.read(ctx.app); + let view = self.view(ctx.app); let line_height = view.line_height(ctx.font_cache); let scroll_top = view.scroll_position().y() * line_height; @@ -197,7 +203,7 @@ impl BufferElement { } fn paint_text(&mut self, bounds: RectF, layout: &LayoutState, ctx: &mut PaintContext) { - let view = self.view.read(ctx.app); + let view = self.view(ctx.app); let line_height = view.line_height(ctx.font_cache); let descent = view.font_descent(ctx.font_cache); let start_row = view.scroll_position().y() as u32; @@ -313,14 +319,14 @@ impl Element for BufferElement { let app = ctx.app; let mut size = constraint.max; if size.y().is_infinite() { - let view = self.view.read(app); + let view = self.view(app); size.set_y((view.max_point(app).row() + 1) as f32 * view.line_height(ctx.font_cache)); } if size.x().is_infinite() { unimplemented!("we don't yet handle an infinite width constraint on buffer elements"); } - let view = self.view.read(app); + let view = self.view(app); let font_cache = &ctx.font_cache; let layout_cache = &ctx.text_layout_cache; let line_height = view.line_height(font_cache); @@ -404,7 +410,7 @@ impl Element for BufferElement { if let Some(layout) = layout { let app = ctx.app.as_ref(); - let view = self.view.read(app); + let view = self.view(app); view.clamp_scroll_left( layout .scroll_max(view, ctx.font_cache, ctx.text_layout_cache, app) @@ -437,7 +443,7 @@ impl Element for BufferElement { layout.text_size, ); - if self.view.read(ctx.app).is_gutter_visible() { + if self.view(ctx.app).is_gutter_visible() { self.paint_gutter(gutter_bounds, layout, ctx); } self.paint_text(text_bounds, layout, ctx); diff --git a/zed/src/editor/buffer_view.rs b/zed/src/editor/buffer_view.rs index 7d80c68217..8a91e447c1 100644 --- a/zed/src/editor/buffer_view.rs +++ b/zed/src/editor/buffer_view.rs @@ -2161,8 +2161,8 @@ impl Entity for BufferView { } impl View for BufferView { - fn render<'a>(&self, app: &AppContext) -> ElementBox { - BufferElement::new(self.handle.upgrade(app).unwrap()).boxed() + fn render<'a>(&self, _: &AppContext) -> ElementBox { + BufferElement::new(self.handle.clone()).boxed() } fn ui_name() -> &'static str {