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:
@@ -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;
|
||||||
|
@@ -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);
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user