Mercurial > octave
changeset 26520:278ae90567a7 stable
Don't use C++ callback to notify close request from Qt Figures (bug #54187)
* Figure.h/cc (Figure::close_figure_callback): Remove callback.
(Figure::eventNotifyBefore): Use gh_manager::post_callback rather than
octave_link::post_event to notify that a figure should be closed.
* graphics.in.h (graphics_event::create_mcode_event): New static function.
* graphics.cc (mcode_event): New class to handle direct mcode evaluation.
(gh_manager::do_post_callback): For "closerequestfcn" callback, create an
mcode_event and use the "close" function to make the figure current before
evaluating the actual closerequestfcn.
author | Pantxo Diribarne <pantxo.diribarne@gmail.com> |
---|---|
date | Fri, 11 Jan 2019 18:14:41 +0100 |
parents | 9ed51ca68352 |
children | 8b0c9dc0799a d6a4237a26b4 |
files | libgui/graphics/Figure.cc libgui/graphics/Figure.h libinterp/corefcn/graphics.cc libinterp/corefcn/graphics.in.h |
diffstat | 4 files changed, 60 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/libgui/graphics/Figure.cc Fri Jan 11 16:57:58 2019 +0100 +++ b/libgui/graphics/Figure.cc Fri Jan 11 18:14:41 2019 +0100 @@ -650,15 +650,6 @@ prop == "position"); } - void - Figure::close_figure_callback (void) - { - figure::properties& fp = properties<figure> (); - octave_value fnum = fp.get___myhandle__ ().as_octave_value (); - - Ffeval (ovl ("close", fnum)); - } - bool Figure::eventNotifyBefore (QObject *obj, QEvent *xevent) { @@ -697,7 +688,7 @@ { case QEvent::Close: xevent->ignore (); - octave_link::post_event (this, &Figure::close_figure_callback); + gh_manager::post_callback (m_handle, "closerequestfcn"); return true; default:
--- a/libgui/graphics/Figure.h Fri Jan 11 16:57:58 2019 +0100 +++ b/libgui/graphics/Figure.h Fri Jan 11 18:14:41 2019 +0100 @@ -108,8 +108,6 @@ void updateFigureToolBarAndMenuBar (void); void set_geometry (QRect r); - void close_figure_callback (void); - void enableMouseTracking (void); private slots:
--- a/libinterp/corefcn/graphics.cc Fri Jan 11 16:57:58 2019 +0100 +++ b/libinterp/corefcn/graphics.cc Fri Jan 11 18:14:41 2019 +0100 @@ -11358,6 +11358,38 @@ }; class +mcode_event : public base_graphics_event +{ +public: + mcode_event (const graphics_handle& h, const std::string& cmd, + int busyaction = base_graphics_event::QUEUE) + : base_graphics_event (busyaction), handle (h), mcode (cmd) + { } + + void execute (void) + { + if (! mcode.empty ()) + { + graphics_object go = gh_manager::get_object (handle); + if (go.valid_object ()) + { + octave_value cb (mcode); + gh_manager::execute_callback (handle, cb); + } + } + } + +private: + mcode_event (void) + : base_graphics_event (), handle (), mcode () + { } + +private: + graphics_handle handle; + std::string mcode; +}; + +class function_event : public base_graphics_event { public: @@ -11481,6 +11513,14 @@ } graphics_event +graphics_event::create_mcode_event (const graphics_handle& h, + const std::string& cmd, + int busyaction) +{ + return graphics_event (new mcode_event (h, cmd, busyaction)); +} + +graphics_event graphics_event::create_function_event (graphics_event::event_fcn fcn, void *data) { @@ -11562,7 +11602,6 @@ } // Copy CB because "function_value" method is non-const. - octave_value cb = cb_arg; if (cb.is_function () || cb.is_function_handle ()) @@ -11659,22 +11698,26 @@ caseless_str cname (name); int busyaction = base_graphics_event::QUEUE; - if (cname.compare ("deletefcn") - || cname.compare ("createfcn") - || (go.isa ("figure") - && cname.compare ("closerequestfcn")) - || ((go.isa ("figure") - || go.isa ("uipanel") + if (cname == "deletefcn" || cname == "createfcn" + || cname == "closerequestfcn" + || ((go.isa ("figure") || go.isa ("uipanel") || go.isa ("uibuttongroup")) - && (cname.compare ("resizefcn") - || cname.compare ("sizechangedfcn")))) + && (cname == "resizefcn" || cname == "sizechangedfcn"))) busyaction = base_graphics_event::INTERRUPT; else if (go.get_properties ().get_busyaction () == "cancel") busyaction = base_graphics_event::CANCEL; - - do_post_event (graphics_event::create_callback_event (h, name, data, - busyaction)); + // The "closerequestfcn" callback must be executed once the figure has + // been made current. Let "close" do the job. + if (cname == "closerequestfcn") + { + std::string cmd ("close (gcbf ());"); + do_post_event (graphics_event::create_mcode_event (h, cmd, + busyaction)); + } + else + do_post_event (graphics_event::create_callback_event (h, name, data, + busyaction)); } }
--- a/libinterp/corefcn/graphics.in.h Fri Jan 11 16:57:58 2019 +0100 +++ b/libinterp/corefcn/graphics.in.h Fri Jan 11 18:14:41 2019 +0100 @@ -6161,6 +6161,10 @@ int busyaction = base_graphics_event::QUEUE); static graphics_event + create_mcode_event (const graphics_handle& h, const std::string& cmd, + int busyaction); + + static graphics_event create_function_event (event_fcn fcn, void *data = nullptr); static graphics_event