Qt: Do not spin unnecessary additional event loops

Show the dialogs asynchronously so no new event loops are created. This
not only simplifies stack traces (reduces the nesting level) but also
prevents hard to debug problems (eg. Bug 15743) from happening.

Change-Id: I85821a1403839a5baca504b40efce0ede2f1e0cb
Reviewed-on: https://code.wireshark.org/review/34646
Reviewed-by: Gerald Combs <gerald@wireshark.org>
Petri-Dish: Gerald Combs <gerald@wireshark.org>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
Tomasz Moń 2019-09-29 11:39:40 +02:00 committed by Anders Broman
parent ef76d65fc6
commit f67eccedd9
14 changed files with 164 additions and 95 deletions

View File

@ -25,6 +25,7 @@
#include "ui/qt/widgets/copy_from_profile_button.h"
#include "ui/qt/widgets/wireshark_file_dialog.h"
#include <functional>
#include <QColorDialog>
#include <QMessageBox>
#include <QPushButton>
@ -127,13 +128,15 @@ ColoringRulesDialog::~ColoringRulesDialog()
void ColoringRulesDialog::checkUnknownColorfilters()
{
if (prefs.unknown_colorfilters) {
QMessageBox mb;
mb.setText(tr("Your coloring rules file contains unknown rules"));
mb.setInformativeText(tr("Wireshark doesn't recognize one or more of your coloring rules. "
QMessageBox *mb = new QMessageBox();
mb->setText(tr("Your coloring rules file contains unknown rules"));
mb->setInformativeText(tr("Wireshark doesn't recognize one or more of your coloring rules. "
"They have been disabled."));
mb.setStandardButtons(QMessageBox::Ok);
mb->setStandardButtons(QMessageBox::Ok);
mb.exec();
mb->setWindowModality(Qt::ApplicationModal);
mb->setAttribute(Qt::WA_DeleteOnClose);
mb->show();
prefs.unknown_colorfilters = FALSE;
}
}
@ -336,13 +339,23 @@ void ColoringRulesDialog::changeColor(bool foreground)
if (!current.isValid())
return;
QColorDialog color_dlg;
QColorDialog *color_dlg = new QColorDialog();
color_dlg->setCurrentColor(colorRuleModel_.data(current, foreground ? Qt::ForegroundRole : Qt::BackgroundRole).toString());
color_dlg.setCurrentColor(colorRuleModel_.data(current, foreground ? Qt::ForegroundRole : Qt::BackgroundRole).toString());
if (color_dlg.exec() == QDialog::Accepted) {
colorRuleModel_.setData(current, color_dlg.currentColor(), foreground ? Qt::ForegroundRole : Qt::BackgroundRole);
setColorButtons(current);
}
connect(color_dlg, &QColorDialog::colorSelected, std::bind(&ColoringRulesDialog::colorChanged, this, foreground, std::placeholders::_1));
color_dlg->setWindowModality(Qt::ApplicationModal);
color_dlg->setAttribute(Qt::WA_DeleteOnClose);
color_dlg->show();
}
void ColoringRulesDialog::colorChanged(bool foreground, const QColor &cc)
{
QModelIndex current = ui->coloringRulesTreeView->currentIndex();
if (!current.isValid())
return;
colorRuleModel_.setData(current, cc, foreground ? Qt::ForegroundRole : Qt::BackgroundRole);
setColorButtons(current);
}
void ColoringRulesDialog::on_fGPushButton_clicked()

View File

@ -41,6 +41,7 @@ protected:
private slots:
void copyFromProfile(QString fileName);
void colorRuleSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
void colorChanged(bool foreground, const QColor &cc);
void on_fGPushButton_clicked();
void on_bGPushButton_clicked();
void on_displayFilterPushButton_clicked();

View File

@ -16,6 +16,7 @@
#include <ui/qt/utils/color_utils.h>
#include "wireshark_application.h"
#include <functional>
#include <QFontDialog>
#include <QColorDialog>
@ -285,23 +286,29 @@ void FontColorPreferencesFrame::updateWidgets()
void FontColorPreferencesFrame::changeColor(pref_t *pref)
{
QColorDialog color_dlg;
QColorDialog *color_dlg = new QColorDialog();
color_t* color = prefs_get_color_value(pref, pref_stashed);
color_dlg.setCurrentColor(QColor(
color_dlg->setCurrentColor(QColor(
color->red >> 8,
color->green >> 8,
color->blue >> 8
));
if (color_dlg.exec() == QDialog::Accepted) {
QColor cc = color_dlg.currentColor();
color_t new_color;
new_color.red = cc.red() << 8 | cc.red();
new_color.green = cc.green() << 8 | cc.green();
new_color.blue = cc.blue() << 8 | cc.blue();
prefs_set_color_value(pref, new_color, pref_stashed);
updateWidgets();
}
connect(color_dlg, &QColorDialog::colorSelected, std::bind(&FontColorPreferencesFrame::colorChanged, this, pref, std::placeholders::_1));
color_dlg->setWindowModality(Qt::ApplicationModal);
color_dlg->setAttribute(Qt::WA_DeleteOnClose);
color_dlg->show();
}
void FontColorPreferencesFrame::colorChanged(pref_t *pref, const QColor &cc)
{
color_t new_color;
new_color.red = cc.red() << 8 | cc.red();
new_color.green = cc.green() << 8 | cc.green();
new_color.blue = cc.blue() << 8 | cc.blue();
prefs_set_color_value(pref, new_color, pref_stashed);
updateWidgets();
}
void FontColorPreferencesFrame::on_fontPushButton_clicked()

View File

@ -57,6 +57,7 @@ private:
void changeColor(pref_t *pref);
private slots:
void colorChanged(pref_t *pref, const QColor &cc);
void on_fontPushButton_clicked();
void on_activeFGPushButton_clicked();

View File

@ -1637,8 +1637,10 @@ void MainWindow::exportDissections(export_type_e export_type) {
capture_file *cf = capture_file_.capFile();
g_return_if_fail(cf);
ExportDissectionDialog ed_dlg(this, cf, export_type);
ed_dlg.exec();
ExportDissectionDialog *ed_dlg = new ExportDissectionDialog(this, cf, export_type);
ed_dlg->setWindowModality(Qt::ApplicationModal);
ed_dlg->setAttribute(Qt::WA_DeleteOnClose);
ed_dlg->show();
}
#ifdef Q_OS_WIN

View File

@ -84,6 +84,7 @@ class FileSetDialog;
class FilterDialog;
class FunnelStatistics;
class WelcomePage;
class PacketCommentDialog;
class PacketList;
class ProtoTree;
#if defined(HAVE_LIBNL) && defined(HAVE_NL80211)
@ -477,8 +478,11 @@ private slots:
void on_actionEditNextTimeReference_triggered();
void on_actionEditPreviousTimeReference_triggered();
void on_actionEditTimeShift_triggered();
void editTimeShiftFinished(int);
void on_actionEditPacketComment_triggered();
void editPacketCommentFinished(PacketCommentDialog* pc_dialog, int result);
void on_actionDeleteAllPacketComments_triggered();
void deleteAllPacketCommentsFinished(int result);
void on_actionEditConfigurationProfiles_triggered();
void showPreferencesDialog(QString pane_name);
void on_actionEditPreferences_triggered();

View File

@ -156,6 +156,7 @@ DIAG_ON(frame-larger-than=)
#include "wlan_statistics_dialog.h"
#include <ui/qt/widgets/wireless_timeline.h>
#include <functional>
#include <QClipboard>
#include <QFileInfo>
#include <QMessageBox>
@ -1645,7 +1646,6 @@ void MainWindow::softwareUpdateRequested() {
}
#endif
// File Menu
void MainWindow::on_actionFileOpen_triggered()
@ -1877,7 +1877,8 @@ void MainWindow::on_actionFilePrint_triggered()
pdlg_->cap_file_ = cf;
}
pdlg_->exec();
pdlg_->setWindowModality(Qt::ApplicationModal);
pdlg_->show();
}
// Edit Menu
@ -2074,11 +2075,20 @@ void MainWindow::on_actionEditPreviousTimeReference_triggered()
void MainWindow::on_actionEditTimeShift_triggered()
{
TimeShiftDialog ts_dialog(this, capture_file_.capFile());
TimeShiftDialog *ts_dialog = new TimeShiftDialog(this, capture_file_.capFile());
connect(ts_dialog, SIGNAL(finished(int)), this, SLOT(editTimeShiftFinished(int)));
connect(this, SIGNAL(setCaptureFile(capture_file*)),
&ts_dialog, SLOT(setCaptureFile(capture_file*)));
connect(&ts_dialog, SIGNAL(timeShifted()), packet_list_, SLOT(applyTimeShift()));
ts_dialog.exec();
ts_dialog, SLOT(setCaptureFile(capture_file*)));
connect(ts_dialog, SIGNAL(timeShifted()), packet_list_, SLOT(applyTimeShift()));
ts_dialog->setWindowModality(Qt::ApplicationModal);
ts_dialog->setAttribute(Qt::WA_DeleteOnClose);
ts_dialog->show();
}
void MainWindow::editTimeShiftFinished(int)
{
if (capture_file_.capFile()->unsaved_changes) {
updateForUnsavedChanges();
}
@ -2086,25 +2096,41 @@ void MainWindow::on_actionEditTimeShift_triggered()
void MainWindow::on_actionEditPacketComment_triggered()
{
PacketCommentDialog pc_dialog(capture_file_.capFile()->current_frame->num, this, packet_list_->packetComment());
if (pc_dialog.exec() == QDialog::Accepted) {
packet_list_->setPacketComment(pc_dialog.text());
PacketCommentDialog* pc_dialog;
pc_dialog = new PacketCommentDialog(capture_file_.capFile()->current_frame->num, this, packet_list_->packetComment());
connect(pc_dialog, &QDialog::finished, std::bind(&MainWindow::editPacketCommentFinished, this, pc_dialog, std::placeholders::_1));
pc_dialog->setWindowModality(Qt::ApplicationModal);
pc_dialog->setAttribute(Qt::WA_DeleteOnClose);
pc_dialog->show();
}
void MainWindow::editPacketCommentFinished(PacketCommentDialog* pc_dialog, int result)
{
if (result == QDialog::Accepted) {
packet_list_->setPacketComment(pc_dialog->text());
updateForUnsavedChanges();
}
}
void MainWindow::on_actionDeleteAllPacketComments_triggered()
{
QMessageBox msg_dialog;
QMessageBox *msg_dialog = new QMessageBox();
connect(msg_dialog, SIGNAL(finished(int)), this, SLOT(deleteAllPacketCommentsFinished(int)));
msg_dialog.setIcon(QMessageBox::Question);
msg_dialog.setText(tr("Are you sure you want to remove all packet comments?"));
msg_dialog->setIcon(QMessageBox::Question);
msg_dialog->setText(tr("Are you sure you want to remove all packet comments?"));
msg_dialog.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
msg_dialog.setDefaultButton(QMessageBox::Ok);
msg_dialog->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
msg_dialog->setDefaultButton(QMessageBox::Ok);
if (msg_dialog.exec() == QMessageBox::Ok)
{
msg_dialog->setWindowModality(Qt::ApplicationModal);
msg_dialog->setAttribute(Qt::WA_DeleteOnClose);
msg_dialog->show();
}
void MainWindow::deleteAllPacketCommentsFinished(int result)
{
if (result == QMessageBox::Ok) {
/* XXX Do we need a wait/hourglass for large files? */
packet_list_->deleteAllPacketComments();
updateForUnsavedChanges();
@ -2113,23 +2139,23 @@ void MainWindow::on_actionDeleteAllPacketComments_triggered()
void MainWindow::on_actionEditConfigurationProfiles_triggered()
{
ProfileDialog cp_dialog;
cp_dialog.exec();
ProfileDialog *cp_dialog = new ProfileDialog();
cp_dialog->setWindowModality(Qt::ApplicationModal);
cp_dialog->setAttribute(Qt::WA_DeleteOnClose);
cp_dialog->show();
}
void MainWindow::showPreferencesDialog(QString pane_name)
{
PreferencesDialog pref_dialog(this);
PreferencesDialog *pref_dialog = new PreferencesDialog(this);
connect(pref_dialog, SIGNAL(finished(int)), wsApp, SLOT(flushAppSignals()));
saveWindowGeometry(); // Save in case the layout panes are rearranged
pref_dialog.setPane(pane_name);
pref_dialog.exec();
// Emitting PacketDissectionChanged directly from a QDialog can cause
// problems on macOS.
wsApp->flushAppSignals();
pref_dialog->setPane(pane_name);
pref_dialog->setWindowModality(Qt::ApplicationModal);
pref_dialog->setAttribute(Qt::WA_DeleteOnClose);
pref_dialog->show();
}
void MainWindow::on_actionEditPreferences_triggered()
@ -2341,12 +2367,15 @@ void MainWindow::on_actionViewColorizePacketList_triggered(bool checked) {
void MainWindow::on_actionViewColoringRules_triggered()
{
ColoringRulesDialog coloring_rules_dialog(this);
connect(&coloring_rules_dialog, SIGNAL(accepted()),
ColoringRulesDialog *coloring_rules_dialog = new ColoringRulesDialog(this);
connect(coloring_rules_dialog, SIGNAL(accepted()),
packet_list_, SLOT(recolorPackets()));
connect(&coloring_rules_dialog, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
connect(coloring_rules_dialog, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)));
coloring_rules_dialog.exec();
coloring_rules_dialog->setWindowModality(Qt::ApplicationModal);
coloring_rules_dialog->setAttribute(Qt::WA_DeleteOnClose);
coloring_rules_dialog->show();
}
// actionViewColorizeConversation1 - 10
@ -2623,12 +2652,12 @@ void MainWindow::on_actionAnalyzeDisplayFilterMacros_triggered()
{
struct epan_uat* dfm_uat;
dfilter_macro_get_uat(&dfm_uat);
UatDialog uat_dlg(parentWidget(), dfm_uat);
UatDialog *uat_dlg = new UatDialog(parentWidget(), dfm_uat);
connect(uat_dlg, SIGNAL(finished(int)), wsApp, SLOT(flushAppSignals()));
uat_dlg.exec();
// Emitting PacketDissectionChanged directly from a QDialog can cause
// problems on macOS.
wsApp->flushAppSignals();
uat_dlg->setWindowModality(Qt::ApplicationModal);
uat_dlg->setAttribute(Qt::WA_DeleteOnClose);
uat_dlg->show();
}
void MainWindow::on_actionAnalyzeCreateAColumn_triggered()
@ -2672,12 +2701,12 @@ void MainWindow::applyExportObject()
void MainWindow::on_actionAnalyzeEnabledProtocols_triggered()
{
EnabledProtocolsDialog enable_proto_dialog(this);
enable_proto_dialog.exec();
EnabledProtocolsDialog *enable_proto_dialog = new EnabledProtocolsDialog(this);
connect(enable_proto_dialog, SIGNAL(finished(int)), wsApp, SLOT(flushAppSignals()));
// Emitting PacketDissectionChanged directly from a QDialog can cause
// problems on macOS.
wsApp->flushAppSignals();
enable_proto_dialog->setWindowModality(Qt::ApplicationModal);
enable_proto_dialog->setAttribute(Qt::WA_DeleteOnClose);
enable_proto_dialog->show();
}
void MainWindow::on_actionAnalyzeDecodeAs_triggered()
@ -2688,12 +2717,12 @@ void MainWindow::on_actionAnalyzeDecodeAs_triggered()
create_new = true;
}
DecodeAsDialog da_dialog(this, capture_file_.capFile(), create_new);
da_dialog.exec();
DecodeAsDialog *da_dialog = new DecodeAsDialog(this, capture_file_.capFile(), create_new);
connect(da_dialog, SIGNAL(finished(int)), wsApp, SLOT(flushAppSignals()));
// Emitting PacketDissectionChanged directly from a QDialog can cause
// problems on macOS.
wsApp->flushAppSignals();
da_dialog->setWindowModality(Qt::ApplicationModal);
da_dialog->setAttribute(Qt::WA_DeleteOnClose);
da_dialog->show();
}
void MainWindow::on_actionAnalyzeReloadLuaPlugins_triggered()

View File

@ -476,8 +476,10 @@ void ModulePreferencesScrollArea::uatPushButtonClicked()
pref_t *pref = VariantPointer<pref_t>::asPtr(uat_pb->property(pref_prop_));
if (!pref) return;
UatDialog uat_dlg(this, prefs_get_uat_value(pref));
uat_dlg.exec();
UatDialog *uat_dlg = new UatDialog(this, prefs_get_uat_value(pref));
uat_dlg->setWindowModality(Qt::ApplicationModal);
uat_dlg->setAttribute(Qt::WA_DeleteOnClose);
uat_dlg->show();
}
void ModulePreferencesScrollArea::saveFilenamePushButtonClicked()

View File

@ -595,12 +595,11 @@ void PacketList::ctxDecodeAsDialog()
return;
bool create_new = da_action->property("create_new").toBool();
DecodeAsDialog da_dialog(this, cap_file_, create_new);
da_dialog.exec();
// Emitting PacketDissectionChanged directly from a QDialog can cause
// problems on macOS.
wsApp->flushAppSignals();
DecodeAsDialog *da_dialog = new DecodeAsDialog(this, cap_file_, create_new);
connect(da_dialog, SIGNAL(finished(int)), wsApp, SLOT(flushAppSignals()));
da_dialog->setWindowModality(Qt::ApplicationModal);
da_dialog->setAttribute(Qt::WA_DeleteOnClose);
da_dialog->show();
}
// Auto scroll if:

View File

@ -83,11 +83,11 @@ public:
}
void showUatDialog() {
UatDialog uat_dlg(parentWidget(), prefs_get_uat_value(pref_));
uat_dlg.exec();
// Emitting PacketDissectionChanged directly from a QDialog can cause
// problems on macOS.
wsApp->flushAppSignals();
UatDialog *uat_dlg = new UatDialog(parentWidget(), prefs_get_uat_value(pref_));
connect(uat_dlg, SIGNAL(finished(int)), wsApp, SLOT(flushAppSignals()));
uat_dlg->setWindowModality(Qt::ApplicationModal);
uat_dlg->setAttribute(Qt::WA_DeleteOnClose);
uat_dlg->show();
}
private:

View File

@ -493,8 +493,10 @@ void CaptureFilterEdit::applyCaptureFilter()
void CaptureFilterEdit::saveFilter()
{
FilterDialog capture_filter_dlg(window(), FilterDialog::CaptureFilter, text());
capture_filter_dlg.exec();
FilterDialog *capture_filter_dlg = new FilterDialog(window(), FilterDialog::CaptureFilter, text());
capture_filter_dlg->setWindowModality(Qt::ApplicationModal);
capture_filter_dlg->setAttribute(Qt::WA_DeleteOnClose);
capture_filter_dlg->show();
}
void CaptureFilterEdit::removeFilter()
@ -521,8 +523,10 @@ void CaptureFilterEdit::removeFilter()
void CaptureFilterEdit::showFilters()
{
FilterDialog capture_filter_dlg(window(), FilterDialog::CaptureFilter);
capture_filter_dlg.exec();
FilterDialog *capture_filter_dlg = new FilterDialog(window(), FilterDialog::CaptureFilter);
capture_filter_dlg->setWindowModality(Qt::ApplicationModal);
capture_filter_dlg->setAttribute(Qt::WA_DeleteOnClose);
capture_filter_dlg->show();
}
void CaptureFilterEdit::prepareFilter()

View File

@ -482,8 +482,10 @@ void DisplayFilterEdit::changeEvent(QEvent* event)
void DisplayFilterEdit::saveFilter()
{
FilterDialog display_filter_dlg(window(), FilterDialog::DisplayFilter, text());
display_filter_dlg.exec();
FilterDialog *display_filter_dlg = new FilterDialog(window(), FilterDialog::DisplayFilter, text());
display_filter_dlg->setWindowModality(Qt::ApplicationModal);
display_filter_dlg->setAttribute(Qt::WA_DeleteOnClose);
display_filter_dlg->show();
}
void DisplayFilterEdit::removeFilter()
@ -510,8 +512,10 @@ void DisplayFilterEdit::removeFilter()
void DisplayFilterEdit::showFilters()
{
FilterDialog display_filter_dlg(window(), FilterDialog::DisplayFilter);
display_filter_dlg.exec();
FilterDialog *display_filter_dlg = new FilterDialog(window(), FilterDialog::DisplayFilter);
display_filter_dlg->setWindowModality(Qt::ApplicationModal);
display_filter_dlg->setAttribute(Qt::WA_DeleteOnClose);
display_filter_dlg->show();
}
void DisplayFilterEdit::showExpressionPrefs()

View File

@ -213,8 +213,10 @@ void FieldFilterEdit::changeEvent(QEvent* event)
void FieldFilterEdit::showFilters()
{
FilterDialog display_filter_dlg(window(), FilterDialog::DisplayFilter);
display_filter_dlg.exec();
FilterDialog *display_filter_dlg = new FilterDialog(window(), FilterDialog::DisplayFilter);
display_filter_dlg->setWindowModality(Qt::ApplicationModal);
display_filter_dlg->setAttribute(Qt::WA_DeleteOnClose);
display_filter_dlg->show();
}
void FieldFilterEdit::prepareFilter()

View File

@ -78,9 +78,6 @@ public:
// dialogs on macOS can be problematic. Dialogs should call queueAppSignal
// instead.
void queueAppSignal(AppSignal signal) { app_signals_ << signal; }
// Flush queued app signals. Should be called from the main window after
// each dialog that calls queueAppSignal closes.
void flushAppSignals();
void emitStatCommandSignal(const QString &menu_path, const char *arg, void *userdata);
void emitTapParameterSignal(const QString cfg_abbr, const QString arg, void *userdata);
void addDynamicMenuGroupItem(int group, QAction *sg_action);
@ -206,6 +203,10 @@ public slots:
void captureEventHandler(CaptureEvent);
// Flush queued app signals. Should be called from the main window after
// each dialog that calls queueAppSignal closes.
void flushAppSignals();
private slots:
void updateTaps();