Fix a sizing/layout problem with GTK3

Relying on "check-resize" to detect when a "size-allocate" is in progess is
insufficient, resulting in the possibility of a window ending up with the wrong
size or position after inital layout. Using our existing "size-allocate"
handlers should be enough to detect the cases we care about.
See #18865
This commit is contained in:
Paul Cornett
2020-08-01 21:23:34 -07:00
parent 5e89d575c3
commit bd835ee452
2 changed files with 12 additions and 26 deletions

View File

@@ -57,6 +57,7 @@ static wxTopLevelWindowGTK *g_activeFrame = NULL;
extern wxCursor g_globalCursor;
extern wxCursor g_busyCursor;
extern bool g_inSizeAllocate;
#ifdef GDK_WINDOWING_X11
// Whether _NET_REQUEST_FRAME_EXTENTS support is working
@@ -240,6 +241,9 @@ size_allocate(GtkWidget*, GtkAllocation* alloc, wxTopLevelWindowGTK* win)
if (win->m_clientWidth != alloc->width ||
win->m_clientHeight != alloc->height)
{
const bool save_inSizeAllocate = g_inSizeAllocate;
g_inSizeAllocate = true;
win->m_clientWidth = alloc->width;
win->m_clientHeight = alloc->height;
@@ -272,6 +276,8 @@ size_allocate(GtkWidget*, GtkAllocation* alloc, wxTopLevelWindowGTK* win)
win->HandleWindowEvent(event);
}
// else the window is currently unmapped, don't generate size events
g_inSizeAllocate = save_inSizeAllocate;
}
}
}

View File

@@ -225,8 +225,8 @@ int g_lastButtonNumber = 0;
#ifdef __WXGTK3__
static GList* gs_sizeRevalidateList;
static bool gs_inSizeAllocate;
#endif
bool g_inSizeAllocate;
#if GTK_CHECK_VERSION(3,14,0)
#define wxGTK_HAS_GESTURES_SUPPORT
@@ -2279,9 +2279,12 @@ size_allocate(GtkWidget* WXUNUSED_IN_GTK2(widget), GtkAllocation* alloc, wxWindo
win->m_width = a.width;
win->m_height = a.height;
{
const bool save_inSizeAllocate = g_inSizeAllocate;
g_inSizeAllocate = true;
wxSizeEvent event(win->GetSize(), win->GetId());
event.SetEventObject(win);
win->GTKProcessEvent(event);
g_inSizeAllocate = save_inSizeAllocate;
}
}
}
@@ -2325,22 +2328,6 @@ static void frame_clock_layout(GdkFrameClock*, wxWindow* win)
}
#endif // GTK_CHECK_VERSION(3,8,0)
#ifdef __WXGTK3__
//-----------------------------------------------------------------------------
// "check-resize"
//-----------------------------------------------------------------------------
static void check_resize(GtkContainer*, wxWindow*)
{
gs_inSizeAllocate = true;
}
static void check_resize_after(GtkContainer*, wxWindow*)
{
gs_inSizeAllocate = false;
}
#endif // __WXGTK3__
} // extern "C"
void wxWindowGTK::GTKHandleRealized()
@@ -2905,13 +2892,6 @@ void wxWindowGTK::PostCreation()
g_signal_connect(m_wxwindow ? m_wxwindow : m_widget, "size_allocate",
G_CALLBACK(size_allocate), this);
}
#ifdef __WXGTK3__
else
{
g_signal_connect(m_widget, "check-resize", G_CALLBACK(check_resize), this);
g_signal_connect_after(m_widget, "check-resize", G_CALLBACK(check_resize_after), this);
}
#endif
#if GTK_CHECK_VERSION(2, 8, 0)
if ( wx_is_at_least_gtk2(8) )
@@ -3736,7 +3716,7 @@ void wxWindowGTK::DoMoveWindow(int x, int y, int width, int height)
pizza->move(m_widget, x, y, width, height);
if (
#ifdef __WXGTK3__
!gs_inSizeAllocate &&
!g_inSizeAllocate &&
#endif
gtk_widget_get_visible(m_widget))
{
@@ -3753,7 +3733,7 @@ void wxWindowGTK::DoMoveWindow(int x, int y, int width, int height)
// size-allocate can generate wxSizeEvent and size event handlers often
// call SetSize(), directly or indirectly. It should be fine to call
// gtk_widget_size_allocate() immediately in this case.
if (gs_inSizeAllocate && gtk_widget_get_visible(m_widget) && width > 0 && height > 0)
if (g_inSizeAllocate && gtk_widget_get_visible(m_widget) && width > 0 && height > 0)
{
// obligatory size request before size allocate to avoid GTK3 warnings
GtkRequisition req;