From 8df84db8428a8553711051f3d6c5227f46885a35 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 6 Nov 2019 15:04:35 +0100 Subject: [PATCH 1/3] Add EnsureValidXWindowSize() helper to wxX11 code Instead of repeating the same checks in several places, do it in a single one. Also use the smallest possible valid size (1, 1) instead of the totally arbitrary (20, 20). --- src/x11/window.cpp | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/x11/window.cpp b/src/x11/window.cpp index a83d2d33a1..d0cf0cad9c 100644 --- a/src/x11/window.cpp +++ b/src/x11/window.cpp @@ -98,6 +98,26 @@ wxEND_EVENT_TABLE() // helper functions // ---------------------------------------------------------------------------- +namespace +{ + +// Passing size with a 0 component to X11 functions results in a BadValue X +// error, so ensure we never do it by using the smallest valid size instead. +inline void EnsureValidXWindowSize(int& x, int& y) +{ + if ( x <= 0 ) + x = 1; + if ( y <= 0 ) + y = 1; +} + +inline void EnsureValidXWindowSize(wxSize& size) +{ + EnsureValidXWindowSize(size.x, size.y); +} + +} // anonymous namespace + // ---------------------------------------------------------------------------- // constructors // ---------------------------------------------------------------------------- @@ -155,13 +175,8 @@ bool wxWindowX11::Create(wxWindow *parent, wxWindowID id, xparent = (Window) parent->X11GetMainWindow(); } - // Size (not including the border) must be nonzero (or a Value error results)! - // Note: The Xlib manual doesn't mention this restriction of XCreateWindow. wxSize size2(size); - if (size2.x <= 0) - size2.x = 20; - if (size2.y <= 0) - size2.y = 20; + EnsureValidXWindowSize(size2); wxPoint pos2(pos); if (pos2.x == wxDefaultCoord) @@ -258,10 +273,7 @@ bool wxWindowX11::Create(wxWindow *parent, wxWindowID id, } // Make again sure the size is nonzero. - if (size2.x <= 0) - size2.x = 1; - if (size2.y <= 0) - size2.y = 1; + EnsureValidXWindowSize(size2); #if wxUSE_NANOX backColor = GR_RGB(m_backgroundColour.Red(), m_backgroundColour.Green(), m_backgroundColour.Blue()); @@ -920,16 +932,13 @@ void wxWindowX11::DoSetSize(int x, int y, int width, int height, int sizeFlags) if (width != wxDefaultCoord) { new_w = width; - if (new_w <= 0) - new_w = 20; } if (height != wxDefaultCoord) { new_h = height; - if (new_h <= 0) - new_h = 20; } + EnsureValidXWindowSize(new_w, new_h); DoMoveWindow( new_x, new_y, new_w, new_h ); } From 23f76146264b32bee7c97d07fe486f57873833df Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 6 Nov 2019 15:05:47 +0100 Subject: [PATCH 2/3] Don't set 0 client size in wxX11 neither This also results in BadValue X11 error, so ensure that the size is valid here too, just as we do in DoSetSize(). --- src/x11/window.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/x11/window.cpp b/src/x11/window.cpp index d0cf0cad9c..373151892a 100644 --- a/src/x11/window.cpp +++ b/src/x11/window.cpp @@ -950,6 +950,7 @@ void wxWindowX11::DoSetClientSize(int width, int height) wxCHECK_RET( xwindow, wxT("invalid window") ); + EnsureValidXWindowSize(width, height); XResizeWindow( wxGlobalDisplay(), xwindow, width, height ); if (m_mainWindow != m_clientWindow) @@ -965,6 +966,7 @@ void wxWindowX11::DoSetClientSize(int width, int height) height -= border.y + border.height; } + EnsureValidXWindowSize(width, height); XResizeWindow( wxGlobalDisplay(), xwindow, width, height ); } } From cdc588e4eb724c242cce83ce90d4812478528262 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 6 Nov 2019 15:06:36 +0100 Subject: [PATCH 3/3] Don't resize the parent from wxToolBar::SetSize() in wxUniv This could result in infinite recursion in wxX11, as the test for the new size being different from the old one which was supposed to stop the recursion, failed there in case the new size was 0: as wxX11 can't use 0 size for the window, the actual size was always different and so we kept sending size events to the parent, which kept resizing the toolbar etc. It could be argued that there is a bug in wxX11 and that GetSize() must return the same value as was passed to SetSize(), even if it was 0, and this might even be correct, in theory, but it doesn't seem worth to do it just to accommodate this weird use case, especially because resizing the parent from the child shouldn't be necessary in the first place and none of wxToolBar implementations in the other ports does it. So just remove this code completely. Closes #18554. --- include/wx/univ/toolbar.h | 3 --- src/univ/toolbar.cpp | 27 --------------------------- 2 files changed, 30 deletions(-) diff --git a/include/wx/univ/toolbar.h b/include/wx/univ/toolbar.h index 7ab15e4bb8..b393311e60 100644 --- a/include/wx/univ/toolbar.h +++ b/include/wx/univ/toolbar.h @@ -101,9 +101,6 @@ protected: const wxString& label) wxOVERRIDE; virtual wxSize DoGetBestClientSize() const wxOVERRIDE; - virtual void DoSetSize(int x, int y, - int width, int height, - int sizeFlags = wxSIZE_AUTO) wxOVERRIDE; virtual void DoDraw(wxControlRenderer *renderer) wxOVERRIDE; // get the bounding rect for the given tool diff --git a/src/univ/toolbar.cpp b/src/univ/toolbar.cpp index 833bd80334..2c2ceffd6c 100644 --- a/src/univ/toolbar.cpp +++ b/src/univ/toolbar.cpp @@ -563,33 +563,6 @@ wxSize wxToolBar::DoGetBestClientSize() const return wxSize(m_maxWidth, m_maxHeight); } -void wxToolBar::DoSetSize(int x, int y, int width, int height, int sizeFlags) -{ - int old_width, old_height; - GetSize(&old_width, &old_height); - - wxToolBarBase::DoSetSize(x, y, width, height, sizeFlags); - - // Correct width and height if needed. - if ( width == wxDefaultCoord || height == wxDefaultCoord ) - { - int tmp_width, tmp_height; - GetSize(&tmp_width, &tmp_height); - - if ( width == wxDefaultCoord ) - width = tmp_width; - if ( height == wxDefaultCoord ) - height = tmp_height; - } - - // We must refresh the frame size when the toolbar changes size - // otherwise the toolbar can be shown incorrectly - if ( old_width != width || old_height != height ) - { - SendSizeEventToParent(); - } -} - // ---------------------------------------------------------------------------- // wxToolBar drawing // ----------------------------------------------------------------------------