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

@@ -61,11 +61,13 @@ bool wxControl::Create( wxWindow *parent,
bool wxControl::SetFont(const wxFont& font) bool wxControl::SetFont(const wxFont& font)
{ {
const bool changed = base_type::SetFont(font); const bool changed = base_type::SetFont(font);
if (changed && !gtk_widget_get_realized(m_widget)) if (changed && !gtk_widget_get_realized(m_widget) && gtk_check_version(3,5,0))
{ {
// GTK defers sending "style-updated" until widget is realized, but // GTK defers sending "style-updated" until widget is realized, but
// GetBestSize() won't compute correct result until the signal is sent, // GetBestSize() won't compute correct result until the signal is sent,
// so we have to do it now // so we have to do it now
// But don't bother for GTK > 3.4, the change won't take effect until
// GTK updates it's style cache
g_signal_emit_by_name(m_widget, "style-updated"); g_signal_emit_by_name(m_widget, "style-updated");
} }
return changed; return changed;

View File

@@ -56,6 +56,10 @@
#include <hildon/hildon.h> #include <hildon/hildon.h>
#endif // wxUSE_LIBHILDON2 #endif // wxUSE_LIBHILDON2
#ifdef __WXGTK3__
void wxGTKSizeRevalidate(wxWindow*);
#endif
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// data // data
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -1038,6 +1042,10 @@ bool wxTopLevelWindowGTK::Show( bool show )
wxSizeEvent event(GetSize(), GetId()); wxSizeEvent event(GetSize(), GetId());
event.SetEventObject(this); event.SetEventObject(this);
HandleWindowEvent(event); HandleWindowEvent(event);
#ifdef __WXGTK3__
wxGTKSizeRevalidate(this);
#endif
} }
bool change = base_type::Show(show); bool change = base_type::Show(show);
@@ -1291,6 +1299,9 @@ void wxTopLevelWindowGTK::GTKUpdateDecorSize(const DecorSize& decorSize)
sizeEvent.SetEventObject(this); sizeEvent.SetEventObject(this);
HandleWindowEvent(sizeEvent); HandleWindowEvent(sizeEvent);
#ifdef __WXGTK3__
wxGTKSizeRevalidate(this);
#endif
gtk_widget_show(m_widget); gtk_widget_show(m_widget);
wxShowEvent showEvent(GetId(), true); wxShowEvent showEvent(GetId(), true);

View File

@@ -219,6 +219,11 @@ static wxWindowGTK *gs_deferredFocusOut = NULL;
GdkEvent *g_lastMouseEvent = NULL; GdkEvent *g_lastMouseEvent = NULL;
int g_lastButtonNumber = 0; int g_lastButtonNumber = 0;
#ifdef __WXGTK3__
static GList* gs_sizeRevalidateList;
void wxGTKSizeRevalidate(wxWindow*);
#endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// debug // debug
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -2038,6 +2043,17 @@ static void unrealize(GtkWidget*, wxWindow* win)
win->GTKHandleUnrealize(); 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" } // extern "C"
void wxWindowGTK::GTKHandleRealized() void wxWindowGTK::GTKHandleRealized()
@@ -2083,13 +2099,26 @@ void wxWindowGTK::GTKHandleRealized()
} }
#endif #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)); wxWindowCreateEvent event(static_cast<wxWindow*>(this));
event.SetEventObject( this ); event.SetEventObject( this );
GTKProcessEvent( event ); GTKProcessEvent( event );
GTKUpdateCursor(false, true); GTKUpdateCursor(false, true);
if (m_wxwindow && IsTopLevel()) if (m_wxwindow && isTopLevel)
{ {
// attaching to style changed signal after realization avoids initial // attaching to style changed signal after realization avoids initial
// changes we don't care about // changes we don't care about
@@ -2482,6 +2511,8 @@ wxWindowGTK::~wxWindowGTK()
#ifdef __WXGTK3__ #ifdef __WXGTK3__
if (m_styleProvider) if (m_styleProvider)
g_object_unref(m_styleProvider); g_object_unref(m_styleProvider);
gs_sizeRevalidateList = g_list_remove(gs_sizeRevalidateList, this);
#endif #endif
gs_needCursorResetMap.erase(this); 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); 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 ) bool wxWindowGTK::SetFont( const wxFont &font )
{ {
if (!wxWindowBase::SetFont(font)) if (!wxWindowBase::SetFont(font))
@@ -4543,6 +4600,24 @@ bool wxWindowGTK::SetFont( const wxFont &font )
GTKApplyWidgetStyle(true); 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; return true;
} }