diff --git a/include/wx/gtk/dialog.h b/include/wx/gtk/dialog.h index b14cd11007..5023f7db67 100644 --- a/include/wx/gtk/dialog.h +++ b/include/wx/gtk/dialog.h @@ -11,6 +11,8 @@ #ifndef __GTKDIALOGH__ #define __GTKDIALOGH__ +class WXDLLIMPEXP_FWD_CORE wxGUIEventLoop; + //----------------------------------------------------------------------------- // wxDialog //----------------------------------------------------------------------------- @@ -47,7 +49,7 @@ public: private: // common part of all ctors void Init(); - + wxGUIEventLoop *m_modalLoop; DECLARE_DYNAMIC_CLASS(wxDialog) }; diff --git a/src/gtk/dialog.cpp b/src/gtk/dialog.cpp index dcdaec3cbe..d9d6dd1e9c 100644 --- a/src/gtk/dialog.cpp +++ b/src/gtk/dialog.cpp @@ -18,11 +18,16 @@ #include "wx/evtloop.h" +#include "wx/ptr_scpd.h" + #include // this is defined in src/gtk/toplevel.cpp extern int wxOpenModalDialogsCount; +wxDEFINE_TIED_SCOPED_PTR_TYPE(wxGUIEventLoop); + + //----------------------------------------------------------------------------- // wxDialog //----------------------------------------------------------------------------- @@ -31,6 +36,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxDialog,wxTopLevelWindow) void wxDialog::Init() { + m_modalLoop = NULL; m_returnCode = 0; m_modalShowing = false; m_themeEnabled = true; @@ -130,7 +136,11 @@ int wxDialog::ShowModal() // NOTE: gtk_window_set_modal internally calls gtk_grab_add() ! gtk_window_set_modal(GTK_WINDOW(m_widget), TRUE); - wxGUIEventLoop().Run(); + // Run modal dialog event loop. + { + wxGUIEventLoopTiedPtr modal(&m_modalLoop, new wxGUIEventLoop()); + m_modalLoop->Run(); + } gtk_window_set_modal(GTK_WINDOW(m_widget), FALSE); @@ -151,7 +161,10 @@ void wxDialog::EndModal( int retCode ) m_modalShowing = false; - gtk_main_quit(); + // Ensure Exit() is only called once. The dialog's event loop may be terminated + // externally due to an uncaught exception. + if (m_modalLoop && m_modalLoop->IsRunning()) + m_modalLoop->Exit(); Show( false ); }