From 3b7067a05dd2373eb4d6b1a2d6d5699232eaa333 Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Thu, 17 May 2012 15:29:50 +0000 Subject: [PATCH] Remove use of "size-request" signal for wxWindow sizing. This signal has been removed from GTK3. Instead have wxPizza keep track of child size, and use gtk_widget_set_size_request() for wxWindows in native containers. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@71465 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/gtk/filepicker.h | 2 -- include/wx/gtk/infobar.h | 1 - include/wx/gtk/private/win_gtk.h | 5 +-- include/wx/gtk/window.h | 5 --- src/gtk/filedlg.cpp | 16 ++------- src/gtk/frame.cpp | 28 ++++------------ src/gtk/mdi.cpp | 8 ----- src/gtk/minifram.cpp | 14 ++++---- src/gtk/toolbar.cpp | 23 ------------- src/gtk/toplevel.cpp | 27 +++++---------- src/gtk/win_gtk.cpp | 71 +++++++++++++++++++++++++++++++--------- src/gtk/window.cpp | 44 ++++--------------------- 12 files changed, 91 insertions(+), 153 deletions(-) diff --git a/include/wx/gtk/filepicker.h b/include/wx/gtk/filepicker.h index 14267d6..51ef90f 100644 --- a/include/wx/gtk/filepicker.h +++ b/include/wx/gtk/filepicker.h @@ -107,8 +107,6 @@ public: // overrides FILEDIRBTN_OVERRIDES protected: - virtual bool GTKShouldConnectSizeRequest() const { return false; } - wxDialog *m_dialog; private: diff --git a/include/wx/gtk/infobar.h b/include/wx/gtk/infobar.h index 5c1ee29..7275756 100644 --- a/include/wx/gtk/infobar.h +++ b/include/wx/gtk/infobar.h @@ -54,7 +54,6 @@ public: void GTKResponse(int btnid); protected: - virtual bool GTKShouldConnectSizeRequest() const { return false; } virtual void DoApplyWidgetStyle(GtkRcStyle *style); private: diff --git a/include/wx/gtk/private/win_gtk.h b/include/wx/gtk/private/win_gtk.h index 010afa0..b5d2a77 100644 --- a/include/wx/gtk/private/win_gtk.h +++ b/include/wx/gtk/private/win_gtk.h @@ -23,12 +23,13 @@ struct WXDLLIMPEXP_CORE wxPizza static GtkWidget* New(long windowStyle = 0); static GType type(); - void move(GtkWidget* widget, int x, int y); - void put(GtkWidget* widget, int x, int y); + void move(GtkWidget* widget, int x, int y, int width, int height); + void put(GtkWidget* widget, int x, int y, int width, int height); void scroll(int dx, int dy); void get_border_widths(int& x, int& y); GtkFixed m_fixed; + GList* m_children; int m_scroll_x; int m_scroll_y; int m_border_style; diff --git a/include/wx/gtk/window.h b/include/wx/gtk/window.h index 55b034c..b555f9e 100644 --- a/include/wx/gtk/window.h +++ b/include/wx/gtk/window.h @@ -382,11 +382,6 @@ protected: // just as it does. unsigned long GTKConnectWidget(const char *signal, wxGTKCallback callback); - // Return true from here if PostCreation() should connect to size_request - // signal: this is done by default but doesn't work for some native - // controls which override this function to return false - virtual bool GTKShouldConnectSizeRequest() const { return !IsTopLevel(); } - void ConstrainSize(); private: diff --git a/src/gtk/filedlg.cpp b/src/gtk/filedlg.cpp index ef6f3e0..ad0ac78 100644 --- a/src/gtk/filedlg.cpp +++ b/src/gtk/filedlg.cpp @@ -135,22 +135,12 @@ static void gtk_filedialog_update_preview_callback(GtkFileChooser *chooser, } // extern "C" -//----------------------------------------------------------------------------- -// "size_request" from m_extraControl -//----------------------------------------------------------------------------- - -extern "C" { -static void extra_widget_size_request(GtkWidget*, GtkRequisition* req, wxWindow* win) +void wxFileDialog::AddChildGTK(wxWindowGTK* child) { // allow dialog to be resized smaller horizontally - req->width = win->GetMinWidth(); -} -} + gtk_widget_set_size_request( + child->m_widget, child->GetMinWidth(), child->m_height); -void wxFileDialog::AddChildGTK(wxWindowGTK* child) -{ - g_signal_connect_after(child->m_widget, "size_request", - G_CALLBACK(extra_widget_size_request), child); gtk_file_chooser_set_extra_widget( GTK_FILE_CHOOSER(m_widget), child->m_widget); } diff --git a/src/gtk/frame.cpp b/src/gtk/frame.cpp index 37272e7..a44b4bf 100644 --- a/src/gtk/frame.cpp +++ b/src/gtk/frame.cpp @@ -300,16 +300,6 @@ void wxFrame::AttachMenuBar( wxMenuBar *menuBar ) GTK_BOX(m_mainWidget), menuBar->m_widget, false, false, 0); gtk_box_reorder_child(GTK_BOX(m_mainWidget), menuBar->m_widget, 0); - // disconnect wxWindowGTK "size_request" handler, - // it interferes with sizing of detached GtkHandleBox - gulong handler_id = g_signal_handler_find( - menuBar->m_widget, - GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA), - g_signal_lookup("size_request", GTK_TYPE_WIDGET), - 0, NULL, NULL, menuBar); - if (handler_id != 0) - g_signal_handler_disconnect(menuBar->m_widget, handler_id); - // reset size request to allow native sizing to work gtk_widget_set_size_request(menuBar->m_widget, -1, -1); @@ -364,17 +354,6 @@ void wxFrame::SetToolBar(wxToolBar *toolbar) gtk_box_reorder_child( GTK_BOX(m_mainWidget), toolbar->m_widget, pos); } - - // disconnect wxWindowGTK "size_request" handler, - // it interferes with sizing of detached GtkHandleBox - gulong handler_id = g_signal_handler_find( - toolbar->m_widget, - GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA), - g_signal_lookup("size_request", GTK_TYPE_WIDGET), - 0, NULL, NULL, toolbar); - if (handler_id != 0) - g_signal_handler_disconnect(toolbar->m_widget, handler_id); - // reset size request to allow native sizing to work gtk_widget_set_size_request(toolbar->m_widget, -1, -1); } @@ -397,6 +376,13 @@ void wxFrame::SetStatusBar(wxStatusBar *statbar) statbar->m_widget, false, false, 0, GTK_PACK_END); // make sure next size_allocate on statusbar causes a size event statbar->m_oldClientWidth = 0; + int h = -1; + if (statbar->m_wxwindow) + { + // statusbar is not a native widget, need to set height request + h = statbar->m_height; + } + gtk_widget_set_size_request(statbar->m_widget, -1, h); } // make sure next size_allocate causes a wxSizeEvent m_oldClientWidth = 0; diff --git a/src/gtk/mdi.cpp b/src/gtk/mdi.cpp index bd97417..b124225 100644 --- a/src/gtk/mdi.cpp +++ b/src/gtk/mdi.cpp @@ -316,14 +316,6 @@ void wxMDIChildFrame::SetMenuBar( wxMenuBar *menu_bar ) m_menuBar->Show(false); gtk_box_pack_start(GTK_BOX(mdi_frame->m_mainWidget), m_menuBar->m_widget, false, false, 0); gtk_box_reorder_child(GTK_BOX(mdi_frame->m_mainWidget), m_menuBar->m_widget, 0); - - gulong handler_id = g_signal_handler_find( - m_menuBar->m_widget, - GSignalMatchType(G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DATA), - g_signal_lookup("size_request", GTK_TYPE_WIDGET), - 0, NULL, NULL, m_menuBar); - if (handler_id != 0) - g_signal_handler_disconnect(m_menuBar->m_widget, handler_id); gtk_widget_set_size_request(m_menuBar->m_widget, -1, -1); } } diff --git a/src/gtk/minifram.cpp b/src/gtk/minifram.cpp index e7b8f70..e1a2aaa 100644 --- a/src/gtk/minifram.cpp +++ b/src/gtk/minifram.cpp @@ -333,6 +333,14 @@ bool wxMiniFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title m_diffX = 0; m_diffY = 0; + // don't allow sizing smaller than decorations + int minWidth = 2 * m_miniEdge; + int minHeight = 2 * m_miniEdge + m_miniTitle; + if (m_minWidth < minWidth) + m_minWidth = minWidth; + if (m_minHeight < minHeight) + m_minHeight = minHeight; + wxFrame::Create( parent, id, title, pos, size, style, name ); // Use a GtkEventBox for the title and borders. Using m_widget for this @@ -360,12 +368,6 @@ bool wxMiniFrame::Create( wxWindow *parent, wxWindowID id, const wxString &title m_decorSize.Set(0, 0); m_deferShow = false; - // don't allow sizing smaller than decorations - GdkGeometry geom; - geom.min_width = 2 * m_miniEdge; - geom.min_height = 2 * m_miniEdge + m_miniTitle; - gtk_window_set_geometry_hints(GTK_WINDOW(m_widget), NULL, &geom, GDK_HINT_MIN_SIZE); - if (m_parent && (GTK_IS_WINDOW(m_parent->m_widget))) { gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(m_parent->m_widget) ); diff --git a/src/gtk/toolbar.cpp b/src/gtk/toolbar.cpp index 3050ca9..8e86454 100644 --- a/src/gtk/toolbar.cpp +++ b/src/gtk/toolbar.cpp @@ -169,20 +169,6 @@ enter_notify_event(GtkWidget*, GdkEventCrossing* event, wxToolBarTool* tool) } //----------------------------------------------------------------------------- -// "size_request" from m_toolbar -//----------------------------------------------------------------------------- - -extern "C" { -static void -size_request(GtkWidget*, GtkRequisition* req, wxToolBar* win) -{ - const wxSize margins = win->GetMargins(); - req->width += margins.x; - req->height += 2 * margins.y; -} -} - -//----------------------------------------------------------------------------- // "expose_event" from GtkImage inside m_item //----------------------------------------------------------------------------- @@ -415,9 +401,6 @@ bool wxToolBar::Create( wxWindow *parent, PostCreation(size); - g_signal_connect_after(m_toolbar, "size_request", - G_CALLBACK(size_request), this); - return true; } @@ -597,12 +580,6 @@ bool wxToolBar::DoInsertTool(size_t pos, wxToolBarToolBase *toolBase) gtk_toolbar_insert(m_toolbar, tool->m_item, int(pos)); g_object_unref(tool->m_item); } - // Inserted items "slide" into place using an animated effect that - // causes multiple size events on the item. Must set size request - // to keep item size from getting permanently set too small by the - // first of these size events. - const wxSize size = control->GetSize(); - gtk_widget_set_size_request(control->m_widget, size.x, size.y); break; } gtk_widget_show(GTK_WIDGET(tool->m_item)); diff --git a/src/gtk/toplevel.cpp b/src/gtk/toplevel.cpp index b55b566..0545234 100644 --- a/src/gtk/toplevel.cpp +++ b/src/gtk/toplevel.cpp @@ -246,22 +246,6 @@ size_allocate(GtkWidget*, GtkAllocation* alloc, wxTopLevelWindowGTK* win) } } -// ---------------------------------------------------------------------------- -// "size_request" -// ---------------------------------------------------------------------------- - -extern "C" { -static -void wxgtk_tlw_size_request_callback(GtkWidget * WXUNUSED(widget), - GtkRequisition *requisition, - wxTopLevelWindowGTK *win) -{ - // we must return the size of the window without WM decorations, otherwise - // GTK+ gets confused, so don't call just GetSize() here - win->GTKDoGetSize(&requisition->width, &requisition->height); -} -} - //----------------------------------------------------------------------------- // "delete_event" //----------------------------------------------------------------------------- @@ -628,8 +612,6 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, g_signal_connect(m_wxwindow, "size_allocate", G_CALLBACK(size_allocate), this); - g_signal_connect (m_widget, "size_request", - G_CALLBACK (wxgtk_tlw_size_request_callback), this); PostCreation(); #if !GTK_CHECK_VERSION(3,0,0) && !defined(GTK_DISABLE_DEPRECATED) @@ -703,6 +685,15 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, } } + // GTK sometimes chooses very small size if max size hint is not explicitly set + int maxWidth = m_maxWidth; + int maxHeight = m_maxHeight; + if (maxWidth < 0) + maxWidth = INT_MAX; + if (maxHeight < 0) + maxHeight = INT_MAX; + DoSetSizeHints(m_minWidth, m_minHeight, maxWidth, maxHeight, -1, -1); + m_decorSize = GetCachedDecorSize(); int w, h; GTKDoGetSize(&w, &h); diff --git a/src/gtk/win_gtk.cpp b/src/gtk/win_gtk.cpp index d5c4a35..5475bf6 100644 --- a/src/gtk/win_gtk.cpp +++ b/src/gtk/win_gtk.cpp @@ -29,6 +29,12 @@ drawn on wxPizza's parent GdkWindow. For RTL, child widget positions are mirrored in size_allocate. */ +struct wxPizzaChild +{ + GtkWidget* widget; + int x, y, width, height; +}; + static GtkWidgetClass* parent_class; extern "C" { @@ -77,9 +83,9 @@ static void size_allocate(GtkWidget* widget, GtkAllocation* alloc) widget->allocation = *alloc; // adjust child positions - for (const GList* list = pizza->m_fixed.children; list; list = list->next) + for (const GList* p = pizza->m_children; p; p = p->next) { - const GtkFixedChild* child = static_cast(list->data); + const wxPizzaChild* child = static_cast(p->data); if (gtk_widget_get_visible(child->widget)) { GtkAllocation child_alloc; @@ -88,10 +94,8 @@ static void size_allocate(GtkWidget* widget, GtkAllocation* alloc) // which has already been adjusted child_alloc.x = child->x - pizza->m_scroll_x; child_alloc.y = child->y - pizza->m_scroll_y; - GtkRequisition req; - gtk_widget_get_child_requisition(child->widget, &req); - child_alloc.width = req.width; - child_alloc.height = req.height; + child_alloc.width = child->width; + child_alloc.height = child->height; if (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL) child_alloc.x = w - child_alloc.x - child_alloc.width; gtk_widget_size_allocate(child->widget, &child_alloc); @@ -142,6 +146,28 @@ static void hide(GtkWidget* widget) parent_class->hide(widget); } +static void pizza_add(GtkContainer* container, GtkWidget* widget) +{ + WX_PIZZA(container)->put(widget, 0, 0, 1, 1); +} + +static void pizza_remove(GtkContainer* container, GtkWidget* widget) +{ + GTK_CONTAINER_CLASS(parent_class)->remove(container, widget); + + wxPizza* pizza = WX_PIZZA(container); + for (GList* p = pizza->m_children; p; p = p->next) + { + wxPizzaChild* child = static_cast(p->data); + if (child->widget == widget) + { + pizza->m_children = g_list_delete_link(pizza->m_children, p); + delete child; + break; + } + } +} + // not used, but needs to exist so gtk_widget_set_scroll_adjustments will work static void set_scroll_adjustments(GtkWidget*, GtkAdjustment*, GtkAdjustment*) { @@ -193,6 +219,9 @@ static void class_init(void* g_class, void*) widget_class->realize = realize; widget_class->show = show; widget_class->hide = hide; + GtkContainerClass* container_class = (GtkContainerClass*)g_class; + container_class->add = pizza_add; + container_class->remove = pizza_remove; wxPizzaClass* klass = (wxPizzaClass*)g_class; // needed to make widget appear scrollable to GTK+ @@ -235,6 +264,7 @@ GtkWidget* wxPizza::New(long windowStyle) { GtkWidget* widget = GTK_WIDGET(g_object_new(type(), NULL)); wxPizza* pizza = WX_PIZZA(widget); + pizza->m_children = NULL; pizza->m_scroll_x = 0; pizza->m_scroll_y = 0; pizza->m_is_scrollable = (windowStyle & (wxHSCROLL | wxVSCROLL)) != 0; @@ -264,26 +294,35 @@ GtkWidget* wxPizza::New(long windowStyle) return widget; } -// gtk_fixed_move does not check for a change before issuing a queue_resize, -// we need to avoid that to prevent endless sizing loops, so check first -void wxPizza::move(GtkWidget* widget, int x, int y) +void wxPizza::move(GtkWidget* widget, int x, int y, int width, int height) { - GtkFixed* fixed = &m_fixed; - for (const GList* list = fixed->children; list; list = list->next) + for (const GList* p = m_children; p; p = p->next) { - const GtkFixedChild* child = static_cast(list->data); + wxPizzaChild* child = static_cast(p->data); if (child->widget == widget) { - if (child->x != x || child->y != y) - gtk_fixed_move(fixed, widget, x, y); + child->x = x; + child->y = y; + child->width = width; + child->height = height; + // normally a queue-resize would be needed here, but we know + // wxWindowGTK::DoMoveWindow() will take care of it break; } } } -void wxPizza::put(GtkWidget* widget, int x, int y) +void wxPizza::put(GtkWidget* widget, int x, int y, int width, int height) { - gtk_fixed_put(&m_fixed, widget, x, y); + gtk_fixed_put(GTK_FIXED(this), widget, 0, 0); + + wxPizzaChild* child = new wxPizzaChild; + child->widget = widget; + child->x = x; + child->y = y; + child->width = width; + child->height = height; + m_children = g_list_append(m_children, child); } struct AdjustData { diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index b878d59..2b1d991 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -222,28 +222,6 @@ int g_lastButtonNumber = 0; #define TRACE_FOCUS wxT("focus") //----------------------------------------------------------------------------- -// "size_request" of m_widget -//----------------------------------------------------------------------------- - -extern "C" { -static void -wxgtk_window_size_request_callback(GtkWidget * WXUNUSED(widget), - GtkRequisition *requisition, - wxWindow * win) -{ - int w, h; - win->GetSize( &w, &h ); - if (w < 2) - w = 2; - if (h < 2) - h = 2; - - requisition->height = h; - requisition->width = w; -} -} - -//----------------------------------------------------------------------------- // "expose_event" of m_wxwindow //----------------------------------------------------------------------------- @@ -2088,9 +2066,8 @@ void wxWindowGTK::AddChildGTK(wxWindowGTK* child) child->m_x += pizza->m_scroll_x; child->m_y += pizza->m_scroll_y; - gtk_widget_set_size_request( - child->m_widget, child->m_width, child->m_height); - pizza->put(child->m_widget, child->m_x, child->m_y); + pizza->put(child->m_widget, + child->m_x, child->m_y, child->m_width, child->m_height); } //----------------------------------------------------------------------------- @@ -2505,16 +2482,8 @@ void wxWindowGTK::PostCreation() } #endif // GTK+ >= 2.8 - if ( GTKShouldConnectSizeRequest() ) - { - // This is needed if we want to add our windows into native - // GTK controls, such as the toolbar. With this callback, the - // toolbar gets to know the correct size (the one set by the - // programmer). Sadly, it misbehaves for wxComboBox. - g_signal_connect (m_widget, "size_request", - G_CALLBACK (wxgtk_window_size_request_callback), - this); - } + if (!WX_IS_PIZZA(gtk_widget_get_parent(m_widget)) && !GTK_IS_WINDOW(m_widget)) + gtk_widget_set_size_request(m_widget, m_width, m_height); InheritAttributes(); @@ -2600,10 +2569,9 @@ void wxWindowGTK::DoMoveWindow(int x, int y, int width, int height) { GtkWidget* parent = gtk_widget_get_parent(m_widget); if (WX_IS_PIZZA(parent)) - { - WX_PIZZA(parent)->move(m_widget, x, y); + WX_PIZZA(parent)->move(m_widget, x, y, width, height); + else gtk_widget_set_size_request(m_widget, width, height); - } // With GTK3, gtk_widget_queue_resize() is ignored while a size-allocate // is in progress. This situation is common in wxWidgets, since -- 2.7.4