changeset 26277:e92a44730a6e stable

Rethrow exceptions from the GUI to the interpreter thread (bug #54920) * main-window.h/cc (octave_qapplication): New class derived from QApplication. (octave_qapplication::notify): Reimplement QApplication::notify to catch and rethrow octave exceptions that happen in QObjects event loop. (octave_qt_app::octave_qt_app): Instantiate an octave_qapplication rather than a QApplication. * GLCanvas.cc (GLCanvas::do_print): Let the first eventual exception, due to the absence of valid context, be handled downstream. Keep the try/catch around gl2ps_print because we still want to release the context in case of error.
author Pantxo Diribarne <pantxo.diribarne@gmail.com>
date Fri, 02 Nov 2018 22:38:28 +0100
parents 5535267e88ba
children 01fdb337fa20
files libgui/graphics/GLCanvas.cc libgui/src/main-window.cc libgui/src/main-window.h
diffstat 3 files changed, 40 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/graphics/GLCanvas.cc	Sat Dec 15 11:31:31 2018 +0100
+++ b/libgui/graphics/GLCanvas.cc	Fri Nov 02 22:38:28 2018 +0100
@@ -140,20 +140,22 @@
     if (obj.valid_object ())
       {
         graphics_object figObj (obj.get_ancestor ("figure"));
+        
+        // Make sure we have a valid current context
+        if (! begin_rendering ())
+          error ("print: no valid OpenGL offscreen context");
+        
         try
           {
-            // Make sure we have a valid current context
-            if (! begin_rendering ())
-              error ("print: no valid OpenGL offscreen context");
-
             octave::gl2ps_print (m_glfcns, figObj, file_cmd.toStdString (),
                                  term.toStdString ());
           }
         catch (octave::execution_exception& e)
           {
             octave_link::post_exception (std::current_exception ());
-            end_rendering ();
           }
+        
+        end_rendering ();
       }
   }
 
--- a/libgui/src/main-window.cc	Sat Dec 15 11:31:31 2018 +0100
+++ b/libgui/src/main-window.cc	Fri Nov 02 22:38:28 2018 +0100
@@ -2750,6 +2750,24 @@
     emit finished ();
   }
 
+  //! Reimplements QApplication::notify.
+  /*! Octave's own exceptions are caugh and rethrown in the interpreter
+      thread.*/
+  bool
+  octave_qapplication::notify (QObject *receiver, QEvent *ev)
+  {
+    try
+      {
+        return QApplication::notify (receiver, ev);
+      }
+    catch (octave::execution_exception&)
+      {
+        octave_link::post_exception (std::current_exception ());
+      }
+
+   return false;
+  }
+
   octave_qt_app::octave_qt_app (gui_application& app_context)
     : QObject (), m_app_context (app_context),
       m_argc (m_app_context.sys_argc ()),
@@ -2796,7 +2814,7 @@
     // Even if START_GUI is false, we still set up the QApplication so
     // that we can use Qt widgets for plot windows.
 
-    m_qt_app = new QApplication (m_argc, m_argv);
+    m_qt_app = new octave_qapplication (m_argc, m_argv);
 
     // Force left-to-right alignment (see bug #46204)
     m_qt_app->setLayoutDirection (Qt::LeftToRight);
--- a/libgui/src/main-window.h	Sat Dec 15 11:31:31 2018 +0100
+++ b/libgui/src/main-window.h	Fri Nov 02 22:38:28 2018 +0100
@@ -494,6 +494,19 @@
     bool m_connect_to_web;
   };
 
+  class octave_qapplication : public QApplication
+  {
+  public:
+
+    octave_qapplication (int& argc, char **argv)
+    : QApplication (argc, argv)
+    { }
+
+    virtual bool notify (QObject *receiver, QEvent *e) override;
+
+    ~octave_qapplication (void) { };
+  };
+
   class octave_qt_app : public QObject
   {
     Q_OBJECT
@@ -553,7 +566,7 @@
     int m_argc;
     char **m_argv;
 
-    QApplication *m_qt_app;
+    octave_qapplication *m_qt_app;
 
     QTranslator *m_qt_tr;
     QTranslator *m_gui_tr;