From 24d5f1a6249b08a8b21854ecf001be7e07e5bf23 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Thu, 11 May 2017 14:20:33 +0200 Subject: [PATCH] Tweak/fix splash screen event-loop Prevent possible endless loop in Splash::display() and handle some related edge-cases and race conditions WRT expose_done and is_visible(). --- gtk2_ardour/ardour_ui.cc | 4 ++-- gtk2_ardour/splash.cc | 28 +++++++++++++++++++++------- gtk2_ardour/splash.h | 4 +++- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index d01a92ebf6..f48d4f527d 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -1282,7 +1282,7 @@ ARDOUR_UI::starting () BootMessage (string_compose (_("%1 is ready for use"), PROGRAM_NAME)); - if (splash && splash->is_visible()) { + if (splash) { // in 1 second, hide the splash screen Glib::signal_timeout().connect (sigc::bind (sigc::ptr_fun (_hide_splash), this), 1000); } @@ -1927,7 +1927,7 @@ ARDOUR_UI::open_recent_session () can_return = false; } - if (splash && splash->is_visible()) { + if (splash) { // in 1 second, hide the splash screen Glib::signal_timeout().connect (sigc::bind (sigc::ptr_fun (_hide_splash), this), 1000); } diff --git a/gtk2_ardour/splash.cc b/gtk2_ardour/splash.cc index 744a49fa4f..756749c6e6 100644 --- a/gtk2_ardour/splash.cc +++ b/gtk2_ardour/splash.cc @@ -21,6 +21,7 @@ #include "pbd/failed_constructor.h" #include "pbd/file_utils.h" +#include "pbd/stacktrace.h" #include "ardour/ardour.h" #include "ardour/filesystem_paths.h" @@ -99,6 +100,9 @@ Splash::Splash () Splash::~Splash () { + idle_connection.disconnect (); + expose_done = true; + hide (); the_splash = 0; } @@ -129,11 +133,19 @@ Splash::pop_back_for (Gtk::Window& win) void Splash::pop_front () { -#if defined __APPLE__ || defined PLATFORM_WINDOWS if (get_window()) { +#if defined __APPLE__ || defined PLATFORM_WINDOWS show (); - } +#else + gdk_window_restack(get_window()->gobj(), NULL, true); #endif + } +} + +void +Splash::hide () +{ + Gtk::Window::hide(); } void @@ -182,8 +194,9 @@ Splash::expose (GdkEventExpose* ev) */ if (expose_is_the_one) { - Glib::signal_idle().connect (sigc::mem_fun (this, &Splash::idle_after_expose), - GDK_PRIORITY_REDRAW+2); + idle_connection = Glib::signal_idle().connect ( + sigc::mem_fun (this, &Splash::idle_after_expose), + GDK_PRIORITY_REDRAW+2); } return true; @@ -216,7 +229,7 @@ Splash::display () present (); if (!was_mapped) { - while (!expose_done) { + while (!expose_done && gtk_events_pending()) { gtk_main_iteration (); } gdk_display_flush (gdk_display_get_default()); @@ -236,13 +249,14 @@ Splash::message (const string& msg) Glib::RefPtr win = darea.get_window(); if (win) { - expose_done = false; - if (win->is_visible ()) { win->invalidate_rect (Gdk::Rectangle (0, darea.get_height() - 30, darea.get_width(), 30), true); } else { darea.queue_draw (); } + if (expose_done) { + ARDOUR::GUIIdle (); + } } } diff --git a/gtk2_ardour/splash.h b/gtk2_ardour/splash.h index d92c443cf0..109b68a8be 100644 --- a/gtk2_ardour/splash.h +++ b/gtk2_ardour/splash.h @@ -47,6 +47,7 @@ public: void on_realize (); bool on_map_event (GdkEventAny*); void message (const std::string& msg); + void hide (); private: static Splash* the_splash; @@ -58,7 +59,8 @@ private: void boot_message (std::string); PBD::ScopedConnection msg_connection; - bool expose_done; + sigc::connection idle_connection; + volatile bool expose_done; bool expose_is_the_one; bool idle_after_expose (); }; -- 2.30.2