From 9ff9d30c0aab3b281ef9b380eac17435556c5088 Mon Sep 17 00:00:00 2001
From: Paul Cornett <paulcor@bullseye.com>
Date: Tue, 26 Aug 2008 16:19:23 +0000
Subject: [PATCH] Hold a reference on m_widget for the life of the associated
 wxWindow object. This allows removing some ugly hacks, and leaking of
 GtkWidgets by wxNotebook.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@55288 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 include/wx/gtk/filedlg.h |  2 +-
 src/gtk/animate.cpp      |  1 +
 src/gtk/bmpbuttn.cpp     |  1 +
 src/gtk/bmpcbox.cpp      |  9 +--------
 src/gtk/button.cpp       |  1 +
 src/gtk/calctrl.cpp      |  1 +
 src/gtk/checkbox.cpp     |  1 +
 src/gtk/choice.cpp       |  1 +
 src/gtk/clrpicker.cpp    |  1 +
 src/gtk/collpane.cpp     |  1 +
 src/gtk/colordlg.cpp     |  2 ++
 src/gtk/combobox.cpp     |  1 +
 src/gtk/dataview.cpp     |  1 +
 src/gtk/dirdlg.cpp       |  1 +
 src/gtk/filectrl.cpp     |  1 +
 src/gtk/filedlg.cpp      | 12 ++++++++++++
 src/gtk/filepicker.cpp   | 14 ++------------
 src/gtk/fontdlg.cpp      |  1 +
 src/gtk/fontpicker.cpp   |  1 +
 src/gtk/gauge.cpp        |  1 +
 src/gtk/hyperlink.cpp    |  1 +
 src/gtk/listbox.cpp      |  3 ++-
 src/gtk/mdi.cpp          |  1 +
 src/gtk/menu.cpp         |  2 ++
 src/gtk/msgdlg.cpp       |  3 +++
 src/gtk/notebook.cpp     |  9 +++------
 src/gtk/popupwin.cpp     |  1 +
 src/gtk/radiobox.cpp     |  1 +
 src/gtk/radiobut.cpp     |  1 +
 src/gtk/scrolbar.cpp     |  1 +
 src/gtk/slider.cpp       |  1 +
 src/gtk/spinbutt.cpp     |  1 +
 src/gtk/spinctrl.cpp     |  1 +
 src/gtk/statbmp.cpp      |  1 +
 src/gtk/statbox.cpp      |  1 +
 src/gtk/statline.cpp     |  1 +
 src/gtk/stattext.cpp     |  1 +
 src/gtk/taskbar.cpp      |  1 +
 src/gtk/tbargtk.cpp      |  7 +------
 src/gtk/textctrl.cpp     |  1 +
 src/gtk/tglbtn.cpp       |  2 ++
 src/gtk/toplevel.cpp     |  2 ++
 src/gtk/window.cpp       | 17 +++++++++--------
 43 files changed, 72 insertions(+), 42 deletions(-)

diff --git a/include/wx/gtk/filedlg.h b/include/wx/gtk/filedlg.h
index f81d91ca69..65054227e6 100644
--- a/include/wx/gtk/filedlg.h
+++ b/include/wx/gtk/filedlg.h
@@ -30,7 +30,7 @@ public:
                  const wxPoint& pos = wxDefaultPosition,
                  const wxSize& sz = wxDefaultSize,
                  const wxString& name = wxFileDialogNameStr);
-    virtual ~wxFileDialog() { delete m_extraControl; }
+    virtual ~wxFileDialog();
 
     virtual wxString GetPath() const;
     virtual void GetPaths(wxArrayString& paths) const;
