From 0c02b05d927e1e3cf17c402c852bc3298e7ec683 Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Fri, 17 Apr 2015 08:45:55 -0700 Subject: [PATCH] Avoid freeze count mismatches with GTK 2.18+ when impl_window changes while frozen, see #16795 --- src/gtk/window.cpp | 61 ++++++++++++---------------------------------- 1 file changed, 15 insertions(+), 46 deletions(-) diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 6cc60836e8d4..1e28eed8e48f 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -3275,59 +3275,13 @@ bool wxWindowGTK::Show( bool show ) return true; } -static void GetFrozen(wxWindowGTK* win, wxVector& vector) -{ - if (win->IsFrozen()) - vector.push_back(win); - - wxWindowList& children = win->GetChildren(); - for (wxWindowList::iterator i = children.begin(); i != children.end(); ++i) - GetFrozen(*i, vector); -} - -extern "C" { -static void find_scrollbar(GtkWidget* widget, void* data) -{ - bool& isScrollbar = *static_cast(data); - if (!isScrollbar) - { - if (GTK_IS_SCROLLBAR(widget)) - isScrollbar = true; - else if (GTK_IS_CONTAINER(widget)) - gtk_container_forall((GtkContainer*)widget, find_scrollbar, data); - } -} -} - void wxWindowGTK::DoEnable( bool enable ) { wxCHECK_RET( (m_widget != NULL), wxT("invalid window") ); - wxVector frozen; - if (enable) - { - // Ubuntu overlay scrollbar can cause GdkWindow.impl_window to change - // (by indirectly invoking gdk_window_ensure_native()), which messes up - // the freeze count. Avoid this by temporarily un-freezing window hierarchy. - bool isScrollbar = false; - find_scrollbar(m_widget, static_cast(&isScrollbar)); - if (isScrollbar) - { - GetFrozen(wxGetTopLevelParent(static_cast(this)), frozen); - for (unsigned i = frozen.size(); i--;) - frozen[i]->DoThaw(); - } - } - gtk_widget_set_sensitive( m_widget, enable ); if (m_wxwindow && (m_wxwindow != m_widget)) gtk_widget_set_sensitive( m_wxwindow, enable ); - - if (enable) - { - for (unsigned i = frozen.size(); i--;) - frozen[i]->DoFreeze(); - } } int wxWindowGTK::GetCharHeight() const @@ -5112,7 +5066,22 @@ void wxWindowGTK::GTKFreezeWidget(GtkWidget* widget) { GdkWindow* window = gtk_widget_get_window(widget); if (window) + { +#if GTK_CHECK_VERSION(2,18,0) +#ifndef __WXGTK3__ + if (gtk_check_version(2,18,0) == NULL) +#endif + { + // impl_window for a non-native GdkWindow can change if + // gdk_window_ensure_native() is called on it or some other + // GdkWindow in the same TLW. Since the freeze count is on the + // impl_window, we have to make sure impl_window does not change + // after we call gdk_window_freeze_updates(). + gdk_window_ensure_native(window); + } +#endif gdk_window_freeze_updates(window); + } } }