Use client size determined by size-allocate when possible
Our client size calculation can be wrong for reasons beyond our control, notably on Ubuntu 12.04 with overlay scrollbars where the GtkScrolledWindow "scrollbar-spacing" is wrong. By using the true size from size-allocate when it becomes available, we can recover from an earlier incorrect client size calculation. See #14871 git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@73231 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -255,7 +255,11 @@ public:
|
|||||||
// position and size of the window
|
// position and size of the window
|
||||||
int m_x, m_y;
|
int m_x, m_y;
|
||||||
int m_width, m_height;
|
int m_width, m_height;
|
||||||
int m_oldClientWidth,m_oldClientHeight;
|
int m_clientWidth, m_clientHeight;
|
||||||
|
// Whether the client size variables above are known to be correct
|
||||||
|
// (because they have been validated by a size-allocate) and should
|
||||||
|
// be used to report client size
|
||||||
|
bool m_useCachedClientSize;
|
||||||
|
|
||||||
// see the docs in src/gtk/window.cpp
|
// see the docs in src/gtk/window.cpp
|
||||||
GtkWidget *m_widget; // mostly the widget seen by the rest of GTK
|
GtkWidget *m_widget; // mostly the widget seen by the rest of GTK
|
||||||
|
@@ -74,6 +74,9 @@ void wxFrame::DoGetClientSize( int *width, int *height ) const
|
|||||||
|
|
||||||
wxFrameBase::DoGetClientSize(width, height);
|
wxFrameBase::DoGetClientSize(width, height);
|
||||||
|
|
||||||
|
if (m_useCachedClientSize)
|
||||||
|
return;
|
||||||
|
|
||||||
if (height)
|
if (height)
|
||||||
{
|
{
|
||||||
#if wxUSE_MENUS_NATIVE
|
#if wxUSE_MENUS_NATIVE
|
||||||
@@ -287,7 +290,8 @@ void wxFrame::DetachMenuBar()
|
|||||||
wxFrameBase::DetachMenuBar();
|
wxFrameBase::DetachMenuBar();
|
||||||
|
|
||||||
// make sure next size_allocate causes a wxSizeEvent
|
// make sure next size_allocate causes a wxSizeEvent
|
||||||
m_oldClientWidth = 0;
|
m_useCachedClientSize = false;
|
||||||
|
m_clientWidth = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxFrame::AttachMenuBar( wxMenuBar *menuBar )
|
void wxFrame::AttachMenuBar( wxMenuBar *menuBar )
|
||||||
@@ -314,7 +318,8 @@ void wxFrame::AttachMenuBar( wxMenuBar *menuBar )
|
|||||||
#endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2/!wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
|
#endif // wxUSE_LIBHILDON || wxUSE_LIBHILDON2/!wxUSE_LIBHILDON && !wxUSE_LIBHILDON2
|
||||||
}
|
}
|
||||||
// make sure next size_allocate causes a wxSizeEvent
|
// make sure next size_allocate causes a wxSizeEvent
|
||||||
m_oldClientWidth = 0;
|
m_useCachedClientSize = false;
|
||||||
|
m_clientWidth = 0;
|
||||||
}
|
}
|
||||||
#endif // wxUSE_MENUS_NATIVE
|
#endif // wxUSE_MENUS_NATIVE
|
||||||
|
|
||||||
@@ -365,7 +370,8 @@ void wxFrame::SetToolBar(wxToolBar *toolbar)
|
|||||||
gtk_widget_set_size_request(toolbar->m_widget, -1, -1);
|
gtk_widget_set_size_request(toolbar->m_widget, -1, -1);
|
||||||
}
|
}
|
||||||
// make sure next size_allocate causes a wxSizeEvent
|
// make sure next size_allocate causes a wxSizeEvent
|
||||||
m_oldClientWidth = 0;
|
m_useCachedClientSize = false;
|
||||||
|
m_clientWidth = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // wxUSE_TOOLBAR
|
#endif // wxUSE_TOOLBAR
|
||||||
@@ -382,7 +388,8 @@ void wxFrame::SetStatusBar(wxStatusBar *statbar)
|
|||||||
gtk_box_set_child_packing(GTK_BOX(m_mainWidget),
|
gtk_box_set_child_packing(GTK_BOX(m_mainWidget),
|
||||||
statbar->m_widget, false, false, 0, GTK_PACK_END);
|
statbar->m_widget, false, false, 0, GTK_PACK_END);
|
||||||
// make sure next size_allocate on statusbar causes a size event
|
// make sure next size_allocate on statusbar causes a size event
|
||||||
statbar->m_oldClientWidth = 0;
|
statbar->m_useCachedClientSize = false;
|
||||||
|
statbar->m_clientWidth = 0;
|
||||||
int h = -1;
|
int h = -1;
|
||||||
if (statbar->m_wxwindow)
|
if (statbar->m_wxwindow)
|
||||||
{
|
{
|
||||||
@@ -392,6 +399,7 @@ void wxFrame::SetStatusBar(wxStatusBar *statbar)
|
|||||||
gtk_widget_set_size_request(statbar->m_widget, -1, h);
|
gtk_widget_set_size_request(statbar->m_widget, -1, h);
|
||||||
}
|
}
|
||||||
// make sure next size_allocate causes a wxSizeEvent
|
// make sure next size_allocate causes a wxSizeEvent
|
||||||
m_oldClientWidth = 0;
|
m_useCachedClientSize = false;
|
||||||
|
m_clientWidth = 0;
|
||||||
}
|
}
|
||||||
#endif // wxUSE_STATUSBAR
|
#endif // wxUSE_STATUSBAR
|
||||||
|
@@ -191,7 +191,7 @@ void wxMDIParentFrame::DoGetClientSize(int* width, int* height) const
|
|||||||
{
|
{
|
||||||
wxFrame::DoGetClientSize(width, height);
|
wxFrame::DoGetClientSize(width, height);
|
||||||
|
|
||||||
if (height)
|
if (!m_useCachedClientSize && height)
|
||||||
{
|
{
|
||||||
wxMDIChildFrame* active_child_frame = GetActiveChild();
|
wxMDIChildFrame* active_child_frame = GetActiveChild();
|
||||||
if (active_child_frame)
|
if (active_child_frame)
|
||||||
|
@@ -435,6 +435,10 @@ bool wxMiniFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title
|
|||||||
void wxMiniFrame::DoGetClientSize(int* width, int* height) const
|
void wxMiniFrame::DoGetClientSize(int* width, int* height) const
|
||||||
{
|
{
|
||||||
wxFrame::DoGetClientSize(width, height);
|
wxFrame::DoGetClientSize(width, height);
|
||||||
|
|
||||||
|
if (m_useCachedClientSize)
|
||||||
|
return;
|
||||||
|
|
||||||
if (width)
|
if (width)
|
||||||
{
|
{
|
||||||
*width -= 2 * m_miniEdge;
|
*width -= 2 * m_miniEdge;
|
||||||
|
@@ -216,11 +216,12 @@ extern "C" {
|
|||||||
static void
|
static void
|
||||||
size_allocate(GtkWidget*, GtkAllocation* alloc, wxTopLevelWindowGTK* win)
|
size_allocate(GtkWidget*, GtkAllocation* alloc, wxTopLevelWindowGTK* win)
|
||||||
{
|
{
|
||||||
if (win->m_oldClientWidth != alloc->width ||
|
win->m_useCachedClientSize = true;
|
||||||
win->m_oldClientHeight != alloc->height)
|
if (win->m_clientWidth != alloc->width ||
|
||||||
|
win->m_clientHeight != alloc->height)
|
||||||
{
|
{
|
||||||
win->m_oldClientWidth = alloc->width;
|
win->m_clientWidth = alloc->width;
|
||||||
win->m_oldClientHeight = alloc->height;
|
win->m_clientHeight = alloc->height;
|
||||||
|
|
||||||
GtkAllocation a;
|
GtkAllocation a;
|
||||||
gtk_widget_get_allocation(win->m_widget, &a);
|
gtk_widget_get_allocation(win->m_widget, &a);
|
||||||
@@ -343,7 +344,8 @@ gtk_frame_map_callback( GtkWidget*,
|
|||||||
// tlw that was "rolled up" with some WMs.
|
// tlw that was "rolled up" with some WMs.
|
||||||
// Queue a resize rather than sending size event directly to allow
|
// Queue a resize rather than sending size event directly to allow
|
||||||
// children to be made visible first.
|
// children to be made visible first.
|
||||||
win->m_oldClientWidth = 0;
|
win->m_useCachedClientSize = false;
|
||||||
|
win->m_clientWidth = 0;
|
||||||
gtk_widget_queue_resize(win->m_wxwindow);
|
gtk_widget_queue_resize(win->m_wxwindow);
|
||||||
}
|
}
|
||||||
// it is possible for m_isShown to be false here, see bug #9909
|
// it is possible for m_isShown to be false here, see bug #9909
|
||||||
@@ -1067,12 +1069,13 @@ void wxTopLevelWindowGTK::DoSetSize( int x, int y, int width, int height, int si
|
|||||||
if (m_width != oldSize.x || m_height != oldSize.y)
|
if (m_width != oldSize.x || m_height != oldSize.y)
|
||||||
{
|
{
|
||||||
m_deferShowAllowed = true;
|
m_deferShowAllowed = true;
|
||||||
|
m_useCachedClientSize = false;
|
||||||
|
|
||||||
int w, h;
|
int w, h;
|
||||||
GTKDoGetSize(&w, &h);
|
GTKDoGetSize(&w, &h);
|
||||||
gtk_window_resize(GTK_WINDOW(m_widget), w, h);
|
gtk_window_resize(GTK_WINDOW(m_widget), w, h);
|
||||||
|
|
||||||
GetClientSize(&m_oldClientWidth, &m_oldClientHeight);
|
DoGetClientSize(&m_clientWidth, &m_clientHeight);
|
||||||
wxSizeEvent event(GetSize(), GetId());
|
wxSizeEvent event(GetSize(), GetId());
|
||||||
event.SetEventObject(this);
|
event.SetEventObject(this);
|
||||||
HandleWindowEvent(event);
|
HandleWindowEvent(event);
|
||||||
@@ -1102,6 +1105,8 @@ void wxTopLevelWindowGTK::DoGetClientSize( int *width, int *height ) const
|
|||||||
if ( height )
|
if ( height )
|
||||||
*height = 0;
|
*height = 0;
|
||||||
}
|
}
|
||||||
|
else if (m_useCachedClientSize)
|
||||||
|
base_type::DoGetClientSize(width, height);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GTKDoGetSize(width, height);
|
GTKDoGetSize(width, height);
|
||||||
@@ -1159,6 +1164,7 @@ void wxTopLevelWindowGTK::GTKUpdateDecorSize(const wxSize& decorSize)
|
|||||||
GetCachedDecorSize() = decorSize;
|
GetCachedDecorSize() = decorSize;
|
||||||
if (m_updateDecorSize && m_decorSize != decorSize)
|
if (m_updateDecorSize && m_decorSize != decorSize)
|
||||||
{
|
{
|
||||||
|
m_useCachedClientSize = false;
|
||||||
const wxSize diff = decorSize - m_decorSize;
|
const wxSize diff = decorSize - m_decorSize;
|
||||||
m_decorSize = decorSize;
|
m_decorSize = decorSize;
|
||||||
bool resized = false;
|
bool resized = false;
|
||||||
@@ -1186,7 +1192,7 @@ void wxTopLevelWindowGTK::GTKUpdateDecorSize(const wxSize& decorSize)
|
|||||||
m_height += diff.y;
|
m_height += diff.y;
|
||||||
if (m_width < 1) m_width = 1;
|
if (m_width < 1) m_width = 1;
|
||||||
if (m_height < 1) m_height = 1;
|
if (m_height < 1) m_height = 1;
|
||||||
m_oldClientWidth = 0;
|
m_clientWidth = 0;
|
||||||
gtk_widget_queue_resize(m_wxwindow);
|
gtk_widget_queue_resize(m_wxwindow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1194,7 +1200,7 @@ void wxTopLevelWindowGTK::GTKUpdateDecorSize(const wxSize& decorSize)
|
|||||||
{
|
{
|
||||||
// gtk_widget_show() was deferred, do it now
|
// gtk_widget_show() was deferred, do it now
|
||||||
m_deferShow = false;
|
m_deferShow = false;
|
||||||
GetClientSize(&m_oldClientWidth, &m_oldClientHeight);
|
DoGetClientSize(&m_clientWidth, &m_clientHeight);
|
||||||
wxSizeEvent sizeEvent(GetSize(), GetId());
|
wxSizeEvent sizeEvent(GetSize(), GetId());
|
||||||
sizeEvent.SetEventObject(this);
|
sizeEvent.SetEventObject(this);
|
||||||
HandleWindowEvent(sizeEvent);
|
HandleWindowEvent(sizeEvent);
|
||||||
|
@@ -1910,10 +1910,11 @@ size_allocate(GtkWidget*, GtkAllocation* alloc, wxWindow* win)
|
|||||||
if (w < 0) w = 0;
|
if (w < 0) w = 0;
|
||||||
if (h < 0) h = 0;
|
if (h < 0) h = 0;
|
||||||
}
|
}
|
||||||
if (win->m_oldClientWidth != w || win->m_oldClientHeight != h)
|
win->m_useCachedClientSize = true;
|
||||||
|
if (win->m_clientWidth != w || win->m_clientHeight != h)
|
||||||
{
|
{
|
||||||
win->m_oldClientWidth = w;
|
win->m_clientWidth = w;
|
||||||
win->m_oldClientHeight = h;
|
win->m_clientHeight = h;
|
||||||
// this callback can be connected to m_wxwindow,
|
// this callback can be connected to m_wxwindow,
|
||||||
// so always get size from m_widget->allocation
|
// so always get size from m_widget->allocation
|
||||||
GtkAllocation a;
|
GtkAllocation a;
|
||||||
@@ -1960,18 +1961,9 @@ static void style_updated(GtkWidget*, wxWindow* win)
|
|||||||
static void style_updated(GtkWidget*, GtkStyle*, wxWindow* win)
|
static void style_updated(GtkWidget*, GtkStyle*, wxWindow* win)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (win->IsTopLevel())
|
wxSysColourChangedEvent event;
|
||||||
{
|
event.SetEventObject(win);
|
||||||
wxSysColourChangedEvent event;
|
win->GTKProcessEvent(event);
|
||||||
event.SetEventObject(win);
|
|
||||||
win->GTKProcessEvent(event);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Border width could change, which will change client size.
|
|
||||||
// Make sure size event occurs for this
|
|
||||||
win->m_oldClientWidth = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -2035,8 +2027,7 @@ void wxWindowGTK::GTKHandleRealized()
|
|||||||
|
|
||||||
GTKUpdateCursor(true, false);
|
GTKUpdateCursor(true, false);
|
||||||
|
|
||||||
if (m_wxwindow &&
|
if (m_wxwindow && IsTopLevel())
|
||||||
(IsTopLevel() || HasFlag(wxBORDER_RAISED | wxBORDER_SUNKEN | wxBORDER_THEME)))
|
|
||||||
{
|
{
|
||||||
// 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
|
||||||
@@ -2064,8 +2055,11 @@ void wxWindowGTK::GTKHandleUnrealize()
|
|||||||
if (m_imData)
|
if (m_imData)
|
||||||
gtk_im_context_set_client_window(m_imData->context, NULL);
|
gtk_im_context_set_client_window(m_imData->context, NULL);
|
||||||
|
|
||||||
g_signal_handlers_disconnect_by_func(
|
if (IsTopLevel())
|
||||||
m_wxwindow, (void*)style_updated, this);
|
{
|
||||||
|
g_signal_handlers_disconnect_by_func(
|
||||||
|
m_wxwindow, (void*)style_updated, this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2214,8 +2208,9 @@ void wxWindowGTK::Init()
|
|||||||
m_scrollPos[dir] = 0;
|
m_scrollPos[dir] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_oldClientWidth =
|
m_clientWidth =
|
||||||
m_oldClientHeight = 0;
|
m_clientHeight = 0;
|
||||||
|
m_useCachedClientSize = false;
|
||||||
|
|
||||||
m_clipPaintRegion = false;
|
m_clipPaintRegion = false;
|
||||||
|
|
||||||
@@ -2731,6 +2726,10 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags
|
|||||||
height = m_height;
|
height = m_height;
|
||||||
|
|
||||||
const bool sizeChange = m_width != width || m_height != height;
|
const bool sizeChange = m_width != width || m_height != height;
|
||||||
|
|
||||||
|
if (sizeChange)
|
||||||
|
m_useCachedClientSize = false;
|
||||||
|
|
||||||
if (sizeChange || m_x != x || m_y != y)
|
if (sizeChange || m_x != x || m_y != y)
|
||||||
{
|
{
|
||||||
m_x = x;
|
m_x = x;
|
||||||
@@ -2760,7 +2759,7 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags
|
|||||||
{
|
{
|
||||||
// update these variables to keep size_allocate handler
|
// update these variables to keep size_allocate handler
|
||||||
// from sending another size event for this change
|
// from sending another size event for this change
|
||||||
GetClientSize( &m_oldClientWidth, &m_oldClientHeight );
|
DoGetClientSize(&m_clientWidth, &m_clientHeight);
|
||||||
|
|
||||||
wxSizeEvent event( wxSize(m_width,m_height), GetId() );
|
wxSizeEvent event( wxSize(m_width,m_height), GetId() );
|
||||||
event.SetEventObject( this );
|
event.SetEventObject( this );
|
||||||
@@ -2825,6 +2824,13 @@ void wxWindowGTK::DoGetClientSize( int *width, int *height ) const
|
|||||||
{
|
{
|
||||||
wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
|
wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
|
||||||
|
|
||||||
|
if (m_useCachedClientSize)
|
||||||
|
{
|
||||||
|
if (width) *width = m_clientWidth;
|
||||||
|
if (height) *height = m_clientHeight;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int w = m_width;
|
int w = m_width;
|
||||||
int h = m_height;
|
int h = m_height;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user