Skip to content

Commit

Permalink
Avoid freeze count mismatches with GTK 2.18+ when impl_window changes…
Browse files Browse the repository at this point in the history
… while frozen, see #16795
  • Loading branch information
paulcor committed Apr 17, 2015
1 parent 84f6686 commit 0c02b05
Showing 1 changed file with 15 additions and 46 deletions.
61 changes: 15 additions & 46 deletions src/gtk/window.cpp
Expand Up @@ -3275,59 +3275,13 @@ bool wxWindowGTK::Show( bool show )
return true;
}

static void GetFrozen(wxWindowGTK* win, wxVector<wxWindowGTK*>& 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<bool*>(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<wxWindowGTK*> 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<void*>(&isScrollbar));
if (isScrollbar)
{
GetFrozen(wxGetTopLevelParent(static_cast<wxWindow*>(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
Expand Down Expand Up @@ -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);
}
}
}

Expand Down

0 comments on commit 0c02b05

Please sign in to comment.