for GTK+ 3.6 and later, invalidate cached best size when GTK's style cache is updated, see #16088

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_3_0_BRANCH@76149 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Paul Cornett
2014-03-15 18:44:02 +00:00
parent 15d82f05e1
commit d737ca76bd
3 changed files with 90 additions and 2 deletions

View File

@@ -219,6 +219,11 @@ static wxWindowGTK *gs_deferredFocusOut = NULL;
GdkEvent *g_lastMouseEvent = NULL;
int g_lastButtonNumber = 0;
#ifdef __WXGTK3__
static GList* gs_sizeRevalidateList;
void wxGTKSizeRevalidate(wxWindow*);
#endif
//-----------------------------------------------------------------------------
// debug
//-----------------------------------------------------------------------------
@@ -2038,6 +2043,17 @@ static void unrealize(GtkWidget*, wxWindow* win)
win->GTKHandleUnrealize();
}
#if GTK_CHECK_VERSION(3,8,0)
//-----------------------------------------------------------------------------
// "layout" from GdkFrameClock
//-----------------------------------------------------------------------------
static void frame_clock_layout(GdkFrameClock*, wxWindow* win)
{
wxGTKSizeRevalidate(win);
}
#endif // GTK_CHECK_VERSION(3,8,0)
} // extern "C"
void wxWindowGTK::GTKHandleRealized()
@@ -2083,13 +2099,26 @@ void wxWindowGTK::GTKHandleRealized()
}
#endif
const bool isTopLevel = IsTopLevel();
#if GTK_CHECK_VERSION(3,8,0)
if (isTopLevel && gtk_check_version(3,8,0) == NULL)
{
GdkFrameClock* clock = gtk_widget_get_frame_clock(m_widget);
if (clock &&
!g_signal_handler_find(clock, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, this))
{
g_signal_connect(clock, "layout", G_CALLBACK(frame_clock_layout), this);
}
}
#endif
wxWindowCreateEvent event(static_cast<wxWindow*>(this));
event.SetEventObject( this );
GTKProcessEvent( event );
GTKUpdateCursor(false, true);
if (m_wxwindow && IsTopLevel())
if (m_wxwindow && isTopLevel)
{
// attaching to style changed signal after realization avoids initial
// changes we don't care about
@@ -2482,6 +2511,8 @@ wxWindowGTK::~wxWindowGTK()
#ifdef __WXGTK3__
if (m_styleProvider)
g_object_unref(m_styleProvider);
gs_sizeRevalidateList = g_list_remove(gs_sizeRevalidateList, this);
#endif
gs_needCursorResetMap.erase(this);
@@ -4531,6 +4562,32 @@ GdkWindow *wxWindowGTK::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
return m_wxwindow ? GTKGetDrawingWindow() : gtk_widget_get_window(m_widget);
}
#ifdef __WXGTK3__
void wxGTKSizeRevalidate(wxWindow* tlw)
{
GList* next;
for (GList* p = gs_sizeRevalidateList; p; p = next)
{
next = p->next;
wxWindow* win = static_cast<wxWindow*>(p->data);
if (wxGetTopLevelParent(win) == tlw)
{
win->InvalidateBestSize();
gs_sizeRevalidateList = g_list_delete_link(gs_sizeRevalidateList, p);
}
}
}
extern "C" {
static gboolean before_resize(void* data)
{
wxWindow* win = static_cast<wxWindow*>(data);
win->InvalidateBestSize();
return false;
}
}
#endif // __WXGTK3__
bool wxWindowGTK::SetFont( const wxFont &font )
{
if (!wxWindowBase::SetFont(font))
@@ -4543,6 +4600,24 @@ bool wxWindowGTK::SetFont( const wxFont &font )
GTKApplyWidgetStyle(true);
}
#ifdef __WXGTK3__
// Starting with GTK 3.6, style information is cached, and the cache is only
// updated before resizing, or when showing a TLW. If a different size font
// is set, our best size calculation will be wrong. All we can do is
// invalidate the best size right before the style cache is updated, so any
// subsequent best size requests use the correct font.
if (gtk_check_version(3,8,0) == NULL)
gs_sizeRevalidateList = g_list_append(gs_sizeRevalidateList, this);
else if (gtk_check_version(3,6,0) == NULL)
{
wxWindow* tlw = wxGetTopLevelParent(static_cast<wxWindow*>(this));
if (tlw->m_widget && gtk_widget_get_visible(tlw->m_widget))
g_idle_add_full(GTK_PRIORITY_RESIZE - 1, before_resize, this, NULL);
else
gs_sizeRevalidateList = g_list_append(gs_sizeRevalidateList, this);
}
#endif
return true;
}