From 3c8d8488eaa8ec5216fce1247764a082d1846814 Mon Sep 17 00:00:00 2001 From: Mike Gelfand Date: Sat, 10 Sep 2022 21:15:01 +0300 Subject: [PATCH] Run GTK dialogs in non-blocking fashion (#3805) GTK 4 drops blocking `run()` method for dialogs. Switch to non-blocking `show()` to support both GTK 3 and 4. --- gtk/Application.cc | 80 ++++++++++++++++++++++++++----------------- gtk/DetailsDialog.cc | 7 ++-- gtk/FileList.cc | 7 ++-- gtk/RelocateDialog.cc | 16 ++++++--- gtk/StatsDialog.cc | 32 +++++++++++------ 5 files changed, 90 insertions(+), 52 deletions(-) diff --git a/gtk/Application.cc b/gtk/Application.cc index 91daf6462..a41848eab 100644 --- a/gtk/Application.cc +++ b/gtk/Application.cc @@ -719,7 +719,7 @@ void Application::Impl::app_setup() if (!gtr_pref_flag_get(TR_KEY_user_has_given_informed_consent)) { - Gtk::MessageDialog w( + auto w = std::make_shared( *wind_, _("Transmission is a file sharing program. When you run a torrent, its data will be " "made available to others by means of upload. Any content you share is your sole responsibility."), @@ -727,19 +727,24 @@ void Application::Impl::app_setup() TR_GTK_MESSAGE_TYPE(OTHER), TR_GTK_BUTTONS_TYPE(NONE), true); - w.add_button(_("_Cancel"), TR_GTK_RESPONSE_TYPE(REJECT)); - w.add_button(_("I _Agree"), TR_GTK_RESPONSE_TYPE(ACCEPT)); - w.set_default_response(TR_GTK_RESPONSE_TYPE(ACCEPT)); - - if (w.run() == TR_GTK_RESPONSE_TYPE(ACCEPT)) - { - // only show it once - gtr_pref_flag_set(TR_KEY_user_has_given_informed_consent, true); - } - else - { - exit(0); - } + w->add_button(_("_Cancel"), TR_GTK_RESPONSE_TYPE(REJECT)); + w->add_button(_("I _Agree"), TR_GTK_RESPONSE_TYPE(ACCEPT)); + w->set_default_response(TR_GTK_RESPONSE_TYPE(ACCEPT)); + w->signal_response().connect( + [w](int response) mutable + { + if (response == TR_GTK_RESPONSE_TYPE(ACCEPT)) + { + // only show it once + gtr_pref_flag_set(TR_KEY_user_has_given_informed_consent, true); + w.reset(); + } + else + { + exit(0); + } + }); + w->show(); } } @@ -959,9 +964,16 @@ void Application::Impl::show_torrent_errors(Glib::ustring const& primary, std::v s << leader << ' ' << f << '\n'; } - Gtk::MessageDialog w(*wind_, primary, false, TR_GTK_MESSAGE_TYPE(ERROR), TR_GTK_BUTTONS_TYPE(CLOSE)); - w.set_secondary_text(s.str()); - w.run(); + auto w = std::make_shared( + *wind_, + primary, + false, + TR_GTK_MESSAGE_TYPE(ERROR), + TR_GTK_BUTTONS_TYPE(CLOSE), + true); + w->set_secondary_text(s.str()); + w->signal_response().connect([w](int /*response*/) mutable { w.reset(); }); + w->show(); files.clear(); } @@ -1296,25 +1308,31 @@ void Application::Impl::show_about_dialog() "Mike Gelfand", }); - Gtk::AboutDialog d; - d.set_authors(authors); - d.set_comments(_("A fast and easy BitTorrent client")); - d.set_copyright(_("Copyright © The Transmission Project")); - d.set_logo_icon_name(AppIconName); - d.set_name(Glib::get_application_name()); + auto d = std::make_shared(); + d->set_authors(authors); + d->set_comments(_("A fast and easy BitTorrent client")); + d->set_copyright(_("Copyright © The Transmission Project")); + d->set_logo_icon_name(AppIconName); + d->set_name(Glib::get_application_name()); /* Translators: translate "translator-credits" as your name to have it appear in the credits in the "About" dialog */ - d.set_translator_credits(_("translator-credits")); - d.set_version(LONG_VERSION_STRING); - d.set_website(uri); - d.set_website_label(uri); + d->set_translator_credits(_("translator-credits")); + d->set_version(LONG_VERSION_STRING); + d->set_website(uri); + d->set_website_label(uri); #ifdef SHOW_LICENSE - d.set_license(LICENSE); - d.set_wrap_license(true); + d->set_license(LICENSE); + d->set_wrap_license(true); #endif - d.set_transient_for(*wind_); - d.run(); + d->set_transient_for(*wind_); + d->set_modal(true); +#if GTKMM_CHECK_VERSION(4, 0, 0) + d->signal_close_request().connect_notify([d]() mutable { d.reset(); }); +#else + d->signal_delete_event().connect_notify([d](void* /*event*/) mutable { d.reset(); }); +#endif + d->show(); } bool Application::Impl::call_rpc_for_selected_torrents(std::string const& method) diff --git a/gtk/DetailsDialog.cc b/gtk/DetailsDialog.cc index 16dd41d6c..ce2069c71 100644 --- a/gtk/DetailsDialog.cc +++ b/gtk/DetailsDialog.cc @@ -2187,15 +2187,16 @@ void EditTrackersDialog::on_response(int response) } else { - Gtk::MessageDialog w( + auto w = std::make_shared( *this, _("List contains invalid URLs"), false, TR_GTK_MESSAGE_TYPE(ERROR), TR_GTK_BUTTONS_TYPE(CLOSE), true); - w.set_secondary_text(_("Please correct the errors and try again.")); - w.run(); + w->set_secondary_text(_("Please correct the errors and try again.")); + w->signal_response().connect([w](int /*response*/) mutable { w.reset(); }); + w->show(); do_destroy = false; } diff --git a/gtk/FileList.cc b/gtk/FileList.cc index 249544b32..3ec315b69 100644 --- a/gtk/FileList.cc +++ b/gtk/FileList.cc @@ -771,7 +771,7 @@ bool FileList::Impl::on_rename_done_idle(Glib::ustring const& path_string, Glib: } else { - Gtk::MessageDialog w( + auto w = std::make_shared( *static_cast(widget_.get_toplevel()), fmt::format( _("Couldn't rename '{old_path}' as '{path}': {error} ({error_code})"), @@ -783,8 +783,9 @@ bool FileList::Impl::on_rename_done_idle(Glib::ustring const& path_string, Glib: TR_GTK_MESSAGE_TYPE(ERROR), TR_GTK_BUTTONS_TYPE(CLOSE), true); - w.set_secondary_text(_("Please correct the errors and try again.")); - w.run(); + w->set_secondary_text(_("Please correct the errors and try again.")); + w->signal_response().connect([w](int /*response*/) mutable { w.reset(); }); + w->show(); } return false; diff --git a/gtk/RelocateDialog.cc b/gtk/RelocateDialog.cc index 68342be0a..afefc0442 100644 --- a/gtk/RelocateDialog.cc +++ b/gtk/RelocateDialog.cc @@ -87,15 +87,23 @@ bool RelocateDialog::Impl::onTimer() { if (done_ == TR_LOC_ERROR) { - Gtk::MessageDialog( + auto d = std::make_shared( *message_dialog_, _("Couldn't move torrent"), false, TR_GTK_MESSAGE_TYPE(ERROR), TR_GTK_BUTTONS_TYPE(CLOSE), - true) - .run(); - message_dialog_.reset(); + true); + + timer_.block(); + d->signal_response().connect( + [this, d](int /*response*/) mutable + { + timer_.unblock(); + d.reset(); + }); + + d->show(); } else if (done_ == TR_LOC_DONE) { diff --git a/gtk/StatsDialog.cc b/gtk/StatsDialog.cc index f2b69dc73..732ba7787 100644 --- a/gtk/StatsDialog.cc +++ b/gtk/StatsDialog.cc @@ -95,19 +95,29 @@ void StatsDialog::Impl::dialogResponse(int response) { if (response == TR_RESPONSE_RESET) { - Gtk::MessageDialog - w(dialog_, _("Reset your statistics?"), false, TR_GTK_MESSAGE_TYPE(QUESTION), TR_GTK_BUTTONS_TYPE(NONE), true); - w.add_button(_("_Cancel"), TR_GTK_RESPONSE_TYPE(CANCEL)); - w.add_button(_("_Reset"), TR_RESPONSE_RESET); - w.set_secondary_text( + auto w = std::make_shared( + dialog_, + _("Reset your statistics?"), + false, + TR_GTK_MESSAGE_TYPE(QUESTION), + TR_GTK_BUTTONS_TYPE(NONE), + true); + w->add_button(_("_Cancel"), TR_GTK_RESPONSE_TYPE(CANCEL)); + w->add_button(_("_Reset"), TR_RESPONSE_RESET); + w->set_secondary_text( _("These statistics are for your information only. " "Resetting them doesn't affect the statistics logged by your BitTorrent trackers.")); - - if (w.run() == TR_RESPONSE_RESET) - { - tr_sessionClearStats(core_->get_session()); - updateStats(); - } + w->signal_response().connect( + [this, w](int inner_response) mutable + { + if (inner_response == TR_RESPONSE_RESET) + { + tr_sessionClearStats(core_->get_session()); + updateStats(); + } + w.reset(); + }); + w->show(); } if (response == TR_GTK_RESPONSE_TYPE(CLOSE))