changeset 21655:c32590cd0080

Do not redraw while figures are being deleted (bug #47699). * graphics.cc (delete_graphics_objects): New static variable delete_executing. Use unwind_protect frame to change delete_executing to true before deleting objects. * graphics.cc (Fdrawnow): Don't redraw if in the middle of a delete operation indicated by delete_executing flag. * graphics.cc (gh_manager::do_close_all_figures): Replace assert that all handles are closed, with a warning.
author Lachlan Andrew <lachlanbis@gmail.com>
date Fri, 29 Apr 2016 18:43:08 +1000
parents a0ebc922fd52
children 6b5f90d9a10b
files libinterp/corefcn/graphics.cc
diffstat 1 files changed, 12 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/graphics.cc	Thu Apr 28 13:10:28 2016 +0200
+++ b/libinterp/corefcn/graphics.cc	Fri Apr 29 18:43:08 2016 +1000
@@ -2659,9 +2659,17 @@
   delete_graphics_object (gh_manager::lookup (val));
 }
 
+// Flag to stop redraws due to callbacks while deletion is in progress.
+static bool delete_executing = false;
+
 static void
 delete_graphics_objects (const NDArray vals)
 {
+  // Prevent redraw of partially deleted objects.
+  unwind_protect frame;
+  frame.protect_var (delete_executing);
+  delete_executing = true;
+
   for (octave_idx_type i = 0; i < vals.numel (); i++)
     delete_graphics_object (vals.elem (i));
 }
@@ -2722,7 +2730,8 @@
 
   hlist = do_figure_handle_list (true);
 
-  assert (hlist.numel () == 0);
+  if (hlist.numel () != 0)
+    warning ("gh_manager::do_close_all_figures: some graphics elements failed to close.");
 
   // Clear all callback objects from our list.
 
@@ -10715,7 +10724,8 @@
   frame.protect_var (Vdrawnow_requested, false);
   frame.protect_var (drawnow_executing);
 
-  if (++drawnow_executing <= 1)
+  // Redraw, unless we are in the middle of an existing redraw or deletion.
+  if (++drawnow_executing <= 1 && ! delete_executing)
     {
       gh_manager::auto_lock guard;