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