diff --git a/src/gtk/animate.cpp b/src/gtk/animate.cpp
index 22cd588406..67dd5aac99 100644
--- a/src/gtk/animate.cpp
+++ b/src/gtk/animate.cpp
@@ -211,6 +211,7 @@ bool wxAnimationCtrl::Create( wxWindow *parent, wxWindowID id,
     SetWindowStyle(style);
 
     m_widget = gtk_image_new();
+    g_object_ref(m_widget);
     gtk_widget_show(m_widget);
 
     m_parent->DoAddChild( this );
diff --git a/src/gtk/bmpbuttn.cpp b/src/gtk/bmpbuttn.cpp
index 916cbf0f16..7920f09130 100644
--- a/src/gtk/bmpbuttn.cpp
+++ b/src/gtk/bmpbuttn.cpp
@@ -137,6 +137,7 @@ bool wxBitmapButton::Create( wxWindow *parent,
     m_bmpNormal = bitmap;
 
     m_widget = gtk_button_new();
+    g_object_ref(m_widget);
 
     if (style & wxNO_BORDER)
        gtk_button_set_relief( GTK_BUTTON(m_widget), GTK_RELIEF_NONE );
diff --git a/src/gtk/bmpcbox.cpp b/src/gtk/bmpcbox.cpp
index 88e4dcb9a6..0378a0a0df 100644
--- a/src/gtk/bmpcbox.cpp
+++ b/src/gtk/bmpcbox.cpp
@@ -32,14 +32,6 @@
 
 #include "wx/gtk/private.h"
 
-#ifdef __WXGTK24__
-    #include "wx/gtk/win_gtk.h"
-
-    #include <gobject/gvaluecollector.h>
-    #include <gtk/gtktreemodel.h>
-#endif
-
-
 // ============================================================================
 // implementation
 // ============================================================================
@@ -133,6 +125,7 @@ void wxBitmapComboBox::GTKCreateComboBoxWidget()
         m_entry = GTK_ENTRY( GTK_BIN(m_widget)->child );
         gtk_entry_set_editable( m_entry, TRUE );
     }
+    g_object_ref(m_widget);
 
     // This must be called as gtk_combo_box_entry_new_with_model adds
     // automatically adds one text column.
diff --git a/src/gtk/button.cpp b/src/gtk/button.cpp
index bee9497fbc..331298c383 100644
--- a/src/gtk/button.cpp
+++ b/src/gtk/button.cpp
@@ -100,6 +100,7 @@ bool wxButton::Create(wxWindow *parent,
     }
 
     m_widget = gtk_button_new_with_mnemonic("");
+    g_object_ref(m_widget);
 
     float x_alignment = 0.5;
     if (HasFlag(wxBU_LEFT))
diff --git a/src/gtk/calctrl.cpp b/src/gtk/calctrl.cpp
index 313a3e3dc6..2da9293d0b 100644
--- a/src/gtk/calctrl.cpp
+++ b/src/gtk/calctrl.cpp
@@ -88,6 +88,7 @@ bool wxGtkCalendarCtrl::Create(wxWindow *parent,
     }
 
     m_widget = gtk_calendar_new();
+    g_object_ref(m_widget);
     SetDate(date.IsValid() ? date : wxDateTime::Today());
 
     if (style & wxCAL_NO_MONTH_CHANGE)
diff --git a/src/gtk/checkbox.cpp b/src/gtk/checkbox.cpp
index 1e4bcf5922..3e925d1160 100644
--- a/src/gtk/checkbox.cpp
+++ b/src/gtk/checkbox.cpp
@@ -144,6 +144,7 @@ bool wxCheckBox::Create(wxWindow *parent,
         m_widgetLabel = GTK_BIN(m_widgetCheckbox)->child;
         m_widget = m_widgetCheckbox;
     }
+    g_object_ref(m_widget);
     SetLabel( label );
 
     g_signal_connect (m_widgetCheckbox, "toggled",
diff --git a/src/gtk/choice.cpp b/src/gtk/choice.cpp
index 97129ba2f1..8ccb592059 100644
--- a/src/gtk/choice.cpp
+++ b/src/gtk/choice.cpp
@@ -79,6 +79,7 @@ bool wxChoice::Create( wxWindow *parent, wxWindowID id,
     }
 
     m_widget = gtk_combo_box_new_text();
+    g_object_ref(m_widget);
 
     Append(n, choices);
 
diff --git a/src/gtk/clrpicker.cpp b/src/gtk/clrpicker.cpp
index de19aa7c4d..0142859111 100644
--- a/src/gtk/clrpicker.cpp
+++ b/src/gtk/clrpicker.cpp
@@ -68,6 +68,7 @@ bool wxColourButton::Create( wxWindow *parent, wxWindowID id,
 
     m_colour = col;
     m_widget = gtk_color_button_new_with_color( m_colour.GetColor() );
+    g_object_ref(m_widget);
     gtk_widget_show(m_widget);
 
     // GtkColourButton signals
diff --git a/src/gtk/collpane.cpp b/src/gtk/collpane.cpp
index d312306ca3..6c27ad35ef 100644
--- a/src/gtk/collpane.cpp
+++ b/src/gtk/collpane.cpp
@@ -189,6 +189,7 @@ bool wxCollapsiblePane::Create(wxWindow *parent,
 
     m_widget =
         gtk_expander_new_with_mnemonic(wxGTK_CONV(GTKConvertMnemonics(label)));
+    g_object_ref(m_widget);
 
     // see the gtk_collapsiblepane_expanded_callback comments to understand why
     // we connect to the "notify::expanded" signal instead of the more common
diff --git a/src/gtk/colordlg.cpp b/src/gtk/colordlg.cpp
index 07623444a3..8300d82f83 100644
--- a/src/gtk/colordlg.cpp
+++ b/src/gtk/colordlg.cpp
@@ -53,6 +53,8 @@ bool wxColourDialog::Create(wxWindow *parent, wxColourData *data)
     m_widget = gtk_color_selection_dialog_new(wxGTK_CONV(title));
 #endif // wxUSE_LIBHILDON/!wxUSE_LIBHILDON
 
+    g_object_ref(m_widget);
+
     if ( parentGTK )
     {
         gtk_window_set_transient_for(GTK_WINDOW(m_widget), parentGTK);
diff --git a/src/gtk/combobox.cpp b/src/gtk/combobox.cpp
index 30a9824ea4..b94d1f983b 100644
--- a/src/gtk/combobox.cpp
+++ b/src/gtk/combobox.cpp
@@ -156,6 +156,7 @@ bool wxComboBox::Create( wxWindow *parent, wxWindowID id, const wxString& value,
 void wxComboBox::GTKCreateComboBoxWidget()
 {
     m_widget = gtk_combo_box_entry_new_text();
+    g_object_ref(m_widget);
 
     m_entry = GTK_ENTRY(GTK_BIN(m_widget)->child);
 }
diff --git a/src/gtk/dataview.cpp b/src/gtk/dataview.cpp
index 697d1cf9cc..58b3538b6a 100644
--- a/src/gtk/dataview.cpp
+++ b/src/gtk/dataview.cpp
@@ -3610,6 +3610,7 @@ bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id,
     m_insertCallback = wxInsertChildInDataViewCtrl;
 
     m_widget = gtk_scrolled_window_new (NULL, NULL);
+    g_object_ref(m_widget);
 
     GtkScrolledWindowSetBorder(m_widget, style);
 
diff --git a/src/gtk/dirdlg.cpp b/src/gtk/dirdlg.cpp
index 7874ff5773..08e4a0af44 100644
--- a/src/gtk/dirdlg.cpp
+++ b/src/gtk/dirdlg.cpp
@@ -120,6 +120,7 @@ wxDirDialog::wxDirDialog(wxWindow* parent,
                    GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                    GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
                    NULL);
+    g_object_ref(m_widget);
 
     gtk_dialog_set_default_response(GTK_DIALOG(m_widget), GTK_RESPONSE_ACCEPT);
 
diff --git a/src/gtk/filectrl.cpp b/src/gtk/filectrl.cpp
index b2729ab9e2..dace1751e7 100644
--- a/src/gtk/filectrl.cpp
+++ b/src/gtk/filectrl.cpp
@@ -287,6 +287,7 @@ bool wxGtkFileCtrl::Create( wxWindow *parent,
         gtkAction = GTK_FILE_CHOOSER_ACTION_SAVE;
 
     m_widget =  gtk_alignment_new ( 0, 0, 1, 1 );
+    g_object_ref(m_widget);
     m_fcWidget = GTK_FILE_CHOOSER( gtk_file_chooser_widget_new(gtkAction) );
     gtk_widget_show ( GTK_WIDGET( m_fcWidget ) );
     gtk_container_add ( GTK_CONTAINER ( m_widget ), GTK_WIDGET( m_fcWidget ) );
diff --git a/src/gtk/filedlg.cpp b/src/gtk/filedlg.cpp
index 6260b33b8e..e8906dfd4f 100644
--- a/src/gtk/filedlg.cpp
+++ b/src/gtk/filedlg.cpp
@@ -214,6 +214,7 @@ wxFileDialog::wxFileDialog(wxWindow *parent, const wxString& message,
                    GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                    ok_btn_stock, GTK_RESPONSE_ACCEPT,
                    NULL);
+    g_object_ref(m_widget);
     GtkFileChooser* file_chooser = GTK_FILE_CHOOSER(m_widget);
 
     m_fc.SetWidget(file_chooser);
@@ -297,6 +298,17 @@ wxFileDialog::wxFileDialog(wxWindow *parent, const wxString& message,
     }
 }
 
+wxFileDialog::~wxFileDialog()
+{
+    if (m_extraControl)
+    {
+        // get chooser to drop its reference right now, allowing wxWindow dtor
+        // to verify that ref count drops to zero
+        gtk_file_chooser_set_extra_widget(
+            GTK_FILE_CHOOSER(m_widget), NULL);
+    }
+}
+
 void wxFileDialog::OnFakeOk(wxCommandEvent& WXUNUSED(event))
 {
     EndDialog(wxID_OK);
diff --git a/src/gtk/filepicker.cpp b/src/gtk/filepicker.cpp
index 9e099cc444..73aab00df1 100644
--- a/src/gtk/filepicker.cpp
+++ b/src/gtk/filepicker.cpp
@@ -81,6 +81,7 @@ bool wxFileButton::Create( wxWindow *parent, wxWindowID id,
         // NOTE: we deliberately ignore the given label as GtkFileChooserButton
         //       use as label the currently selected file
         m_widget = gtk_file_chooser_button_new_with_dialog( m_dialog->m_widget );
+        g_object_ref(m_widget);
         gtk_widget_show(m_widget);
 
         // we need to know when the dialog has been dismissed clicking OK...
@@ -103,12 +104,6 @@ bool wxFileButton::Create( wxWindow *parent, wxWindowID id,
 
 wxFileButton::~wxFileButton()
 {
-    // GtkFileChooserButton will automatically destroy the
-    // GtkFileChooserDialog associated with m_dialog.
-    // Thus we have to set its m_widget to NULL to avoid
-    // double destruction on same widget
-    if (m_dialog)
-        m_dialog->m_widget = NULL;
 }
 
 void wxFileButton::OnDialogOK(wxCommandEvent& ev)
@@ -229,6 +224,7 @@ bool wxDirButton::Create( wxWindow *parent, wxWindowID id,
         // NOTE: we deliberately ignore the given label as GtkFileChooserButton
         //       use as label the currently selected file
         m_widget = gtk_file_chooser_button_new_with_dialog( m_dialog->m_widget );
+        g_object_ref(m_widget);
 
         gtk_widget_show(m_widget);
 
@@ -249,12 +245,6 @@ bool wxDirButton::Create( wxWindow *parent, wxWindowID id,
 
 wxDirButton::~wxDirButton()
 {
-    // GtkFileChooserButton will automatically destroy the
-    // GtkFileChooserDialog associated with m_dialog.
-    // Thus we have to set its m_widget to NULL to avoid
-    // double destruction on same widget
-    if (m_dialog)
-        m_dialog->m_widget = NULL;
 }
 
 void wxDirButton::SetPath(const wxString& str)
diff --git a/src/gtk/fontdlg.cpp b/src/gtk/fontdlg.cpp
index 50f971d756..8cb4f89917 100644
--- a/src/gtk/fontdlg.cpp
+++ b/src/gtk/fontdlg.cpp
@@ -98,6 +98,7 @@ bool wxFontDialog::DoCreate(wxWindow *parent)
 
     wxString m_message( _("Choose font") );
     m_widget = gtk_font_selection_dialog_new( wxGTK_CONV( m_message ) );
+    g_object_ref(m_widget);
 
     if (parent)
         gtk_window_set_transient_for(GTK_WINDOW(m_widget),
diff --git a/src/gtk/fontpicker.cpp b/src/gtk/fontpicker.cpp
index 00b1181bc9..b2cdb532e3 100644
--- a/src/gtk/fontpicker.cpp
+++ b/src/gtk/fontpicker.cpp
@@ -66,6 +66,7 @@ bool wxFontButton::Create( wxWindow *parent, wxWindowID id,
     }
 
     m_widget = gtk_font_button_new();
+    g_object_ref(m_widget);
 
     // set initial font
     m_selectedFont = initial.IsOk() ? initial : *wxNORMAL_FONT;
diff --git a/src/gtk/gauge.cpp b/src/gtk/gauge.cpp
index aaa124506c..2d29922938 100644
--- a/src/gtk/gauge.cpp
+++ b/src/gtk/gauge.cpp
@@ -41,6 +41,7 @@ bool wxGauge::Create( wxWindow *parent,
     m_rangeMax = range;
 
     m_widget = gtk_progress_bar_new();
+    g_object_ref(m_widget);
     if ( style & wxGA_VERTICAL )
     {
         gtk_progress_bar_set_orientation( GTK_PROGRESS_BAR(m_widget),
diff --git a/src/gtk/hyperlink.cpp b/src/gtk/hyperlink.cpp
index d9d9ea1420..44645ce0fa 100644
--- a/src/gtk/hyperlink.cpp
+++ b/src/gtk/hyperlink.cpp
@@ -84,6 +84,7 @@ bool wxHyperlinkCtrl::Create(wxWindow *parent, wxWindowID id,
         }
 
         m_widget = gtk_link_button_new("asdfsaf asdfdsaf asdfdsa");
+        g_object_ref(m_widget);
         gtk_widget_show(m_widget);
 
         // alignment
diff --git a/src/gtk/listbox.cpp b/src/gtk/listbox.cpp
index 79f85977bb..d453bf384a 100644
--- a/src/gtk/listbox.cpp
+++ b/src/gtk/listbox.cpp
@@ -169,7 +169,7 @@ gtk_listitem_changed_callback(GtkTreeSelection * WXUNUSED(selection),
 //-----------------------------------------------------------------------------
 
 extern "C" {
-static gint
+static gboolean
 gtk_listbox_key_press_callback( GtkWidget *WXUNUSED(widget),
                                 GdkEventKey *gdk_event,
                                 wxListBox *listbox )
@@ -362,6 +362,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id,
     }
 
     m_widget = gtk_scrolled_window_new( (GtkAdjustment*) NULL, (GtkAdjustment*) NULL );
+    g_object_ref(m_widget);
     if (style & wxLB_ALWAYS_SB)
     {
       gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(m_widget),
diff --git a/src/gtk/mdi.cpp b/src/gtk/mdi.cpp
index 4a7ddf7c9f..2503d66083 100644
--- a/src/gtk/mdi.cpp
+++ b/src/gtk/mdi.cpp
@@ -457,6 +457,7 @@ bool wxMDIClientWindow::CreateClient( wxMDIParentFrame *parent, long style )
     }
 
     m_widget = gtk_notebook_new();
+    g_object_ref(m_widget);
 
     g_signal_connect (m_widget, "switch_page",
                       G_CALLBACK (gtk_mdi_page_change_callback), parent);
diff --git a/src/gtk/menu.cpp b/src/gtk/menu.cpp
index 5511b9bae6..bbbd626e99 100644
--- a/src/gtk/menu.cpp
+++ b/src/gtk/menu.cpp
@@ -94,6 +94,8 @@ void wxMenuBar::Init(size_t n, wxMenu *menus[], const wxString titles[], long st
     ApplyWidgetStyle();
 #endif // wxUSE_LIBHILDON/!wxUSE_LIBHILDON
 
+    g_object_ref(m_widget);
+
     for (size_t i = 0; i < n; ++i )
         Append(menus[i], titles[i]);
 }
diff --git a/src/gtk/msgdlg.cpp b/src/gtk/msgdlg.cpp
index 49b2a38b1c..b71806be72 100644
--- a/src/gtk/msgdlg.cpp
+++ b/src/gtk/msgdlg.cpp
@@ -140,6 +140,8 @@ void wxMessageDialog::GTKCreateMsgDialog()
 #endif // GTK+ 2.6+
 #endif // wxUSE_LIBHILDON/!wxUSE_LIBHILDON
 
+    g_object_ref(m_widget);
+
     if (m_caption != wxMessageBoxCaptionStr)
         gtk_window_set_title(GTK_WINDOW(m_widget), wxGTK_CONV(m_caption));
 
@@ -204,6 +206,7 @@ int wxMessageDialog::ShowModal()
 
     gint result = gtk_dialog_run(GTK_DIALOG(m_widget));
     gtk_widget_destroy(m_widget);
+    g_object_unref(m_widget);
     m_widget = NULL;
 
     switch (result)
diff --git a/src/gtk/notebook.cpp b/src/gtk/notebook.cpp
index 0b95ed355e..60fe23a01f 100644
--- a/src/gtk/notebook.cpp
+++ b/src/gtk/notebook.cpp
@@ -174,6 +174,7 @@ bool wxNotebook::Create(wxWindow *parent, wxWindowID id,
 
 
     m_widget = gtk_notebook_new();
+    g_object_ref(m_widget);
 
     gtk_notebook_set_scrollable( GTK_NOTEBOOK(m_widget), 1 );
 
@@ -345,7 +346,6 @@ wxNotebookPage *wxNotebook::DoRemovePage( size_t page )
     if ( !client )
         return NULL;
 
-    gtk_widget_ref( client->m_widget );
     gtk_widget_unrealize( client->m_widget );
 
     // we don't need to unparent the client->m_widget; GTK+ will do
@@ -378,11 +378,8 @@ bool wxNotebook::InsertPage( size_t position,
                  _T("invalid page index in wxNotebookPage::InsertPage()") );
 
     // Hack Alert! (Part II): See above in wxInsertChildInNotebook callback
-    // why this has to be done.  NOTE: using gtk_widget_unparent here does not
-    // work as it seems to undo too much and will cause errors in the
-    // gtk_notebook_insert_page below, so instead just clear the parent by
-    // hand here.
-    win->m_widget->parent = NULL;
+    // why this has to be done.
+    gtk_widget_unparent(win->m_widget);
 
     if (m_themeEnabled)
         win->SetThemeEnabled(true);
diff --git a/src/gtk/popupwin.cpp b/src/gtk/popupwin.cpp
index a16315563b..5bcc578fa7 100644
--- a/src/gtk/popupwin.cpp
+++ b/src/gtk/popupwin.cpp
@@ -154,6 +154,7 @@ bool wxPopupWindow::Create( wxWindow *parent, int style )
     m_insertCallback = wxInsertChildInPopupWin;
 
     m_widget = gtk_window_new( GTK_WINDOW_POPUP );
+    g_object_ref(m_widget);
 
     if ((m_parent) && (GTK_IS_WINDOW(m_parent->m_widget)))
         gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(m_parent->m_widget) );
diff --git a/src/gtk/radiobox.cpp b/src/gtk/radiobox.cpp
index 15dd404b7d..33f01ccb61 100644
--- a/src/gtk/radiobox.cpp
+++ b/src/gtk/radiobox.cpp
@@ -224,6 +224,7 @@ bool wxRadioBox::Create( wxWindow *parent, wxWindowID id, const wxString& title,
     }
 
     m_widget = GTKCreateFrame(title);
+    g_object_ref(m_widget);
     wxControl::SetLabel(title);
     if ( HasFlag(wxNO_BORDER) )
     {
diff --git a/src/gtk/radiobut.cpp b/src/gtk/radiobut.cpp
index 649a520830..fc095b6538 100644
--- a/src/gtk/radiobut.cpp
+++ b/src/gtk/radiobut.cpp
@@ -83,6 +83,7 @@ bool wxRadioButton::Create( wxWindow *parent,
     }
 
     m_widget = gtk_radio_button_new_with_label( radioButtonGroup, wxGTK_CONV( label ) );
+    g_object_ref(m_widget);
 
     SetLabel(label);
 
diff --git a/src/gtk/scrolbar.cpp b/src/gtk/scrolbar.cpp
index 413e8fbe3c..0a76b68267 100644
--- a/src/gtk/scrolbar.cpp
+++ b/src/gtk/scrolbar.cpp
@@ -144,6 +144,7 @@ bool wxScrollBar::Create(wxWindow *parent, wxWindowID id,
         m_widget = gtk_vscrollbar_new( (GtkAdjustment *) NULL );
     else
         m_widget = gtk_hscrollbar_new( (GtkAdjustment *) NULL );
+    g_object_ref(m_widget);
 
     m_scrollBar[0] = (GtkRange*)m_widget;
 
diff --git a/src/gtk/slider.cpp b/src/gtk/slider.cpp
index f14ae6394a..b2a24b3640 100644
--- a/src/gtk/slider.cpp
+++ b/src/gtk/slider.cpp
@@ -307,6 +307,7 @@ bool wxSlider::Create(wxWindow *parent,
         m_widget = gtk_vscale_new( (GtkAdjustment *) NULL );
     else
         m_widget = gtk_hscale_new( (GtkAdjustment *) NULL );
+    g_object_ref(m_widget);
 
     gtk_scale_set_draw_value(GTK_SCALE (m_widget), (style & wxSL_LABELS) != 0);
     // Keep full precision in position value
diff --git a/src/gtk/spinbutt.cpp b/src/gtk/spinbutt.cpp
index b886fbc324..45138d8ae4 100644
--- a/src/gtk/spinbutt.cpp
+++ b/src/gtk/spinbutt.cpp
@@ -107,6 +107,7 @@ bool wxSpinButton::Create(wxWindow *parent,
     m_pos = 0;
 
     m_widget = gtk_spin_button_new_with_range(0, 100, 1);
+    g_object_ref(m_widget);
 
     gtk_spin_button_set_wrap( GTK_SPIN_BUTTON(m_widget),
                               (int)(m_windowStyle & wxSP_WRAP) );
diff --git a/src/gtk/spinctrl.cpp b/src/gtk/spinctrl.cpp
index 77a9cb485b..952d003784 100644
--- a/src/gtk/spinctrl.cpp
+++ b/src/gtk/spinctrl.cpp
@@ -113,6 +113,7 @@ bool wxSpinCtrlGTKBase::Create(wxWindow *parent, wxWindowID id,
     }
 
     m_widget = gtk_spin_button_new_with_range(min, max, inc);
+    g_object_ref(m_widget);
 
     gtk_spin_button_set_value( GTK_SPIN_BUTTON(m_widget), initial);
     m_value = gtk_spin_button_get_value( GTK_SPIN_BUTTON(m_widget));
diff --git a/src/gtk/statbmp.cpp b/src/gtk/statbmp.cpp
index aeb95223ec..b12acdde77 100644
--- a/src/gtk/statbmp.cpp
+++ b/src/gtk/statbmp.cpp
@@ -47,6 +47,7 @@ bool wxStaticBitmap::Create( wxWindow *parent, wxWindowID id, const wxBitmap &bi
     m_bitmap = bitmap;
 
     m_widget = gtk_image_new();
+    g_object_ref(m_widget);
 
     if (bitmap.Ok())
         SetBitmap(bitmap);
diff --git a/src/gtk/statbox.cpp b/src/gtk/statbox.cpp
index 7115010262..20326248c2 100644
--- a/src/gtk/statbox.cpp
+++ b/src/gtk/statbox.cpp
@@ -78,6 +78,7 @@ bool wxStaticBox::Create( wxWindow *parent,
     }
 
     m_widget = GTKCreateFrame(label);
+    g_object_ref(m_widget);
     // only base SetLabel needs to be called after GTKCreateFrame
     wxControl::SetLabel(label);
 
diff --git a/src/gtk/statline.cpp b/src/gtk/statline.cpp
index 97bfa70cfa..9cb487fb6a 100644
--- a/src/gtk/statline.cpp
+++ b/src/gtk/statline.cpp
@@ -65,6 +65,7 @@ bool wxStaticLine::Create( wxWindow *parent, wxWindowID id,
             SetSize( new_size );
         }
     }
+    g_object_ref(m_widget);
 
     m_parent->DoAddChild( this );
 
diff --git a/src/gtk/stattext.cpp b/src/gtk/stattext.cpp
index e0d277d91b..e9366a1e38 100644
--- a/src/gtk/stattext.cpp
+++ b/src/gtk/stattext.cpp
@@ -52,6 +52,7 @@ bool wxStaticText::Create(wxWindow *parent,
     }
 
     m_widget = gtk_label_new(NULL);
+    g_object_ref(m_widget);
 
     GtkJustification justify;
     if ( style & wxALIGN_CENTER_HORIZONTAL )
diff --git a/src/gtk/taskbar.cpp b/src/gtk/taskbar.cpp
index 8035e5b342..80bfd6b119 100644
--- a/src/gtk/taskbar.cpp
+++ b/src/gtk/taskbar.cpp
@@ -32,6 +32,7 @@ wxTaskBarIconAreaBase::wxTaskBarIconAreaBase()
     if (IsProtocolSupported())
     {
         m_widget = GTK_WIDGET(egg_tray_icon_new("systray icon"));
+        g_object_ref(m_widget);
         gtk_window_set_resizable(GTK_WINDOW(m_widget), false);
 
         wxLogTrace(_T("systray"), _T("using freedesktop.org systray spec"));
diff --git a/src/gtk/tbargtk.cpp b/src/gtk/tbargtk.cpp
index 63d7dae975..a179de76e9 100644
--- a/src/gtk/tbargtk.cpp
+++ b/src/gtk/tbargtk.cpp
@@ -51,12 +51,6 @@ public:
         : wxToolBarToolBase(tbar, control, label)
     {
         m_item = NULL;
-        // Hold a reference to keep control alive until DoInsertTool() is
-        // called, or if RemoveTool() is called (see DoDeleteTool)
-        g_object_ref(control->m_widget);
-        // release reference when gtk_widget_destroy() is called on control
-        g_signal_connect(
-            control->m_widget, "destroy", G_CALLBACK(g_object_unref), NULL);
     }
 
     void SetImage();
@@ -411,6 +405,7 @@ bool wxToolBar::Create( wxWindow *parent,
         m_widget = gtk_event_box_new();
         ConnectWidget( m_widget );
     }
+    g_object_ref(m_widget);
     gtk_container_add(GTK_CONTAINER(m_widget), GTK_WIDGET(m_toolbar));
     gtk_widget_show(GTK_WIDGET(m_toolbar));
 
diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp
index 325dcbd5c6..71ba5a7020 100644
--- a/src/gtk/textctrl.cpp
+++ b/src/gtk/textctrl.cpp
@@ -687,6 +687,7 @@ bool wxTextCtrl::Create( wxWindow *parent,
             g_object_set (m_text, "has-frame", FALSE, NULL);
 
     }
+    g_object_ref(m_widget);
 
     m_parent->DoAddChild( this );
 
diff --git a/src/gtk/tglbtn.cpp b/src/gtk/tglbtn.cpp
index b98f151305..162d9b396f 100644
--- a/src/gtk/tglbtn.cpp
+++ b/src/gtk/tglbtn.cpp
@@ -66,6 +66,7 @@ bool wxBitmapToggleButton::Create(wxWindow *parent, wxWindowID id,
 
     // Create the gtk widget.
     m_widget = gtk_toggle_button_new();
+    g_object_ref(m_widget);
 
     if (style & wxNO_BORDER)
         gtk_button_set_relief( GTK_BUTTON(m_widget), GTK_RELIEF_NONE );
@@ -204,6 +205,7 @@ bool wxToggleButton::Create(wxWindow *parent, wxWindowID id,
 
     // Create the gtk widget.
     m_widget = gtk_toggle_button_new_with_mnemonic("");
+    g_object_ref(m_widget);
 
     SetLabel(label);
 
diff --git a/src/gtk/toplevel.cpp b/src/gtk/toplevel.cpp
index 7ddd774e3b..e7a51956d4 100644
--- a/src/gtk/toplevel.cpp
+++ b/src/gtk/toplevel.cpp
@@ -511,6 +511,8 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent,
             }
         }
 #endif // wxUSE_LIBHILDON/!wxUSE_LIBHILDON
+
+        g_object_ref(m_widget);
     }
 
     wxWindow *topParent = wxGetTopLevelParent(m_parent);
diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp
index f62c235b8b..fb849b4953 100644
--- a/src/gtk/window.cpp
+++ b/src/gtk/window.cpp
@@ -2131,6 +2131,7 @@ bool wxWindowGTK::Create( wxWindow *parent,
 
         gtk_widget_show( m_wxwindow );
     }
+    g_object_ref(m_widget);
 
     if (m_parent)
         m_parent->DoAddChild( this );
@@ -2180,17 +2181,17 @@ wxWindowGTK::~wxWindowGTK()
     // delete before the widgets to avoid a crash on solaris
     delete m_imData;
 
-    if (m_wxwindow && (m_wxwindow != m_widget))
-    {
-        gtk_widget_destroy( m_wxwindow );
-        m_wxwindow = (GtkWidget*) NULL;
-    }
-
     if (m_widget)
     {
-        gtk_widget_destroy( m_widget );
-        m_widget = (GtkWidget*) NULL;
+        // Note that gtk_widget_destroy() does not destroy the widget, it just
+        // emits the "destroy" signal. The widget is not actually destroyed
+        // until its reference count drops to zero.
+        gtk_widget_destroy(m_widget);
+        // Release our reference, should be the last one
+        g_object_unref(m_widget);
+        m_widget = NULL;
     }
+    m_wxwindow = NULL;
 }
 
 bool wxWindowGTK::PreCreation( wxWindowGTK *parent, const wxPoint &pos,  const wxSize &size )
-- 
2.47.2