Redraw the window at the end of `flush_effects` in tests

Antonio Scandurra and Max Brunsfeld created

Co-Authored-By: Max Brunsfeld <max@zed.dev>

Change summary

crates/gpui2/src/app.rs                    | 10 +++++++++-
crates/gpui2/src/platform/test/platform.rs |  3 ++-
crates/gpui2/src/platform/test/window.rs   | 15 +++++++++------
crates/gpui2/src/window.rs                 |  5 ++++-
4 files changed, 24 insertions(+), 9 deletions(-)

Detailed changes

crates/gpui2/src/app.rs 🔗

@@ -595,6 +595,14 @@ impl AppContext {
                 break;
             }
         }
+
+        for (_, window) in &self.windows {
+            if let Some(window) = window.as_ref() {
+                if window.dirty {
+                    window.platform_window.invalidate();
+                }
+            }
+        }
     }
 
     /// Repeatedly called during `flush_effects` to release any entities whose
@@ -713,7 +721,7 @@ impl AppContext {
     fn apply_refresh_effect(&mut self) {
         for window in self.windows.values_mut() {
             if let Some(window) = window.as_mut() {
-                window.platform_window.invalidate();
+                window.dirty = true;
             }
         }
     }

crates/gpui2/src/platform/test/platform.rs 🔗

@@ -136,11 +136,12 @@ impl Platform for TestPlatform {
         &self,
         handle: AnyWindowHandle,
         options: WindowOptions,
-        _draw: Box<dyn FnMut() -> Result<Scene>>,
+        draw: Box<dyn FnMut() -> Result<Scene>>,
     ) -> Box<dyn crate::PlatformWindow> {
         *self.active_window.lock() = Some(handle);
         Box::new(TestWindow::new(
             options,
+            draw,
             self.weak.clone(),
             self.active_display.clone(),
         ))

crates/gpui2/src/platform/test/window.rs 🔗

@@ -1,7 +1,7 @@
 use crate::{
-    px, AtlasKey, AtlasTextureId, AtlasTile, Pixels, PlatformAtlas, PlatformDisplay,
-    PlatformInputHandler, PlatformWindow, Point, Scene, Size, TestPlatform, TileId,
-    WindowAppearance, WindowBounds, WindowOptions,
+    px, AtlasKey, AtlasTextureId, AtlasTile, DrawWindow, Pixels, PlatformAtlas, PlatformDisplay,
+    PlatformInputHandler, PlatformWindow, Point, Size, TestPlatform, TileId, WindowAppearance,
+    WindowBounds, WindowOptions,
 };
 use collections::HashMap;
 use parking_lot::Mutex;
@@ -20,7 +20,7 @@ pub(crate) struct TestWindowHandlers {
 
 pub struct TestWindow {
     pub(crate) bounds: WindowBounds,
-    current_scene: Mutex<Option<Scene>>,
+    draw: Mutex<DrawWindow>,
     display: Rc<dyn PlatformDisplay>,
     pub(crate) window_title: Option<String>,
     pub(crate) input_handler: Option<Arc<Mutex<Box<dyn PlatformInputHandler>>>>,
@@ -32,12 +32,13 @@ pub struct TestWindow {
 impl TestWindow {
     pub fn new(
         options: WindowOptions,
+        draw: DrawWindow,
         platform: Weak<TestPlatform>,
         display: Rc<dyn PlatformDisplay>,
     ) -> Self {
         Self {
             bounds: options.bounds,
-            current_scene: Default::default(),
+            draw: Mutex::new(draw),
             display,
             platform,
             input_handler: None,
@@ -166,7 +167,9 @@ impl PlatformWindow for TestWindow {
         unimplemented!()
     }
 
-    fn invalidate(&self) {}
+    fn invalidate(&self) {
+        (self.draw.lock())().unwrap();
+    }
 
     fn sprite_atlas(&self) -> sync::Arc<dyn crate::PlatformAtlas> {
         self.sprite_atlas.clone()

crates/gpui2/src/window.rs 🔗

@@ -223,6 +223,7 @@ pub struct Window {
     bounds: WindowBounds,
     bounds_observers: SubscriberSet<(), AnyObserver>,
     active: bool,
+    pub(crate) dirty: bool,
     activation_observers: SubscriberSet<(), AnyObserver>,
     pub(crate) last_blur: Option<Option<FocusId>>,
     pub(crate) focus: Option<FocusId>,
@@ -355,6 +356,7 @@ impl Window {
             bounds,
             bounds_observers: SubscriberSet::new(),
             active: false,
+            dirty: false,
             activation_observers: SubscriberSet::new(),
             last_blur: None,
             focus: None,
@@ -406,7 +408,7 @@ impl<'a> WindowContext<'a> {
 
     /// Mark the window as dirty, scheduling it to be redrawn on the next frame.
     pub fn notify(&mut self) {
-        self.window.platform_window.invalidate();
+        self.window.dirty = true;
     }
 
     /// Close this window.
@@ -1237,6 +1239,7 @@ impl<'a> WindowContext<'a> {
             .take()
             .unwrap_or(CursorStyle::Arrow);
         self.platform.set_cursor_style(cursor_style);
+        self.window.dirty = false;
 
         scene
     }