Specify parent window for popups. (#3406)
Some checks failed
CI / ${{ matrix.name }} (/usr/bin/gcc-12, /usr/bin/g++-12, ubuntu:22.04, linux-x86_64-system-deps, false, 3.11.x, true, false) (push) Has been cancelled
CI / ${{ matrix.name }} (default, default, 6) (push) Has been cancelled
CI / ${{ matrix.name }} (ubuntu:20.04, linux-x86_64, true, 3.6.x, false, false) (push) Has been cancelled
CI / ${{ matrix.name }} (ubuntu:20.04, tarball, false, 3.6.x, false, true) (push) Has been cancelled
CI / ${{ matrix.name }} (/usr/bin/gcc-7, /usr/bin/g++-7, ubuntu:18.04, linux-x86_64-qt5-system-deps, false, 3.6.x, 5, true) (push) Has been cancelled
CI / ${{ matrix.name }} (ubuntu:18.04, linux-x86_64-qt5, true, 3.6.x, 5, false) (push) Has been cancelled
CI / ${{ matrix.name }} () (push) Has been cancelled
CI / ${{ matrix.name }} (3.12.x) (push) Has been cancelled
CI / ${{ matrix.name }} (arm64, macos-arm64, macos-14, artifact_macos, true) (push) Has been cancelled
CI / ${{ matrix.name }} (false) (push) Has been cancelled
CI / ${{ matrix.name }} (windows-x86_64, windows-2019, artifact_windows, true, 3.12.x) (push) Has been cancelled
CI / ${{ matrix.name }} (x86_64, macos-x86_64, macos-13, true) (push) Has been cancelled
Docs / deploy (push) Has been cancelled
Linter / changes (push) Has been cancelled
CI / plugin-test-${{ matrix.name }} (build, artifact_macos, macos-arm64, macos-14) (push) Has been cancelled
CI / plugin-test-${{ matrix.name }} (build, artifact_windows, windows, windows-2019) (push) Has been cancelled
CI / plugin-test-${{ matrix.name }} (build-linux, artifact_linux, linux-x86_64, ubuntu-20.04) (push) Has been cancelled
Linter / clang-format (push) Has been cancelled
coverity-scan / latest (push) Has been cancelled

* 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.
This commit is contained in:
karliss 2025-01-22 13:39:35 +02:00 committed by GitHub
parent d5088a51ae
commit 3652cb7b23
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 40 additions and 24 deletions

View File

@ -6,6 +6,12 @@
#include <QObject>
#include <QMessageBox>
#include <QJsonObject>
#include <qwidget.h>
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?"),

View File

@ -2,12 +2,14 @@
#define IOMODESCONTROLLER_H
#include "core/Cutter.h"
#include <qwidget.h>
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 @@ public:
public slots:
bool askCommitUnsavedChanges();
private:
QWidget *parentWindow;
};
#endif // IOMODESCONTROLLER_H

View File

@ -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);

View File

@ -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);

View File

@ -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");

View File

@ -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) {

View File

@ -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);

View File

@ -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 <b>%1</b>?").arg(currTheme));
this, tr("Delete"), tr("Are you sure you want to delete <b>%1</b>?").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);
}
}
}

View File

@ -25,6 +25,7 @@ DisassemblyContextMenu::DisassemblyContextMenu(QWidget *parent, MainWindow *main
offset(0),
canCopy(false),
mainWindow(mainWindow),
ioModesController(mainWindow),
actionEditInstruction(this),
actionNopInstruction(this),
actionJmpReverse(this),

View File

@ -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;

View File

@ -44,6 +44,7 @@ HexWidget::HexWidget(QWidget *parent)
showAscii(true),
showExHex(true),
showExAddr(true),
ioModesController(parent),
warningTimer(this)
{
setMouseTracking(true);

View File

@ -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: