wxWindowList::compatibility_iterator node = win->GetChildren().GetFirst();
while (node)
{
- wxWindowGTK *child = node->GetData();
+ wxWindow* child = static_cast<wxWindow*>(node->GetData());
node = node->GetNext();
if (!child->IsShown())
return wxWindowBase::Destroy();
}
+static GSList* gs_queueResizeList;
+
+extern "C" {
+static gboolean queue_resize(void*)
+{
+ gdk_threads_enter();
+ for (GSList* p = gs_queueResizeList; p; p = p->next)
+ {
+ if (p->data)
+ {
+ gtk_widget_queue_resize(GTK_WIDGET(p->data));
+ g_object_remove_weak_pointer(G_OBJECT(p->data), &p->data);
+ }
+ }
+ g_slist_free(gs_queueResizeList);
+ gs_queueResizeList = NULL;
+ gdk_threads_leave();
+ return false;
+}
+}
+
void wxWindowGTK::DoMoveWindow(int x, int y, int width, int height)
{
- gtk_widget_set_size_request(m_widget, width, height);
+ GtkWidget* parent = gtk_widget_get_parent(m_widget);
+ if (WX_IS_PIZZA(parent))
+ {
+ WX_PIZZA(parent)->move(m_widget, x, y);
+ gtk_widget_set_size_request(m_widget, width, height);
+ }
- // inform the parent to perform the move
- wxASSERT_MSG(m_parent && m_parent->m_wxwindow,
- "the parent window has no client area?");
- WX_PIZZA(m_parent->m_wxwindow)->move(m_widget, x, y);
+ // With GTK3, gtk_widget_queue_resize() is ignored while a size-allocate
+ // is in progress. This situation is common in wxWidgets, since
+ // size-allocate can generate wxSizeEvent and size event handlers often
+ // call SetSize(), directly or indirectly. Work around this by deferring
+ // the queue-resize until after size-allocate processing is finished.
+ if (g_slist_find(gs_queueResizeList, m_widget) == NULL)
+ {
+ if (gs_queueResizeList == NULL)
+ g_idle_add_full(GTK_PRIORITY_RESIZE, queue_resize, NULL, NULL);
+ gs_queueResizeList = g_slist_prepend(gs_queueResizeList, m_widget);
+ g_object_add_weak_pointer(G_OBJECT(m_widget), &gs_queueResizeList->data);
+ }
}
void wxWindowGTK::ConstrainSize()
void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags )
{
- wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") );
- wxASSERT_MSG( (m_parent != NULL), wxT("wxWindowGTK::SetSize requires parent.\n") );
+ wxCHECK_RET(m_widget, "invalid window");
- if ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0 && (x == -1 || y == -1))
+ int scrollX = 0, scrollY = 0;
+ GtkWidget* parent = gtk_widget_get_parent(m_widget);
+ if (WX_IS_PIZZA(parent))
{
- int currentX, currentY;
- GetPosition(¤tX, ¤tY);
- if (x == -1)
- x = currentX;
- if (y == -1)
- y = currentY;
+ wxPizza* pizza = WX_PIZZA(parent);
+ scrollX = pizza->m_scroll_x;
+ scrollY = pizza->m_scroll_y;
}
- AdjustForParentClientOrigin(x, y, sizeFlags);
+ if (x != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+ x += scrollX;
+ else
+ x = m_x;
+ if (y != -1 || (sizeFlags & wxSIZE_ALLOW_MINUS_ONE))
+ y += scrollY;
+ else
+ y = m_y;
// calculate the best size if we should auto size the window
if ( ((sizeFlags & wxSIZE_AUTO_WIDTH) && width == -1) ||
height = sizeBest.y;
}
- const wxSize oldSize(m_width, m_height);
- if (width != -1)
- m_width = width;
- if (height != -1)
- m_height = height;
+ if (width == -1)
+ width = m_width;
+ if (height == -1)
+ height = m_height;
- if (m_parent->m_wxwindow)
+ const bool sizeChange = m_width != width || m_height != height;
+ if (sizeChange || m_x != x || m_y != y)
{
- wxPizza* pizza = WX_PIZZA(m_parent->m_wxwindow);
- m_x = x + pizza->m_scroll_x;
- m_y = y + pizza->m_scroll_y;
-
- int left_border = 0;
- int right_border = 0;
- int top_border = 0;
- int bottom_border = 0;
+ m_x = x;
+ m_y = y;
+ m_width = width;
+ m_height = height;
/* the default button has a border around it */
if (gtk_widget_get_can_default(m_widget))
gtk_widget_style_get( m_widget, "default_border", &default_border, NULL );
if (default_border)
{
- left_border += default_border->left;
- right_border += default_border->right;
- top_border += default_border->top;
- bottom_border += default_border->bottom;
+ x -= default_border->left;
+ y -= default_border->top;
+ width += default_border->left + default_border->right;
+ height += default_border->top + default_border->bottom;
gtk_border_free( default_border );
}
}
- DoMoveWindow( m_x - left_border,
- m_y - top_border,
- m_width+left_border+right_border,
- m_height+top_border+bottom_border );
+ DoMoveWindow(x, y, width, height);
}
- if (m_width != oldSize.x || m_height != oldSize.y)
+ if ((sizeChange && !m_nativeSizeEvent) || (sizeFlags & wxSIZE_FORCE_EVENT))
{
// update these variables to keep size_allocate handler
// from sending another size event for this change
GetClientSize( &m_oldClientWidth, &m_oldClientHeight );
- gtk_widget_queue_resize(m_widget);
- if (!m_nativeSizeEvent)
- {
- wxSizeEvent event( wxSize(m_width,m_height), GetId() );
- event.SetEventObject( this );
- HandleWindowEvent( event );
- }
- } else
- if (sizeFlags & wxSIZE_FORCE_EVENT)
- {
wxSizeEvent event( wxSize(m_width,m_height), GetId() );
event.SetEventObject( this );
HandleWindowEvent( event );