X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e56307d3196b614ae7a09e53dda87b339cbbc913..1e6ffd6691b959e7be4aee314e4218b316be0923:/src/gtk/win_gtk.cpp diff --git a/src/gtk/win_gtk.cpp b/src/gtk/win_gtk.cpp index 0e21432e6a..30576aa367 100644 --- a/src/gtk/win_gtk.cpp +++ b/src/gtk/win_gtk.cpp @@ -8,7 +8,7 @@ /////////////////////////////////////////////////////////////////////////////// #include "wx/defs.h" -#include "wx/gtk/win_gtk.h" +#include "wx/gtk/private/win_gtk.h" /* wxPizza is a custom GTK+ widget derived from GtkFixed. A custom widget @@ -64,29 +64,28 @@ static void size_allocate(GtkWidget* widget, GtkAllocation* alloc) if (pizza->m_is_scrollable) { - // backing window is inside border + // two windows, both same size gdk_window_move_resize(pizza->m_backing_window, alloc->x + border_x, alloc->y + border_y, w, h); + if (is_resize) + gdk_window_resize(widget->window, w, h); + } + else if (pizza->m_backing_window) + { + // two windows, widget->window is smaller by border widths (need to + // move widget->window as well as resize because border can change) + gdk_window_move_resize(pizza->m_backing_window, + alloc->x, alloc->y, alloc->width, alloc->height); + gdk_window_move_resize(widget->window, border_x, border_y, w, h); } else { - // border window (or only window if - // no-scroll no-border) is full size - GdkWindow* window = pizza->m_backing_window; - if (window == NULL) - window = widget->window; - gdk_window_move_resize( - window, alloc->x, alloc->y, alloc->width, alloc->height); + // one window + gdk_window_move_resize(widget->window, + alloc->x, alloc->y, alloc->width, alloc->height); } if (is_resize && pizza->m_backing_window) { - // main window is inside border - if (pizza->m_is_scrollable) - gdk_window_resize(widget->window, w, h); - else - // need move as well as resize because border can change - gdk_window_move_resize(widget->window, border_x, border_y, w, h); - // wxWidgets turns off redraw-on-allocate by default, // so border area needs to be invalidated if (border_x > 1 || border_y > 1) @@ -166,6 +165,11 @@ static void realize(GtkWidget* widget) else gdk_window_reparent(widget->window, pizza->m_backing_window, border_x, border_y); gdk_window_resize(widget->window, w, h); + + // Parts of m_backing_window which are supposed to be obscured may be + // exposed temporarily while resizing. Setting the backing pixmap to + // None prevents those areas from being briefly painted black. + gdk_window_set_back_pixmap(pizza->m_backing_window, NULL, false); } } @@ -298,8 +302,8 @@ GtkWidget* wxPizza::New(long windowStyle) pizza->m_scroll_x = 0; pizza->m_scroll_y = 0; pizza->m_is_scrollable = (windowStyle & (wxHSCROLL | wxVSCROLL)) != 0; - pizza->m_border_style = - int(windowStyle & (wxBORDER_SIMPLE | wxBORDER_RAISED | wxBORDER_SUNKEN)); + // mask off border styles not useable with wxPizza + pizza->m_border_style = int(windowStyle & BORDER_STYLES); gtk_fixed_set_has_window(GTK_FIXED(widget), true); gtk_widget_add_events(widget, GDK_EXPOSURE_MASK | @@ -317,7 +321,6 @@ GtkWidget* wxPizza::New(long windowStyle) GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_FOCUS_CHANGE_MASK); - gtk_container_set_resize_mode(GTK_CONTAINER(widget), GTK_RESIZE_QUEUE); return widget; } @@ -338,6 +341,30 @@ void wxPizza::move(GtkWidget* widget, int x, int y) } } +struct AdjustData { + GdkWindow* window; + int dx, dy; +}; + +// Adjust allocations for all widgets using the GdkWindow which was just scrolled +extern "C" { +static void scroll_adjust(GtkWidget* widget, void* data) +{ + const AdjustData* p = static_cast(data); + if (widget->window == p->window) + { + widget->allocation.x += p->dx; + widget->allocation.y += p->dy; + // GtkFrame requires a queue_resize, otherwise parts of + // the frame newly exposed by the scroll are not drawn. + // To be safe, do it for all widgets. + gtk_widget_queue_resize_no_redraw(widget); + if (GTK_IS_CONTAINER(widget)) + gtk_container_forall(GTK_CONTAINER(widget), scroll_adjust, data); + } +} +} + void wxPizza::scroll(int dx, int dy) { GtkWidget* widget = GTK_WIDGET(this); @@ -346,16 +373,17 @@ void wxPizza::scroll(int dx, int dy) m_scroll_x -= dx; m_scroll_y -= dy; if (widget->window) - gdk_window_scroll(widget->window, dx, dy); - const GList* list = m_fixed.children; - if (list) { - const GtkFixedChild* child = static_cast(list->data); - // queueing a resize on any child will update them all - gtk_widget_queue_resize(child->widget); + gdk_window_scroll(widget->window, dx, dy); + // Adjust child allocations. Doing a queue_resize on the children is not + // enough, sometimes they redraw in the wrong place during fast scrolling. + AdjustData data = { widget->window, dx, dy }; + gtk_container_forall(GTK_CONTAINER(widget), scroll_adjust, &data); } } +extern GtkWidget *GetEntryWidget(); + void wxPizza::get_border_widths(int& x, int& y) { x = y = 0; @@ -363,11 +391,11 @@ void wxPizza::get_border_widths(int& x, int& y) x = y = 1; else if (m_border_style) { - GtkWidget* widget = GTK_WIDGET(this); - if (widget->style) + GtkWidget *entry_widget = GetEntryWidget(); + if (entry_widget->style) { - x = widget->style->xthickness; - y = widget->style->ythickness; + x = entry_widget->style->xthickness; + y = entry_widget->style->ythickness; } } }