Skip to content

Commit

Permalink
improve exiting GUI in Qt6 by fixing crash in variable editor
Browse files Browse the repository at this point in the history
* octave-qobject.cc (~base_qobject): use deleteLater for main
  window and delete for dick widgets

* variable-editor.h: new class variable with a list of all used
  dock widgets for the open variables

* variable-editor.cc (variable_editor::variable_editor):
  initialize new class variable with list of current dock widgets;
  (variable_editor::focusInEvent): search in list of dock widgets
  instead of using findChildren;
  (variable_editor::~variable_editor): disconnect destroyed()
  signals of all variable dock widgets preventing a crash when
  dock widgets are destroyed after   variable editor, no need to
  delete tool bar here anymore;
  (variable_editor::edit_variable): add new dock widget to the list
  (variable_editor::variable_destroyed): search in list of dock widgets
  instead of using findChildren;
  (variable_editor::variable_focused): dito
  • Loading branch information
ttl-octave committed Aug 9, 2023
1 parent cd1218d commit 9917ed4
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 42 deletions.
31 changes: 12 additions & 19 deletions libgui/src/octave-qobject.cc
Original file line number Diff line number Diff line change
Expand Up @@ -361,33 +361,26 @@ base_qobject::~base_qobject ()
if (m_community_news)
m_community_news->close ();
}
else
{
m_main_window->deleteLater ();
}

if (m_terminal_widget)
m_terminal_widget->deleteLater ();
if (m_documentation_widget)
m_documentation_widget->deleteLater ();
if (m_file_browser_widget)
m_file_browser_widget->deleteLater ();
if (m_history_widget)
m_history_widget->deleteLater ();
if (m_workspace_widget)
m_workspace_widget->deleteLater ();
if (m_editor_widget)
m_editor_widget->deleteLater ();
if (m_variable_editor_widget)
m_variable_editor_widget->deleteLater ();
if (m_community_news)
m_community_news->deleteLater ();
delete m_terminal_widget;
delete m_documentation_widget;
delete m_file_browser_widget;
delete m_history_widget;
delete m_workspace_widget;
delete m_editor_widget;
delete m_variable_editor_widget;
delete m_community_news;

delete m_interpreter_qobj;
delete m_qsci_tr;
delete m_gui_tr;
delete m_qt_tr;
delete m_workspace_model;

if (m_main_window)
m_main_window->deleteLater ();

delete m_qapplication;

string_vector::delete_c_str_vec (m_argv);
Expand Down
56 changes: 33 additions & 23 deletions libgui/src/variable-editor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1128,6 +1128,7 @@ variable_editor::variable_editor (QWidget *p)
m_font (),
m_sel_font (),
m_table_colors (),
m_variables (QList<variable_dock_widget*> ()),
m_current_focus_vname (""),
m_hovered_focus_vname (""),
m_plot_mapper (nullptr),
Expand Down Expand Up @@ -1196,28 +1197,33 @@ void variable_editor::focusInEvent (QFocusEvent *ev)
}
else
{
QDockWidget *any_qdw = m_main->findChild<QDockWidget *> (QString (), Qt::FindDirectChildrenOnly);
if (any_qdw != nullptr)
bool focus_set = false;
for (qsizetype i = 0; i < m_variables.size (); i++)
{
activateWindow ();
any_qdw->setFocus ();
if (m_variables.at (i) != nullptr)
{
activateWindow ();
m_variables.at (i)->setFocus ();
focus_set = true;
break;
}
}
else
if (! focus_set)
setFocus();
}
}
}

variable_editor::~variable_editor ()
{
// FIXME: Maybe toolbar actions could be handled with signals and
// slots so that deleting the toolbar here would disconnect all
// toolbar actions and any other slots that might try to access the
// toolbar would work properly (I'm looking at you,
// handle_focus_change).

delete m_tool_bar;
m_tool_bar = nullptr;
// Disconnect the destroyed() signals from all variable_dock_widget
// other wise the non existing slot in variable_editor seems to be
// accessed in Qt6 leading to a crash (signal 6).
for (qsizetype i = 0; i < m_variables.size (); i++)
{
if (m_variables.at (i) != nullptr)
disconnect (m_variables.at (i), SIGNAL (destroyed (QObject*)), 0, 0);
}
}

void
Expand Down Expand Up @@ -1251,6 +1257,8 @@ variable_editor::edit_variable (const QString& name, const octave_value& val)

variable_dock_widget *page = new variable_dock_widget (this);

m_variables << page;

page->setObjectName (name);
m_main->addDockWidget (Qt::LeftDockWidgetArea, page);

Expand Down Expand Up @@ -1516,14 +1524,18 @@ variable_editor::variable_destroyed (QObject *obj)
m_focus_widget_vdw = nullptr;
}

if (m_tool_bar)
for (qsizetype i = 0; i < m_variables.size (); i++)
{
// If no variable pages remain, deactivate the tool bar.
QList<variable_dock_widget *> vdwlist = findChildren<variable_dock_widget *> ();
if (vdwlist.isEmpty ())
m_tool_bar->setEnabled (false);
if (m_variables.at (i) == obj)
{
m_variables.removeAt (i);
break;
}
}

if (m_tool_bar && m_variables.isEmpty ())
m_tool_bar->setEnabled (false);

QFocusEvent ev (QEvent::FocusIn);
focusInEvent (&ev);
}
Expand All @@ -1541,14 +1553,12 @@ variable_editor::variable_focused (const QString& name)
m_focus_widget_vdw = nullptr;
if (current != nullptr)
{
QList<variable_dock_widget *> vdwlist = findChildren<variable_dock_widget *> (QString (), Qt::FindDirectChildrenOnly);
for (int i = 0; i < vdwlist.size (); i++)
for (qsizetype i = 0; i < m_variables.size (); i++)
{
variable_dock_widget *vdw = vdwlist.at (i);
if (vdw->isAncestorOf (current))
if (m_variables.at (i)->isAncestorOf (current))
{
m_focus_widget = current;
m_focus_widget_vdw = vdw;
m_focus_widget_vdw = m_variables.at (i);
break;
}
}
Expand Down
2 changes: 2 additions & 0 deletions libgui/src/variable-editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,8 @@ protected slots:

void construct_tool_bar ();

QList<variable_dock_widget*> m_variables;

QString m_current_focus_vname;

QString m_hovered_focus_vname;
Expand Down

0 comments on commit 9917ed4

Please sign in to comment.