code: def wait_for_zero_canvases(middle_mouse_close=False):
      
      if not __ACTIVE:
          wait_failover(wait_for_zero_canvases)
          return
  
      @dispatcher
      def count_canvases():
          """
          Count the number of active canvases and finish gApplication.Run()
          if there are none remaining.
  
          incpy.ignore
          """
          if not get_visible_canvases():
              try:
                  ROOT.gSystem.ExitLoop()
              except AttributeError:
                  # We might be exiting and ROOT.gROOT will raise an AttributeError
                  pass
  
      @dispatcher
      def exit_application_loop():
          """
          Signal handler for CTRL-c to cause gApplication.Run() to finish.
  
          incpy.ignore
          """
          ROOT.gSystem.ExitLoop()
  
      # Handle CTRL-c
      sh = ROOT.TSignalHandler(ROOT.kSigInterrupt, True)
      sh.Add()
      sh.Connect("Notified()", "TPyDispatcher",
                 exit_application_loop, "Dispatch()")
  
      visible_canvases = get_visible_canvases()
  
      for canvas in visible_canvases:
          log.debug("waiting for canvas {0} to close".format(canvas.GetName()))
          canvas.Update()
  
          if middle_mouse_close:
              attach_event_handler(canvas)
  
          if not getattr(canvas, "_py_close_dispatcher_attached", False):
              # Attach a handler only once to each canvas
              canvas._py_close_dispatcher_attached = True
              canvas.Connect("Closed()", "TPyDispatcher",
                             count_canvases, "Dispatch()")
              keepalive(canvas, count_canvases)
  
      if visible_canvases and not ROOT.gROOT.IsBatch():
          run_application_until_done()
  
          # Disconnect from canvases
          for canvas in visible_canvases:
              if getattr(canvas, "_py_close_dispatcher_attached", False):
                  canvas._py_close_dispatcher_attached = False
                  canvas.Disconnect("Closed()", count_canvases, "Dispatch()")
docs: Wait for all canvases to be closed, or CTRL-c.
  
      If `middle_mouse_close`, middle click will shut the canvas.
  
      incpy.ignore