From 39cc7a0bae66d5b82ce9a9cc71a51f4efda52166 Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Fri, 30 Nov 2001 23:40:12 +0000
Subject: [PATCH] added wxWS_EX_TRANSIENT, added code for handling it and fixed
 wxLogGeneric to avoid crashes related to creating the log dialog as child of
 a window which is destroyed before it is

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@12781 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/latex/wx/window.tex |  4 ++++
 include/wx/defs.h        |  6 ++++++
 src/generic/logg.cpp     |  7 ++-----
 src/generic/progdlgg.cpp |  3 +++
 src/gtk/dialog.cpp       |  5 ++++-
 src/gtk1/dialog.cpp      |  5 ++++-
 src/msw/toplevel.cpp     | 15 +++++++++++----
 7 files changed, 34 insertions(+), 11 deletions(-)

diff --git a/docs/latex/wx/window.tex b/docs/latex/wx/window.tex
index 77e76e7270..106ff9e65d 100644
--- a/docs/latex/wx/window.tex
+++ b/docs/latex/wx/window.tex
@@ -2068,6 +2068,10 @@ for them is found. Using this style allows to prevent them from being
 propagated beyond this window. Notice that wxDialog has this style on by
 default for the reasons explained in the 
 \helpref{event processing overview}{eventprocessing}.}
+\twocolitem{\windowstyle{wxWS\_EX\_TRANSIENT}}{This can be used to prevent a
+window from being used as an implicit parent for the dialogs which were
+created without a parent. It is useful for the windows which can disappear at
+any moment as creating childs of such windows results in fatal problems.}
 \end{twocollist}
 
 \membersection{wxWindow::SetFocus}\label{wxwindowsetfocus}
diff --git a/include/wx/defs.h b/include/wx/defs.h
index 91b788c8f8..39578aaa31 100644
--- a/include/wx/defs.h
+++ b/include/wx/defs.h
@@ -784,6 +784,12 @@ enum wxBorder
 // flag on by default.
 #define wxWS_EX_BLOCK_EVENTS            0x00000002
 
+// don't use this window as an implicit parent for the other windows: this must
+// be used with transient windows as otherwise there is the risk of creating a
+// dialog/frame with this window as a parent which would lead to a crash if the
+// parent is destroyed before the child
+#define wxWS_EX_TRANSIENT               0x00000004
+
 /*
  * wxFrame/wxDialog style flags
  */
diff --git a/src/generic/logg.cpp b/src/generic/logg.cpp
index a0ff4d3672..155628d827 100644
--- a/src/generic/logg.cpp
+++ b/src/generic/logg.cpp
@@ -245,9 +245,6 @@ void wxLogGui::Flush()
     wxString title;
     title.Printf(titleFormat, appName.c_str());
 
-    // this is the best we can do here
-    wxWindow *parent = wxTheApp->GetTopWindow();
-
     size_t nMsgCount = m_aMessages.Count();
 
     // avoid showing other log dialogs until we're done with the dialog we're
@@ -263,7 +260,7 @@ void wxLogGui::Flush()
     {
 #if wxUSE_LOG_DIALOG
 
-        wxLogDialog dlg(parent,
+        wxLogDialog dlg(NULL,
                         m_aMessages, m_aSeverity, m_aTimes,
                         title, style);
 
@@ -295,7 +292,7 @@ void wxLogGui::Flush()
     // situation without it
     if ( !!str )
     {
-        wxMessageBox(str, title, wxOK | style, parent);
+        wxMessageBox(str, title, wxOK | style);
 
         // no undisplayed messages whatsoever
         Clear();
diff --git a/src/generic/progdlgg.cpp b/src/generic/progdlgg.cpp
index 94109c5660..33a8d648fc 100644
--- a/src/generic/progdlgg.cpp
+++ b/src/generic/progdlgg.cpp
@@ -89,6 +89,9 @@ wxProgressDialog::wxProgressDialog(wxString const &title,
                                    int style)
                 : wxDialog(parent, -1, title)
 {
+    // we may disappear at any moment, let the others know about it
+    SetExtraStyle(GetExtraStyle() | wxWS_EX_TRANSIENT);
+
     m_windowStyle |= style;
 
     bool hasAbortButton = (style & wxPD_CAN_ABORT) != 0;
diff --git a/src/gtk/dialog.cpp b/src/gtk/dialog.cpp
index e948cddd10..68a991a371 100644
--- a/src/gtk/dialog.cpp
+++ b/src/gtk/dialog.cpp
@@ -198,7 +198,10 @@ int wxDialog::ShowModal()
     if ( !GetParent() && !(GetWindowStyleFlag() & wxDIALOG_NO_PARENT) )
     {
         wxWindow *parent = wxTheApp->GetTopWindow();
-        if ( parent && parent != this && parent->IsBeingDeleted() )
+        if ( parent &&
+                parent != this &&
+                    parent->IsBeingDeleted() &&
+                        !(parent->GetExtraStyle() & wxWS_EX_TRANSIENT) )
         {
             m_parent = parent;
             gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(parent->m_widget) );
diff --git a/src/gtk1/dialog.cpp b/src/gtk1/dialog.cpp
index e948cddd10..68a991a371 100644
--- a/src/gtk1/dialog.cpp
+++ b/src/gtk1/dialog.cpp
@@ -198,7 +198,10 @@ int wxDialog::ShowModal()
     if ( !GetParent() && !(GetWindowStyleFlag() & wxDIALOG_NO_PARENT) )
     {
         wxWindow *parent = wxTheApp->GetTopWindow();
-        if ( parent && parent != this && parent->IsBeingDeleted() )
+        if ( parent &&
+                parent != this &&
+                    parent->IsBeingDeleted() &&
+                        !(parent->GetExtraStyle() & wxWS_EX_TRANSIENT) )
         {
             m_parent = parent;
             gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(parent->m_widget) );
diff --git a/src/msw/toplevel.cpp b/src/msw/toplevel.cpp
index 4482e103d9..a7b917f9f1 100644
--- a/src/msw/toplevel.cpp
+++ b/src/msw/toplevel.cpp
@@ -196,11 +196,18 @@ bool wxTopLevelWindowMSW::CreateDialog(const wxChar *dlgTemplate,
     {
         parent = wxTheApp->GetTopWindow();
 
-        // but don't use the window which is currently hidden as then the
-        // dialog would be hidden as well
-        if ( parent && !parent->IsShown() )
+        if ( parent )
         {
-            parent = NULL;
+            // don't use transient windows as parents, this is dangerous as it
+            // can lead to a crash if the parent is destroyed before the child
+            //
+            // also don't use the window which is currently hidden as then the
+            // dialog would be hidden as well
+            if ( (parent->GetExtraStyle() & wxWS_EX_TRANSIENT) ||
+                    !parent->IsShown() )
+            {
+                parent = NULL;
+            }
         }
     }
 
-- 
2.50.0

