UI/Qt: Execute dialogs opened from the page asynchronously

Invoking exec() entirely blocks the UI application's main thread. Qt
explicitly recommends against this. In practice, it seems prevents some
IPC messages from being handled by the UI until the dialog is closed by
the user.

Instead, use open() (which is non-blocking) and set up a signal handler
to deal with the result.
This commit is contained in:
Timothy Flynn 2024-10-25 13:43:53 -04:00 committed by Andreas Kling
commit ea9abe26e1
Notes: github-actions[bot] 2024-10-26 09:26:32 +00:00

View file

@ -180,34 +180,46 @@ Tab::Tab(BrowserWindow* window, RefPtr<WebView::WebContentClient> parent_client,
view().on_request_alert = [this](auto const& message) { view().on_request_alert = [this](auto const& message) {
m_dialog = new QMessageBox(QMessageBox::Icon::Warning, "Ladybird", qstring_from_ak_string(message), QMessageBox::StandardButton::Ok, &view()); m_dialog = new QMessageBox(QMessageBox::Icon::Warning, "Ladybird", qstring_from_ak_string(message), QMessageBox::StandardButton::Ok, &view());
m_dialog->exec();
view().alert_closed(); QObject::connect(m_dialog, &QDialog::finished, this, [this]() {
m_dialog = nullptr; view().alert_closed();
m_dialog = nullptr;
});
m_dialog->open();
}; };
view().on_request_confirm = [this](auto const& message) { view().on_request_confirm = [this](auto const& message) {
m_dialog = new QMessageBox(QMessageBox::Icon::Question, "Ladybird", qstring_from_ak_string(message), QMessageBox::StandardButton::Ok | QMessageBox::StandardButton::Cancel, &view()); m_dialog = new QMessageBox(QMessageBox::Icon::Question, "Ladybird", qstring_from_ak_string(message), QMessageBox::StandardButton::Ok | QMessageBox::StandardButton::Cancel, &view());
auto result = m_dialog->exec();
view().confirm_closed(result == QMessageBox::StandardButton::Ok || result == QDialog::Accepted); QObject::connect(m_dialog, &QDialog::finished, this, [this](auto result) {
m_dialog = nullptr; view().confirm_closed(result == QMessageBox::StandardButton::Ok || result == QDialog::Accepted);
m_dialog = nullptr;
});
m_dialog->open();
}; };
view().on_request_prompt = [this](auto const& message, auto const& default_) { view().on_request_prompt = [this](auto const& message, auto const& default_) {
m_dialog = new QInputDialog(&view()); m_dialog = new QInputDialog(&view());
auto& dialog = static_cast<QInputDialog&>(*m_dialog);
auto& dialog = static_cast<QInputDialog&>(*m_dialog);
dialog.setWindowTitle("Ladybird"); dialog.setWindowTitle("Ladybird");
dialog.setLabelText(qstring_from_ak_string(message)); dialog.setLabelText(qstring_from_ak_string(message));
dialog.setTextValue(qstring_from_ak_string(default_)); dialog.setTextValue(qstring_from_ak_string(default_));
if (dialog.exec() == QDialog::Accepted) QObject::connect(m_dialog, &QDialog::finished, this, [this](auto result) {
view().prompt_closed(ak_string_from_qstring(dialog.textValue())); if (result == QDialog::Accepted) {
else auto& dialog = static_cast<QInputDialog&>(*m_dialog);
view().prompt_closed({}); view().prompt_closed(ak_string_from_qstring(dialog.textValue()));
} else {
view().prompt_closed({});
}
m_dialog = nullptr; m_dialog = nullptr;
});
m_dialog->open();
}; };
view().on_request_set_prompt_text = [this](auto const& message) { view().on_request_set_prompt_text = [this](auto const& message) {
@ -227,20 +239,26 @@ Tab::Tab(BrowserWindow* window, RefPtr<WebView::WebContentClient> parent_client,
view().on_request_color_picker = [this](Color current_color) { view().on_request_color_picker = [this](Color current_color) {
m_dialog = new QColorDialog(QColor(current_color.red(), current_color.green(), current_color.blue()), &view()); m_dialog = new QColorDialog(QColor(current_color.red(), current_color.green(), current_color.blue()), &view());
auto& dialog = static_cast<QColorDialog&>(*m_dialog);
auto& dialog = static_cast<QColorDialog&>(*m_dialog);
dialog.setWindowTitle("Ladybird"); dialog.setWindowTitle("Ladybird");
dialog.setOption(QColorDialog::ShowAlphaChannel, false); dialog.setOption(QColorDialog::ShowAlphaChannel, false);
QObject::connect(&dialog, &QColorDialog::currentColorChanged, this, [this](QColor const& color) { QObject::connect(&dialog, &QColorDialog::currentColorChanged, this, [this](QColor const& color) {
view().color_picker_update(Color(color.red(), color.green(), color.blue()), Web::HTML::ColorPickerUpdateState::Update); view().color_picker_update(Color(color.red(), color.green(), color.blue()), Web::HTML::ColorPickerUpdateState::Update);
}); });
if (dialog.exec() == QDialog::Accepted) QObject::connect(m_dialog, &QDialog::finished, this, [this](auto result) {
view().color_picker_update(Color(dialog.selectedColor().red(), dialog.selectedColor().green(), dialog.selectedColor().blue()), Web::HTML::ColorPickerUpdateState::Closed); if (result == QDialog::Accepted) {
else auto& dialog = static_cast<QColorDialog&>(*m_dialog);
view().color_picker_update({}, Web::HTML::ColorPickerUpdateState::Closed); view().color_picker_update(Color(dialog.selectedColor().red(), dialog.selectedColor().green(), dialog.selectedColor().blue()), Web::HTML::ColorPickerUpdateState::Closed);
} else {
view().color_picker_update({}, Web::HTML::ColorPickerUpdateState::Closed);
}
m_dialog = nullptr; m_dialog = nullptr;
});
m_dialog->open();
}; };
view().on_request_file_picker = [this](auto const& accepted_file_types, auto allow_multiple_files) { view().on_request_file_picker = [this](auto const& accepted_file_types, auto allow_multiple_files) {