浏览代码

Merge pull request #1106 from AvaloniaUI/fixes/1096-popup-scene-not-updating

Clear scene for invisible root visuals.
Steven Kirk 8 年之前
父节点
当前提交
67959eedf7

+ 24 - 18
src/Avalonia.Visuals/Rendering/DeferredRenderer.cs

@@ -11,6 +11,7 @@ using System.Collections.Generic;
 using System.IO;
 using Avalonia.Media.Immutable;
 using System.Threading;
+using System.Linq;
 
 namespace Avalonia.Rendering
 {
@@ -58,7 +59,6 @@ namespace Avalonia.Rendering
             _dispatcher = dispatcher ?? Dispatcher.UIThread;
             _root = root;
             _sceneBuilder = sceneBuilder ?? new SceneBuilder();
-            _scene = new Scene(root);
             _layerFactory = layerFactory ?? new DefaultRenderLayerFactory();
             _layers = new RenderLayers(_layerFactory);
             _renderLoop = renderLoop;
@@ -86,7 +86,6 @@ namespace Avalonia.Rendering
             _root = root;
             _renderTarget = renderTarget;
             _sceneBuilder = sceneBuilder ?? new SceneBuilder();
-            _scene = new Scene(root);
             _layerFactory = layerFactory ?? new DefaultRenderLayerFactory();
             _layers = new RenderLayers(_layerFactory);
         }
@@ -122,7 +121,7 @@ namespace Avalonia.Rendering
                 UpdateScene();
             }
 
-            return _scene.HitTest(p, filter);
+            return _scene?.HitTest(p, filter) ?? Enumerable.Empty<IVisual>();
         }
 
         /// <inheritdoc/>
@@ -186,7 +185,7 @@ namespace Avalonia.Rendering
                 _dirtyRectsDisplay.Tick();
             }
 
-            if (scene.Size != Size.Empty)
+            if (scene != null && scene.Size != Size.Empty)
             {
                 if (scene.Generation != _lastSceneId)
                 {
@@ -366,25 +365,32 @@ namespace Avalonia.Rendering
 
             try
             {
-                var scene = _scene.Clone();
-
-                if (_dirty == null)
-                {
-                    _dirty = new DirtyVisuals();
-                    _sceneBuilder.UpdateAll(scene);
-                }
-                else if (_dirty.Count > 0)
+                if (_root.IsVisible)
                 {
-                    foreach (var visual in _dirty)
+                    var scene = _scene?.Clone() ?? new Scene(_root);
+
+                    if (_dirty == null)
                     {
-                        _sceneBuilder.Update(scene, visual);
+                        _dirty = new DirtyVisuals();
+                        _sceneBuilder.UpdateAll(scene);
+                    }
+                    else if (_dirty.Count > 0)
+                    {
+                        foreach (var visual in _dirty)
+                        {
+                            _sceneBuilder.Update(scene, visual);
+                        }
                     }
-                }
 
-                Interlocked.Exchange(ref _scene, scene);
+                    Interlocked.Exchange(ref _scene, scene);
 
-                _dirty.Clear();
-                (_root as IRenderRoot)?.Invalidate(new Rect(scene.Size));
+                    _dirty.Clear();
+                    (_root as IRenderRoot)?.Invalidate(new Rect(scene.Size));
+                }
+                else
+                {
+                    Interlocked.Exchange(ref _scene, null);
+                }
             }
             finally
             {

+ 6 - 0
src/Avalonia.Visuals/Rendering/SceneGraph/SceneBuilder.cs

@@ -36,8 +36,14 @@ namespace Avalonia.Rendering.SceneGraph
         {
             Contract.Requires<ArgumentNullException>(scene != null);
             Contract.Requires<ArgumentNullException>(visual != null);
+
             Dispatcher.UIThread.VerifyAccess();
 
+            if (!scene.Root.Visual.IsVisible)
+            {
+                throw new AvaloniaInternalException("Cannot update the scene for an invisible root visual.");
+            }
+
             var node = (VisualNode)scene.FindNode(visual);
 
             if (visual == scene.Root.Visual)

+ 0 - 27
tests/Avalonia.Visuals.UnitTests/Rendering/SceneGraph/SceneBuilderTests_Layers.cs

@@ -273,32 +273,5 @@ namespace Avalonia.Visuals.UnitTests.Rendering.SceneGraph
                     ((MockStreamGeometryImpl)borderLayer.GeometryClip).Transform);
             }
         }
-
-        [Fact]
-        public void Hiding_Root_Should_Not_Remove_Root_Layer()
-        {
-            using (TestApplication())
-            {
-                Border border;
-                var tree = new TestRoot
-                {
-                    Child = border = new Border()
-                };
-
-                var layout = AvaloniaLocator.Current.GetService<ILayoutManager>();
-                layout.ExecuteInitialLayoutPass(tree);
-
-                var scene = new Scene(tree);
-                var sceneBuilder = new SceneBuilder();
-                sceneBuilder.UpdateAll(scene);
-
-                tree.IsVisible = false;
-
-                scene = scene.Clone();
-                sceneBuilder.Update(scene, tree);
-
-                Assert.Equal(1, scene.Layers.Count);
-            }
-        }
     }
 }