From 21a2e5030c3498c3db102d97cd1ce56ecd268ddb Mon Sep 17 00:00:00 2001 From: Karliss Date: Tue, 21 Jan 2025 18:43:59 +0200 Subject: [PATCH 1/2] Specify parrent window for popups. Message boxes without parent are almost always a mistake. Such message boxes * Aren't properly position on top of current window, instead they get placed in the corner of screen possibly away from main window. * They get treated as separate window by window manager, but they still prevent proper interaction with main window. If you alt tab the message box can get lost, resulting in confusing behavior where you don't know why you can't interact with main window. --- src/common/IOModesController.cpp | 10 ++++++++-- src/common/IOModesController.h | 5 +++++ src/core/MainWindow.cpp | 5 +++-- src/dialogs/AboutDialog.cpp | 10 ++++++---- src/dialogs/GlibcHeapInfoDialog.cpp | 2 +- src/dialogs/RemoteDebugDialog.cpp | 8 ++++---- src/dialogs/WelcomeDialog.cpp | 2 +- src/dialogs/preferences/AppearanceOptionsWidget.cpp | 6 +++--- src/menus/DisassemblyContextMenu.cpp | 3 ++- src/widgets/DebugActions.cpp | 12 ++++++------ src/widgets/HexWidget.cpp | 1 + src/widgets/ProcessesWidget.cpp | 2 +- 12 files changed, 41 insertions(+), 25 deletions(-) diff --git a/src/common/IOModesController.cpp b/src/common/IOModesController.cpp index a3ba1edc1d..4072d6e71b 100644 --- a/src/common/IOModesController.cpp +++ b/src/common/IOModesController.cpp @@ -6,6 +6,12 @@ #include #include #include +#include + +IOModesController::IOModesController(QWidget *parentWindow) + : QObject(parentWindow), parentWindow(parentWindow) +{ +} bool IOModesController::canWrite() { @@ -48,7 +54,7 @@ bool IOModesController::prepareForWriting() return true; } - QMessageBox msgBox; + QMessageBox msgBox(parentWindow); msgBox.setIcon(QMessageBox::Icon::Critical); msgBox.setWindowTitle(QObject::tr("Write error")); msgBox.setText(QObject::tr( @@ -91,7 +97,7 @@ bool IOModesController::askCommitUnsavedChanges() // Check if there are uncommitted changes if (!allChangesComitted()) { QMessageBox::StandardButton ret = QMessageBox::question( - NULL, QObject::tr("Uncommitted changes"), + parentWindow, QObject::tr("Uncommitted changes"), QObject::tr("It seems that you have changes or patches that are not committed to " "the file.\n" "Do you want to commit them now?"), diff --git a/src/common/IOModesController.h b/src/common/IOModesController.h index 740a33593e..4a0a5890b2 100644 --- a/src/common/IOModesController.h +++ b/src/common/IOModesController.h @@ -2,12 +2,14 @@ #define IOMODESCONTROLLER_H #include "core/Cutter.h" +#include class IOModesController : public QObject { Q_OBJECT public: + IOModesController(QWidget *parent); enum class Mode { READ_ONLY, CACHE, WRITE }; bool prepareForWriting(); bool canWrite(); @@ -17,6 +19,9 @@ class IOModesController : public QObject public slots: bool askCommitUnsavedChanges(); + +private: + QWidget *parentWindow; }; #endif // IOMODESCONTROLLER_H diff --git a/src/core/MainWindow.cpp b/src/core/MainWindow.cpp index e7364d4387..095ca06e53 100644 --- a/src/core/MainWindow.cpp +++ b/src/core/MainWindow.cpp @@ -129,7 +129,8 @@ T *getNewInstance(MainWindow *m) using namespace Cutter; -MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), core(Core()), ui(new Ui::MainWindow) +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent), core(Core()), ui(new Ui::MainWindow), ioModesController(this) { tabsOnTop = false; configuration = Config(); @@ -538,7 +539,7 @@ void MainWindow::openNewFile(InitialOptions &options, bool skipOptionsDialog) if (options.script.isEmpty()) { QString script = QString("%1.rz").arg(this->filename); if (rz_file_exists(script.toStdString().data())) { - QMessageBox mb; + QMessageBox mb(this); mb.setWindowTitle(tr("Script loading")); mb.setText(tr("Do you want to load the '%1' script?").arg(script)); mb.setStandardButtons(QMessageBox::Yes | QMessageBox::No); diff --git a/src/dialogs/AboutDialog.cpp b/src/dialogs/AboutDialog.cpp index aaca9b47b5..fa7bfb11ed 100644 --- a/src/dialogs/AboutDialog.cpp +++ b/src/dialogs/AboutDialog.cpp @@ -95,7 +95,9 @@ void AboutDialog::on_checkForUpdatesButton_clicked() #if CUTTER_UPDATE_WORKER_AVAILABLE UpdateWorker updateWorker; - QProgressDialog waitDialog; + auto parentWindow = this; + + QProgressDialog waitDialog(parentWindow); QProgressBar *bar = new QProgressBar(&waitDialog); bar->setMaximum(0); @@ -104,12 +106,12 @@ void AboutDialog::on_checkForUpdatesButton_clicked() connect(&updateWorker, &UpdateWorker::checkComplete, &waitDialog, &QProgressDialog::cancel); connect(&updateWorker, &UpdateWorker::checkComplete, - [&updateWorker](const QVersionNumber &version, const QString &error) { + [&updateWorker, parentWindow](const QVersionNumber &version, const QString &error) { if (!error.isEmpty()) { - QMessageBox::critical(nullptr, tr("Error!"), error); + QMessageBox::critical(parentWindow, tr("Error!"), error); } else { if (version <= UpdateWorker::currentVersionNumber()) { - QMessageBox::information(nullptr, tr("Version control"), + QMessageBox::information(parentWindow, tr("Version control"), tr("Cutter is up to date!")); } else { updateWorker.showUpdateDialog(false); diff --git a/src/dialogs/GlibcHeapInfoDialog.cpp b/src/dialogs/GlibcHeapInfoDialog.cpp index a430fbb87b..304f3fb5d1 100644 --- a/src/dialogs/GlibcHeapInfoDialog.cpp +++ b/src/dialogs/GlibcHeapInfoDialog.cpp @@ -62,7 +62,7 @@ void GlibcHeapInfoDialog::updateFields() void GlibcHeapInfoDialog::saveChunkInfo() { - QMessageBox msgBox; + QMessageBox msgBox(this); msgBox.setText("Do you want to overwrite chunk metadata?"); msgBox.setInformativeText( "Any field which cannot be converted to a valid integer will be saved as zero"); diff --git a/src/dialogs/RemoteDebugDialog.cpp b/src/dialogs/RemoteDebugDialog.cpp index 7a70d11d73..600d22c214 100644 --- a/src/dialogs/RemoteDebugDialog.cpp +++ b/src/dialogs/RemoteDebugDialog.cpp @@ -53,7 +53,7 @@ bool RemoteDebugDialog::validate() } else if (debugger == WINDBG) { return validatePath(); } - QMessageBox msgBox; + QMessageBox msgBox(this); msgBox.setText(tr("Invalid debugger")); msgBox.exec(); return false; @@ -61,7 +61,7 @@ bool RemoteDebugDialog::validate() bool RemoteDebugDialog::validateIp() { - QMessageBox msgBox; + QMessageBox msgBox(this); QString ip = getIpOrPath(); if (QHostAddress(ip).isNull()) { @@ -74,7 +74,7 @@ bool RemoteDebugDialog::validateIp() bool RemoteDebugDialog::validatePath() { - QMessageBox msgBox; + QMessageBox msgBox(this); QString path = getIpOrPath(); if (!QFileInfo(path).exists()) { @@ -87,7 +87,7 @@ bool RemoteDebugDialog::validatePath() bool RemoteDebugDialog::validatePort() { - QMessageBox msgBox; + QMessageBox msgBox(this); int port = getPort(); if (port < 1 || port > 65535) { diff --git a/src/dialogs/WelcomeDialog.cpp b/src/dialogs/WelcomeDialog.cpp index 1422d70db8..4aa04e2a82 100644 --- a/src/dialogs/WelcomeDialog.cpp +++ b/src/dialogs/WelcomeDialog.cpp @@ -66,7 +66,7 @@ void WelcomeDialog::onLanguageComboBox_currentIndexChanged(int index) QString language = ui->languageComboBox->itemText(index); Config()->setLocaleByName(language); - QMessageBox mb; + QMessageBox mb(this); mb.setWindowTitle(tr("Language settings")); mb.setText(tr("Language will be changed after next application start.")); mb.setIcon(QMessageBox::Information); diff --git a/src/dialogs/preferences/AppearanceOptionsWidget.cpp b/src/dialogs/preferences/AppearanceOptionsWidget.cpp index 3ff4511ad0..15e3c8bc7d 100644 --- a/src/dialogs/preferences/AppearanceOptionsWidget.cpp +++ b/src/dialogs/preferences/AppearanceOptionsWidget.cpp @@ -156,16 +156,16 @@ void AppearanceOptionsWidget::on_deleteButton_clicked() { QString currTheme = ui->colorComboBox->currentText(); if (!ThemeWorker().isCustomTheme(currTheme)) { - QMessageBox::critical(nullptr, tr("Error"), ThemeWorker().deleteTheme(currTheme)); + QMessageBox::critical(this, tr("Error"), ThemeWorker().deleteTheme(currTheme)); return; } int ret = QMessageBox::question( - nullptr, tr("Delete"), tr("Are you sure you want to delete %1?").arg(currTheme)); + this, tr("Delete"), tr("Are you sure you want to delete %1?").arg(currTheme)); if (ret == QMessageBox::Yes) { QString err = ThemeWorker().deleteTheme(currTheme); updateThemeFromConfig(false); if (!err.isEmpty()) { - QMessageBox::critical(nullptr, tr("Error"), err); + QMessageBox::critical(this, tr("Error"), err); } } } diff --git a/src/menus/DisassemblyContextMenu.cpp b/src/menus/DisassemblyContextMenu.cpp index fbadfecac4..0a7b1a2e0c 100644 --- a/src/menus/DisassemblyContextMenu.cpp +++ b/src/menus/DisassemblyContextMenu.cpp @@ -25,6 +25,7 @@ DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent, MainWindow *main offset(0), canCopy(false), mainWindow(mainWindow), + ioModesController(mainWindow), actionEditInstruction(this), actionNopInstruction(this), actionJmpReverse(this), @@ -1096,7 +1097,7 @@ void DisassemblyContextMenu::on_actionEditFunction_triggered() fcn->cc = rz_str_constpool_get(&core->analysis->constpool, newCC.constData()); } - emit Core()->functionsChanged(); + emit Core() -> functionsChanged(); } } } diff --git a/src/widgets/DebugActions.cpp b/src/widgets/DebugActions.cpp index 76295793a9..d905ccf0cc 100644 --- a/src/widgets/DebugActions.cpp +++ b/src/widgets/DebugActions.cpp @@ -143,7 +143,7 @@ DebugActions::DebugActions(QToolBar *toolBar, MainWindow *main) : QObject(main), reverseActions = { actionStepBack, actionContinueBack }; connect(Core(), &CutterCore::debugProcessFinished, this, [=](int pid) { - QMessageBox msgBox; + QMessageBox msgBox(main); msgBox.setText(tr("Debugged process exited (") + QString::number(pid) + ")"); msgBox.exec(); }); @@ -262,7 +262,7 @@ void DebugActions::showDebugWarning() { if (!acceptedDebugWarning) { acceptedDebugWarning = true; - QMessageBox msgBox; + QMessageBox msgBox(main); msgBox.setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse); msgBox.setText(tr("Debug is currently in beta.\n") + tr("If you encounter any problems or have suggestions, please submit an " @@ -302,7 +302,7 @@ void DebugActions::onAttachedRemoteDebugger(bool successfully) return; if (!successfully) { - QMessageBox msgBox; + QMessageBox msgBox(main); msgBox.setText(tr("Error connecting.")); msgBox.exec(); attachRemoteDialog(); @@ -326,7 +326,7 @@ void DebugActions::attachRemoteDialog() if (!remoteDialog) { remoteDialog = new RemoteDebugDialog(main); } - QMessageBox msgBox; + QMessageBox msgBox(main); bool success = false; while (!success) { success = true; @@ -355,7 +355,7 @@ void DebugActions::attachProcessDialog() attachProcess(pid); } else { success = false; - QMessageBox msgBox; + QMessageBox msgBox(main); msgBox.setText(tr("Error attaching. No process selected!")); msgBox.exec(); } @@ -384,7 +384,7 @@ void DebugActions::startDebug() QFileInfo info(filename); if (!Core()->currentlyDebugging && !info.isExecutable()) { - QMessageBox msgBox; + QMessageBox msgBox(main); msgBox.setText(tr("File '%1' does not have executable permissions.").arg(filename)); msgBox.exec(); return; diff --git a/src/widgets/HexWidget.cpp b/src/widgets/HexWidget.cpp index c89337c69b..e153e6dced 100644 --- a/src/widgets/HexWidget.cpp +++ b/src/widgets/HexWidget.cpp @@ -44,6 +44,7 @@ HexWidget::HexWidget(QWidget *parent) showAscii(true), showExHex(true), showExAddr(true), + ioModesController(parent), warningTimer(this) { setMouseTracking(true); diff --git a/src/widgets/ProcessesWidget.cpp b/src/widgets/ProcessesWidget.cpp index 0a45a98e55..3b2d4dac2f 100644 --- a/src/widgets/ProcessesWidget.cpp +++ b/src/widgets/ProcessesWidget.cpp @@ -157,7 +157,7 @@ void ProcessesWidget::onActivated(const QModelIndex &index) // attach to any given id. If it isn't found simply update the UI. for (const auto &value : Core()->getAllProcesses()) { if (pid == value.pid) { - QMessageBox msgBox; + QMessageBox msgBox(this); switch (value.status) { case RZ_DBG_PROC_ZOMBIE: case RZ_DBG_PROC_DEAD: From bef6d6b042de54bdec1cb8bfbeb424a7c7876d05 Mon Sep 17 00:00:00 2001 From: Karliss Date: Tue, 21 Jan 2025 19:02:56 +0200 Subject: [PATCH 2/2] Format. --- src/menus/DisassemblyContextMenu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/menus/DisassemblyContextMenu.cpp b/src/menus/DisassemblyContextMenu.cpp index 0a7b1a2e0c..4943f54d13 100644 --- a/src/menus/DisassemblyContextMenu.cpp +++ b/src/menus/DisassemblyContextMenu.cpp @@ -1097,7 +1097,7 @@ void DisassemblyContextMenu::on_actionEditFunction_triggered() fcn->cc = rz_str_constpool_get(&core->analysis->constpool, newCC.constData()); } - emit Core() -> functionsChanged(); + emit Core()->functionsChanged(); } } }