From b6fa52db667283fea7eaba7abe3dc48b8631f360 Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Thu, 9 Mar 2000 13:24:34 +0000 Subject: [PATCH] Some make corrections for HP and related, Changed refresh order so that window-less widgets don't get overdrawn anymore, Prevent GTK from filtering our supposedly unneeded expose events, Block all expose calls if a resize is requested and do a full redraw then, thus removing flicker and behaving like wxMSW, Moved some doubled expose and draw code from GtkPizza to the respective callbacks in window.cpp, Set idle priority to a higher value (which should indicate a lower priority if I interpret glib.h correctly) but the desired side-effect didn't really show up. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6533 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- Makefile.in | 6 +- configure.in | 1 + include/wx/gtk/win_gtk.h | 10 ++ include/wx/gtk/window.h | 2 + include/wx/gtk1/win_gtk.h | 10 ++ include/wx/gtk1/window.h | 2 + samples/caret/caret.cpp | 2 +- samples/help/demo.cpp | 2 +- samples/html/about/about.cpp | 2 +- samples/html/test/test.cpp | 2 +- src/generic/filedlgg.cpp | 2 + src/gtk/app.cpp | 8 +- src/gtk/dcclient.cpp | 5 +- src/gtk/frame.cpp | 1 + src/gtk/win_gtk.c | 201 ++++++++++++-------------------- src/gtk/window.cpp | 218 +++++++++++++++++++++++++++++------ src/gtk1/app.cpp | 8 +- src/gtk1/dcclient.cpp | 5 +- src/gtk1/frame.cpp | 1 + src/gtk1/win_gtk.c | 201 ++++++++++++-------------------- src/gtk1/window.cpp | 218 +++++++++++++++++++++++++++++------ 21 files changed, 557 insertions(+), 350 deletions(-) diff --git a/Makefile.in b/Makefile.in index 338b740dd5..c3e5994dec 100644 --- a/Makefile.in +++ b/Makefile.in @@ -751,6 +751,7 @@ SAMPLES_DIST: ALL_GUI_DIST cp $(SAMPDIR)/drawing/makefile.unx $(DISTDIR)/samples/drawing cp $(SAMPDIR)/drawing/*.cpp $(DISTDIR)/samples/drawing cp $(SAMPDIR)/drawing/*.xpm $(DISTDIR)/samples/drawing + cp $(SAMPDIR)/drawing/*.bmp $(DISTDIR)/samples/drawing mkdir $(DISTDIR)/samples/dynamic cp $(SAMPDIR)/dynamic/Makefile.in $(DISTDIR)/samples/dynamic @@ -806,6 +807,7 @@ SAMPLES_DIST: ALL_GUI_DIST cp $(SAMPDIR)/html/test/*.cpp $(DISTDIR)/samples/html/test cp $(SAMPDIR)/html/test/*.bmp $(DISTDIR)/samples/html/test cp $(SAMPDIR)/html/test/*.png $(DISTDIR)/samples/html/test + cp $(SAMPDIR)/html/test/*.gif $(DISTDIR)/samples/html/test cp $(SAMPDIR)/html/test/*.htm $(DISTDIR)/samples/html/test cp $(SAMPDIR)/html/test/*.html $(DISTDIR)/samples/html/test mkdir $(DISTDIR)/samples/html/virtual @@ -839,10 +841,10 @@ SAMPLES_DIST: ALL_GUI_DIST cp $(SAMPDIR)/internat/*.xpm $(DISTDIR)/samples/internat cp $(SAMPDIR)/internat/*.txt $(DISTDIR)/samples/internat cp $(SAMPDIR)/internat/*.po $(DISTDIR)/samples/internat - cp $(SAMPDIR)/internat/fr/*.po $(DISTDIR)/samples/internat/fr + cp $(SAMPDIR)/internat/fr/*.mo $(DISTDIR)/samples/internat/fr cp $(SAMPDIR)/internat/de/*.mo $(DISTDIR)/samples/internat/de cp $(SAMPDIR)/internat/fr/*.po $(DISTDIR)/samples/internat/fr - cp $(SAMPDIR)/internat/de/*.mo $(DISTDIR)/samples/internat/de + cp $(SAMPDIR)/internat/de/*.po $(DISTDIR)/samples/internat/de mkdir $(DISTDIR)/samples/ipc cp $(SAMPDIR)/ipc/Makefile.in $(DISTDIR)/samples/ipc diff --git a/configure.in b/configure.in index 9e995e02e4..4aa404df89 100644 --- a/configure.in +++ b/configure.in @@ -51,6 +51,7 @@ dnl #include #include #include +#include int main () diff --git a/include/wx/gtk/win_gtk.h b/include/wx/gtk/win_gtk.h index b4bd331726..afede32a49 100644 --- a/include/wx/gtk/win_gtk.h +++ b/include/wx/gtk/win_gtk.h @@ -33,9 +33,19 @@ typedef enum GTK_MYSHADOW_OUT } GtkMyShadowType; +typedef struct _GtkPizzaChild GtkPizzaChild; typedef struct _GtkPizza GtkPizza; typedef struct _GtkPizzaClass GtkPizzaClass; +struct _GtkPizzaChild +{ + GtkWidget *widget; + gint x; + gint y; + gint width; + gint height; +}; + struct _GtkPizza { GtkContainer container; diff --git a/include/wx/gtk/window.h b/include/wx/gtk/window.h index 302d12e95f..914a9a045a 100644 --- a/include/wx/gtk/window.h +++ b/include/wx/gtk/window.h @@ -186,6 +186,8 @@ public: bool m_isFrame:1; /* faster than IS_KIND_OF */ bool m_acceptsFocus:1; /* not wxStaticBox, not wxStaticBitmap etc. */ bool m_isScrolling; + bool m_clipPaintRegion; /* TRUE after ScrollWindow() */ + bool m_queuedFullRedraw; /* TRUE after DoMoveWindow */ // these are true if the style were set before the widget was realized // (typcally in the constructor) but the actual GTK style must not be set diff --git a/include/wx/gtk1/win_gtk.h b/include/wx/gtk1/win_gtk.h index b4bd331726..afede32a49 100644 --- a/include/wx/gtk1/win_gtk.h +++ b/include/wx/gtk1/win_gtk.h @@ -33,9 +33,19 @@ typedef enum GTK_MYSHADOW_OUT } GtkMyShadowType; +typedef struct _GtkPizzaChild GtkPizzaChild; typedef struct _GtkPizza GtkPizza; typedef struct _GtkPizzaClass GtkPizzaClass; +struct _GtkPizzaChild +{ + GtkWidget *widget; + gint x; + gint y; + gint width; + gint height; +}; + struct _GtkPizza { GtkContainer container; diff --git a/include/wx/gtk1/window.h b/include/wx/gtk1/window.h index 302d12e95f..914a9a045a 100644 --- a/include/wx/gtk1/window.h +++ b/include/wx/gtk1/window.h @@ -186,6 +186,8 @@ public: bool m_isFrame:1; /* faster than IS_KIND_OF */ bool m_acceptsFocus:1; /* not wxStaticBox, not wxStaticBitmap etc. */ bool m_isScrolling; + bool m_clipPaintRegion; /* TRUE after ScrollWindow() */ + bool m_queuedFullRedraw; /* TRUE after DoMoveWindow */ // these are true if the style were set before the widget was realized // (typcally in the constructor) but the actual GTK style must not be set diff --git a/samples/caret/caret.cpp b/samples/caret/caret.cpp index 5e41c55f79..a1c9367a74 100644 --- a/samples/caret/caret.cpp +++ b/samples/caret/caret.cpp @@ -128,7 +128,7 @@ enum Minimal_Test2, // controls start here (the numbers are, of course, arbitrary) - Minimal_Text = 1000, + Minimal_Text = 1000 }; // ---------------------------------------------------------------------------- diff --git a/samples/help/demo.cpp b/samples/help/demo.cpp index a27dfef41a..35778a4694 100644 --- a/samples/help/demo.cpp +++ b/samples/help/demo.cpp @@ -127,7 +127,7 @@ enum HelpDemo_Help_GNOME, HelpDemo_Help_Netscape, // controls start here (the numbers are, of course, arbitrary) - HelpDemo_Text = 1000, + HelpDemo_Text = 1000 }; // ---------------------------------------------------------------------------- diff --git a/samples/html/about/about.cpp b/samples/html/about/about.cpp index f4c03cfeb6..a97c5e58c3 100644 --- a/samples/html/about/about.cpp +++ b/samples/html/about/about.cpp @@ -74,7 +74,7 @@ Minimal_Forward, // controls start here (the numbers are, of course, arbitrary) - Minimal_Text = 1000, + Minimal_Text = 1000 }; // ---------------------------------------------------------------------------- diff --git a/samples/html/test/test.cpp b/samples/html/test/test.cpp index cfb493b4ed..a7130fcb79 100644 --- a/samples/html/test/test.cpp +++ b/samples/html/test/test.cpp @@ -75,7 +75,7 @@ Minimal_Forward, // controls start here (the numbers are, of course, arbitrary) - Minimal_Text = 1000, + Minimal_Text = 1000 }; // ---------------------------------------------------------------------------- diff --git a/src/generic/filedlgg.cpp b/src/generic/filedlgg.cpp index 60b582dcfb..0026835965 100644 --- a/src/generic/filedlgg.cpp +++ b/src/generic/filedlgg.cpp @@ -928,9 +928,11 @@ wxFileDialog::wxFileDialog(wxWindow *parent, Centre( wxBOTH ); +/* if (m_fileName.IsEmpty()) m_list->SetFocus(); else +*/ m_text->SetFocus(); wxEndBusyCursor(); diff --git a/src/gtk/app.cpp b/src/gtk/app.cpp index b89d77cd5c..ddeb9691a0 100644 --- a/src/gtk/app.cpp +++ b/src/gtk/app.cpp @@ -95,8 +95,8 @@ bool wxYield() if (has_idle) { - /* re-add idle handler */ - wxTheApp->m_idleTag = gtk_idle_add( wxapp_idle_callback, (gpointer) NULL ); + /* re-add idle handler (very low priority) */ + wxTheApp->m_idleTag = gtk_idle_add_priority( 500, wxapp_idle_callback, (gpointer) NULL ); } // disable log flushing from here because a call to wxYield() shouldn't @@ -177,9 +177,9 @@ void wxapp_install_idle_handler() indicating that the idle is over. It may also get called from other thread for sending events to the main thread (and processing these in - idle time). */ + idle time). Very low priority. */ - wxTheApp->m_idleTag = gtk_idle_add( wxapp_idle_callback, (gpointer) NULL ); + wxTheApp->m_idleTag = gtk_idle_add_priority( 500, wxapp_idle_callback, (gpointer) NULL ); g_isIdle = FALSE; } diff --git a/src/gtk/dcclient.cpp b/src/gtk/dcclient.cpp index 1dbaf55b39..0e930e4cff 100644 --- a/src/gtk/dcclient.cpp +++ b/src/gtk/dcclient.cpp @@ -2019,7 +2019,10 @@ wxPaintDC::wxPaintDC() wxPaintDC::wxPaintDC( wxWindow *win ) : wxWindowDC( win ) { -#if USE_PAINT_REGION +#if USE_PAINT_REGION + if (!win->m_clipPaintRegion) + return; + m_paintClippingRegion = win->GetUpdateRegion(); m_currentClippingRegion.Union( m_paintClippingRegion ); diff --git a/src/gtk/frame.cpp b/src/gtk/frame.cpp index 301a3b309d..2bc208bcb4 100644 --- a/src/gtk/frame.cpp +++ b/src/gtk/frame.cpp @@ -834,6 +834,7 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), gtk_pizza_set_size( GTK_PIZZA(m_wxwindow), m_frameStatusBar->m_widget, xx, yy, ww, hh ); + gtk_widget_draw( m_frameStatusBar->m_widget, (GdkRectangle*) NULL ); } #endif diff --git a/src/gtk/win_gtk.c b/src/gtk/win_gtk.c index f97158acf9..7d5f7a92ad 100644 --- a/src/gtk/win_gtk.c +++ b/src/gtk/win_gtk.c @@ -30,7 +30,6 @@ extern "C" { (y >= G_MINSHORT) && (y <= G_MAXSHORT)) typedef struct _GtkPizzaAdjData GtkPizzaAdjData; -typedef struct _GtkPizzaChild GtkPizzaChild; struct _GtkPizzaAdjData { @@ -38,22 +37,13 @@ struct _GtkPizzaAdjData gint dy; }; -struct _GtkPizzaChild -{ - GtkWidget *widget; - gint x; - gint y; - gint width; - gint height; -}; - -static void gtk_pizza_class_init (GtkPizzaClass *klass); -static void gtk_pizza_init (GtkPizza *pizza); +static void gtk_pizza_class_init (GtkPizzaClass *klass); +static void gtk_pizza_init (GtkPizza *pizza); -static void gtk_pizza_realize (GtkWidget *widget); -static void gtk_pizza_unrealize (GtkWidget *widget); +static void gtk_pizza_realize (GtkWidget *widget); +static void gtk_pizza_unrealize (GtkWidget *widget); -static void gtk_pizza_map (GtkWidget *widget); +static void gtk_pizza_map (GtkWidget *widget); static void gtk_pizza_size_request (GtkWidget *widget, GtkRequisition *requisition); @@ -67,42 +57,42 @@ static void gtk_pizza_add (GtkContainer *container, GtkWidget *widget); static void gtk_pizza_remove (GtkContainer *container, GtkWidget *widget); -static void gtk_pizza_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data); +static void gtk_pizza_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data); static void gtk_pizza_position_child (GtkPizza *pizza, - GtkPizzaChild *child); + GtkPizzaChild *child); static void gtk_pizza_allocate_child (GtkPizza *pizza, - GtkPizzaChild *child); + GtkPizzaChild *child); static void gtk_pizza_position_children (GtkPizza *pizza); static void gtk_pizza_adjust_allocations_recurse (GtkWidget *widget, - gpointer cb_data); -static void gtk_pizza_adjust_allocations (GtkPizza *pizza, - gint dx, - gint dy); + gpointer cb_data); +static void gtk_pizza_adjust_allocations (GtkPizza *pizza, + gint dx, + gint dy); -static void gtk_pizza_expose_area (GtkPizza *pizza, - gint x, - gint y, - gint width, - gint height); +static void gtk_pizza_expose_area (GtkPizza *pizza, + gint x, + gint y, + gint width, + gint height); static void gtk_pizza_adjustment_changed (GtkAdjustment *adjustment, - GtkPizza *pizza); + GtkPizza *pizza); static GdkFilterReturn gtk_pizza_filter (GdkXEvent *gdk_xevent, - GdkEvent *event, - gpointer data); + GdkEvent *event, + gpointer data); static GdkFilterReturn gtk_pizza_main_filter (GdkXEvent *gdk_xevent, - GdkEvent *event, - gpointer data); + GdkEvent *event, + gpointer data); static GtkType gtk_pizza_child_type (GtkContainer *container); -static void gtk_pizza_scroll_set_adjustments (GtkPizza *pizza, +static void gtk_pizza_scroll_set_adjustments (GtkPizza *pizza, GtkAdjustment *hadj, GtkAdjustment *vadj); @@ -200,7 +190,7 @@ gtk_pizza_init (GtkPizza *pizza) pizza->visibility = GDK_VISIBILITY_PARTIAL; pizza->clear_on_draw = TRUE; - pizza->use_filter = FALSE; + pizza->use_filter = TRUE; } GtkWidget* @@ -222,7 +212,7 @@ gtk_pizza_scroll_set_adjustments (GtkPizza *pizza, } void -gtk_pizza_set_shadow_type (GtkPizza *pizza, +gtk_pizza_set_shadow_type (GtkPizza *pizza, GtkMyShadowType type) { g_return_if_fail (pizza != NULL); @@ -241,8 +231,8 @@ gtk_pizza_set_shadow_type (GtkPizza *pizza, } void -gtk_pizza_set_clear (GtkPizza *pizza, - gboolean clear) +gtk_pizza_set_clear (GtkPizza *pizza, + gboolean clear) { g_return_if_fail (pizza != NULL); g_return_if_fail (GTK_IS_PIZZA (pizza)); @@ -251,8 +241,8 @@ gtk_pizza_set_clear (GtkPizza *pizza, } void -gtk_pizza_set_filter (GtkPizza *pizza, - gboolean use) +gtk_pizza_set_filter (GtkPizza *pizza, + gboolean use) { g_return_if_fail (pizza != NULL); g_return_if_fail (GTK_IS_PIZZA (pizza)); @@ -261,12 +251,12 @@ gtk_pizza_set_filter (GtkPizza *pizza, } void -gtk_pizza_put (GtkPizza *pizza, - GtkWidget *widget, - gint x, - gint y, - gint width, - gint height) +gtk_pizza_put (GtkPizza *pizza, + GtkWidget *widget, + gint x, + gint y, + gint width, + gint height) { GtkPizzaChild *child_info; @@ -311,10 +301,10 @@ gtk_pizza_put (GtkPizza *pizza, } void -gtk_pizza_move (GtkPizza *pizza, - GtkWidget *widget, - gint x, - gint y) +gtk_pizza_move (GtkPizza *pizza, + GtkWidget *widget, + gint x, + gint y) { GtkPizzaChild *child; GList *children; @@ -345,10 +335,10 @@ gtk_pizza_move (GtkPizza *pizza, } void -gtk_pizza_resize (GtkPizza *pizza, - GtkWidget *widget, - gint width, - gint height) +gtk_pizza_resize (GtkPizza *pizza, + GtkWidget *widget, + gint width, + gint height) { GtkPizzaChild *child; GList *children; @@ -381,12 +371,12 @@ gtk_pizza_resize (GtkPizza *pizza, } void -gtk_pizza_set_size (GtkPizza *pizza, - GtkWidget *widget, - gint x, - gint y, - gint width, - gint height) +gtk_pizza_set_size (GtkPizza *pizza, + GtkWidget *widget, + gint x, + gint y, + gint width, + gint height) { GtkPizzaChild *child; GList *children; @@ -539,7 +529,7 @@ gtk_pizza_realize (GtkWidget *widget) widget->style = gtk_style_attach (widget->style, widget->window); gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); - gtk_style_set_background (widget->style, pizza->bin_window, GTK_STATE_NORMAL); + gtk_style_set_background (widget->style, pizza->bin_window, GTK_STATE_NORMAL ); /* add filters for intercepting visibility and expose events */ gdk_window_add_filter (widget->window, gtk_pizza_main_filter, pizza); @@ -579,7 +569,7 @@ gtk_pizza_unrealize (GtkWidget *widget) static void gtk_pizza_size_request (GtkWidget *widget, - GtkRequisition *requisition) + GtkRequisition *requisition) { GtkPizza *pizza; GtkPizzaChild *child; @@ -612,7 +602,7 @@ gtk_pizza_size_request (GtkWidget *widget, static void gtk_pizza_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) + GtkAllocation *allocation) { GtkPizza *pizza; gint border; @@ -660,70 +650,17 @@ gtk_pizza_size_allocate (GtkWidget *widget, static void gtk_pizza_draw (GtkWidget *widget, - GdkRectangle *area) + GdkRectangle *area) { - GtkPizza *pizza; - GtkPizzaChild *child; - GdkRectangle child_area; - GList *children; - - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_PIZZA (widget)); - - pizza = GTK_PIZZA (widget); - - children = pizza->children; - if ( !(GTK_WIDGET_APP_PAINTABLE (widget)) && - (pizza->clear_on_draw)) - { - gdk_window_clear_area( pizza->bin_window, - area->x, area->y, area->width, area->height); - } - - while (children) - { - child = children->data; - children = children->next; - - if (gtk_widget_intersect (child->widget, area, &child_area)) - gtk_widget_draw (child->widget, &child_area); - } + /* We handle all draws events in window.cpp now. */ + return; } static gint gtk_pizza_expose (GtkWidget *widget, - GdkEventExpose *event) + GdkEventExpose *event) { - GtkPizza *pizza; - GtkPizzaChild *child; - GdkEventExpose child_event; - GList *children; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_PIZZA (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - pizza = GTK_PIZZA (widget); - - if (event->window != pizza->bin_window) - return FALSE; - - children = pizza->children; - while (children) - { - child = children->data; - children = children->next; - - child_event = *event; - - if (GTK_WIDGET_NO_WINDOW (child->widget) && - GTK_WIDGET_DRAWABLE (child->widget) && - gtk_widget_intersect (child->widget, &event->area, &child_event.area)) - { - gtk_widget_event (child->widget, (GdkEvent*) &child_event); - } - } - + /* We handle all expose events in window.cpp now. */ return FALSE; } @@ -740,7 +677,7 @@ gtk_pizza_add (GtkContainer *container, static void gtk_pizza_remove (GtkContainer *container, - GtkWidget *widget) + GtkWidget *widget) { GtkPizza *pizza; GtkPizzaChild *child; @@ -782,9 +719,9 @@ gtk_pizza_remove (GtkContainer *container, static void gtk_pizza_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data) + gboolean include_internals, + GtkCallback callback, + gpointer callback_data) { GtkPizza *pizza; GtkPizzaChild *child; @@ -812,7 +749,7 @@ gtk_pizza_forall (GtkContainer *container, static void gtk_pizza_position_child (GtkPizza *pizza, - GtkPizzaChild *child) + GtkPizzaChild *child) { gint x; gint y; @@ -844,7 +781,7 @@ gtk_pizza_position_child (GtkPizza *pizza, static void gtk_pizza_allocate_child (GtkPizza *pizza, - GtkPizzaChild *child) + GtkPizzaChild *child) { GtkAllocation allocation; GtkRequisition requisition; @@ -1166,6 +1103,9 @@ gtk_pizza_filter (GdkXEvent *gdk_xevent, pizza = GTK_PIZZA (data); + if (!pizza->use_filter) + return GDK_FILTER_CONTINUE; + switch (xevent->type) { case Expose: @@ -1210,6 +1150,9 @@ gtk_pizza_main_filter (GdkXEvent *gdk_xevent, xevent = (XEvent *)gdk_xevent; pizza = GTK_PIZZA (data); + + if (!pizza->use_filter) + return GDK_FILTER_CONTINUE; if (xevent->type == VisibilityNotify) { diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 7525485937..06e4797192 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -381,10 +381,13 @@ static void draw_frame( GtkWidget *widget, wxWindow *win ) // "expose_event" of m_widget //----------------------------------------------------------------------------- -static void gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win ) +gint gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win ) { - if (gdk_event->count > 0) return; + if (gdk_event->count > 0) return FALSE; + draw_frame( widget, win ); + + return TRUE; } //----------------------------------------------------------------------------- @@ -610,12 +613,18 @@ static long map_to_wx_keysym( KeySym keysym ) // "expose_event" of m_wxwindow //----------------------------------------------------------------------------- -static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExpose *gdk_event, wxWindow *win ) +static int gtk_window_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win ) { DEBUG_MAIN_THREAD + if (g_isIdle) + wxapp_install_idle_handler(); + + if (win->m_queuedFullRedraw) + return TRUE; + /* - if (win->GetName() == wxT("grid window")) + if (win->GetName() == wxT("htmlWindow")) { wxPrintf( wxT("OnExpose from ") ); if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) @@ -634,10 +643,7 @@ static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExp if (gdk_event->count > 0) - return; - - if (!win->m_hasVMT) - return; + return TRUE; wxEraseEvent eevent( win->GetId() ); eevent.SetEventObject( win ); @@ -648,25 +654,85 @@ static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExp win->GetEventHandler()->ProcessEvent( event ); win->GetUpdateRegion().Clear(); + + /* The following code will result in all window-less widgets + being redrawn if the wxWindows class is given a chance to + paint *anything* because it will then be allowed to paint + over the window-less widgets */ + + GtkPizza *pizza = GTK_PIZZA (widget); + + GList *children = pizza->children; + while (children) + { + GtkPizzaChild *child = (GtkPizzaChild*) children->data; + children = children->next; + + GdkEventExpose child_event = *gdk_event; + + if (GTK_WIDGET_NO_WINDOW (child->widget) && + GTK_WIDGET_DRAWABLE (child->widget)) + { + child_event.area.x = child->widget->allocation.x; + child_event.area.y = child->widget->allocation.y; + child_event.area.width = child->widget->allocation.width; + child_event.area.height = child->widget->allocation.height; + gtk_widget_event (child->widget, (GdkEvent*) &child_event); + } + } + + return TRUE; +} + +//----------------------------------------------------------------------------- +// "event" of m_wxwindow +//----------------------------------------------------------------------------- + +/* GTK thinks it is clever and filters out a certain amount of "unneeded" + expose events. We need them, of course, so we override the main event + procedure in GtkWidget by giving our own handler for all system events, + looking for the expose events and then we can always send them. */ + +gint gtk_window_event_event_callback( GtkWidget *widget, GdkEventExpose *event, wxWindow *win ) +{ + if (event->type == GDK_EXPOSE) + { + gint ret = gtk_window_expose_callback( widget, event, win ); + return ret; + } + + + return FALSE; } //----------------------------------------------------------------------------- // "draw" of m_wxwindow //----------------------------------------------------------------------------- -static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget), - GdkRectangle *rect, wxWindow *win ) +/* This callback is a complete replacement of the gtk_pizza_draw() function, + which disabled. */ + +static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxWindow *win ) { DEBUG_MAIN_THREAD if (g_isIdle) wxapp_install_idle_handler(); - if ((rect->x == 0) && (rect->y == 0) && (rect->width <= 1) && (rect->height <= 1)) + if (win->m_queuedFullRedraw) return; + GtkPizza *pizza = GTK_PIZZA (widget); + + if ( !(GTK_WIDGET_APP_PAINTABLE (widget)) && + (pizza->clear_on_draw)) + { + gdk_window_clear_area( pizza->bin_window, + rect->x, rect->y, rect->width, rect->height); + } + /* - if (win->GetName() == wxT("grid window")) + if (win->GetName() == wxT("htmlWindow")) { wxPrintf( wxT("OnDraw from ") ); if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) @@ -677,13 +743,10 @@ static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget), (int)rect->height ); } */ - + win->GetUpdateRegion().Union( rect->x, rect->y, rect->width, rect->height ); - if (!win->m_hasVMT) - return; - wxEraseEvent eevent( win->GetId() ); eevent.SetEventObject( win ); win->GetEventHandler()->ProcessEvent(eevent); @@ -693,6 +756,17 @@ static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget), win->GetEventHandler()->ProcessEvent( event ); win->GetUpdateRegion().Clear(); + + GList *children = pizza->children; + while (children) + { + GtkPizzaChild *child = (GtkPizzaChild*) children->data; + children = children->next; + + GdkRectangle child_area; + if (gtk_widget_intersect (child->widget, rect, &child_area)) + gtk_widget_draw (child->widget, (GdkRectangle*) NULL ); + } } //----------------------------------------------------------------------------- @@ -1974,6 +2048,9 @@ void wxWindow::Init() m_isFrame = FALSE; m_acceptsFocus = FALSE; + m_clipPaintRegion = FALSE; + m_queuedFullRedraw = FALSE; + m_cursor = *wxSTANDARD_CURSOR; #ifdef HAVE_XIM @@ -2008,21 +2085,12 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, } m_insertCallback = wxInsertChildInWindow; - + m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL ); GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); -#ifdef __WXDEBUG__ - debug_focus_in( m_widget, wxT("wxWindow::m_widget"), name ); -#endif - GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(m_widget); -#ifdef __WXDEBUG__ - debug_focus_in( scrolledWindow->hscrollbar, wxT("wxWindow::hsrcollbar"), name ); - debug_focus_in( scrolledWindow->vscrollbar, wxT("wxWindow::vsrcollbar"), name ); -#endif - GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass ); scroll_class->scrollbar_spacing = 0; @@ -2033,10 +2101,6 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, m_wxwindow = gtk_pizza_new(); -#ifdef __WXDEBUG__ - debug_focus_in( m_wxwindow, wxT("wxWindow::m_wxwindow"), name ); -#endif - gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow ); #if (GTK_MINOR_VERSION > 0) @@ -2221,6 +2285,9 @@ void wxWindow::PostCreation() if (!m_noExpose) { /* these get reported to wxWindows -> wxPaintEvent */ + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "event", + GTK_SIGNAL_FUNC(gtk_window_event_event_callback), (gpointer)this ); + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event", GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this ); @@ -2320,6 +2387,24 @@ bool wxWindow::Destroy() void wxWindow::DoMoveWindow(int x, int y, int width, int height) { + if (m_wxwindow && GTK_PIZZA(m_wxwindow)->bin_window) + { + /* Normally, GTK will send expose events only for the regions + which actually got exposed. Sadly, wxMSW invalidates + the whole window so we have to do that, too. We could + simply add a complete refresh, but we would then get + the normal GTK expose events in surplus, so we shut + off the expose events and schedule a full redraw to + be done in OnInternalIdle, where we restore the handling + of expose events. */ + + m_queuedFullRedraw = TRUE; + + GdkEventMask mask = gdk_window_get_events( GTK_PIZZA(m_wxwindow)->bin_window ); + mask = (GdkEventMask)(mask & ~GDK_EXPOSURE_MASK); + gdk_window_set_events( GTK_PIZZA(m_wxwindow)->bin_window, mask ); + } + gtk_pizza_set_size( GTK_PIZZA(m_parent->m_wxwindow), m_widget, x, y, width, height ); } @@ -2330,7 +2415,7 @@ void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags ) if (m_resizing) return; /* I don't like recursions */ m_resizing = TRUE; - + if (m_parent->m_wxwindow == NULL) /* i.e. wxNotebook */ { /* don't set the size for children of wxNotebook, just take the values. */ @@ -2391,6 +2476,12 @@ void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags ) if (m_hasScrolling) { + /* Sometimes the client area changes size without the + whole windows's size changing, but if the whole + windows's size doesn't change, no wxSizeEvent will + normally be sent. Here we add an extra test if + the client test has been changed and this will + be used then. */ GetClientSize( &m_oldClientWidth, &m_oldClientHeight ); } @@ -2461,6 +2552,27 @@ void wxWindow::OnInternalIdle() } UpdateWindowUI(); + + if (m_queuedFullRedraw) + { + /* See also wxWindow::DoMoveWindow for explanation of this code. What + we test here is if the requested size of the window is the same as + the actual size of window, in which case all expose events that resulted + from resizing the window have been sent (and discarded) and we can + now do our full redraw and switch on expose event handling again. */ + + if ((m_width == m_widget->allocation.width) && (m_height == m_widget->allocation.height)) + { + m_queuedFullRedraw = FALSE; + m_updateRegion.Clear(); + m_updateRegion.Union( 0,0,m_width,m_height ); + gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL ); + + GdkEventMask mask = gdk_window_get_events( GTK_PIZZA(m_wxwindow)->bin_window ); + mask = (GdkEventMask)(mask | GDK_EXPOSURE_MASK); + gdk_window_set_events( GTK_PIZZA(m_wxwindow)->bin_window, mask ); + } + } } void wxWindow::DoGetSize( int *width, int *height ) const @@ -2898,37 +3010,65 @@ void wxWindow::Refresh( bool eraseBackground, const wxRect *rect ) { if (m_wxwindow) { + +/* GtkPizza *pizza = GTK_PIZZA(m_wxwindow); gboolean old_clear = pizza->clear_on_draw; gtk_pizza_set_clear( pizza, FALSE ); - gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL ); - gtk_pizza_set_clear( pizza, old_clear ); +*/ + GdkEventExpose gdk_event; + gdk_event.count = 0; + gdk_event.area.x = 0; + gdk_event.area.y = 0; + gdk_event.area.width = m_wxwindow->allocation.width; + gdk_event.area.height = m_wxwindow->allocation.height; + gtk_window_expose_callback( m_wxwindow, &gdk_event, this ); + } else + { gtk_widget_draw( m_widget, (GdkRectangle*) NULL ); + } } else { - GdkRectangle gdk_rect; - gdk_rect.x = rect->x; - gdk_rect.y = rect->y; - gdk_rect.width = rect->width; - gdk_rect.height = rect->height; if (m_wxwindow) { +/* GtkPizza *pizza = GTK_PIZZA(m_wxwindow); gboolean old_clear = pizza->clear_on_draw; gtk_pizza_set_clear( pizza, FALSE ); + GdkRectangle gdk_rect; + gdk_rect.x = rect->x; + gdk_rect.y = rect->y; + gdk_rect.width = rect->width; + gdk_rect.height = rect->height; gtk_widget_draw( m_wxwindow, &gdk_rect ); + gtk_window_draw_callback( m_wxwindow, &gdk_rect, this ); gtk_pizza_set_clear( pizza, old_clear ); +*/ + GdkEventExpose gdk_event; + gdk_event.count = 0; + gdk_event.area.x = rect->x; + gdk_event.area.y = rect->y; + gdk_event.area.width = rect->width; + gdk_event.area.height = rect->height; + gtk_window_expose_callback( m_wxwindow, &gdk_event, this ); } else + { + GdkRectangle gdk_rect; + gdk_rect.x = rect->x; + gdk_rect.y = rect->y; + gdk_rect.width = rect->width; + gdk_rect.height = rect->height; gtk_widget_draw( m_widget, &gdk_rect ); + } } } @@ -3452,7 +3592,9 @@ void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) ) if ((dx == 0) && (dy == 0)) return; + m_clipPaintRegion = TRUE; gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy ); + m_clipPaintRegion = FALSE; /* if (m_children.GetCount() > 0) diff --git a/src/gtk1/app.cpp b/src/gtk1/app.cpp index b89d77cd5c..ddeb9691a0 100644 --- a/src/gtk1/app.cpp +++ b/src/gtk1/app.cpp @@ -95,8 +95,8 @@ bool wxYield() if (has_idle) { - /* re-add idle handler */ - wxTheApp->m_idleTag = gtk_idle_add( wxapp_idle_callback, (gpointer) NULL ); + /* re-add idle handler (very low priority) */ + wxTheApp->m_idleTag = gtk_idle_add_priority( 500, wxapp_idle_callback, (gpointer) NULL ); } // disable log flushing from here because a call to wxYield() shouldn't @@ -177,9 +177,9 @@ void wxapp_install_idle_handler() indicating that the idle is over. It may also get called from other thread for sending events to the main thread (and processing these in - idle time). */ + idle time). Very low priority. */ - wxTheApp->m_idleTag = gtk_idle_add( wxapp_idle_callback, (gpointer) NULL ); + wxTheApp->m_idleTag = gtk_idle_add_priority( 500, wxapp_idle_callback, (gpointer) NULL ); g_isIdle = FALSE; } diff --git a/src/gtk1/dcclient.cpp b/src/gtk1/dcclient.cpp index 1dbaf55b39..0e930e4cff 100644 --- a/src/gtk1/dcclient.cpp +++ b/src/gtk1/dcclient.cpp @@ -2019,7 +2019,10 @@ wxPaintDC::wxPaintDC() wxPaintDC::wxPaintDC( wxWindow *win ) : wxWindowDC( win ) { -#if USE_PAINT_REGION +#if USE_PAINT_REGION + if (!win->m_clipPaintRegion) + return; + m_paintClippingRegion = win->GetUpdateRegion(); m_currentClippingRegion.Union( m_paintClippingRegion ); diff --git a/src/gtk1/frame.cpp b/src/gtk1/frame.cpp index 301a3b309d..2bc208bcb4 100644 --- a/src/gtk1/frame.cpp +++ b/src/gtk1/frame.cpp @@ -834,6 +834,7 @@ void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y), gtk_pizza_set_size( GTK_PIZZA(m_wxwindow), m_frameStatusBar->m_widget, xx, yy, ww, hh ); + gtk_widget_draw( m_frameStatusBar->m_widget, (GdkRectangle*) NULL ); } #endif diff --git a/src/gtk1/win_gtk.c b/src/gtk1/win_gtk.c index f97158acf9..7d5f7a92ad 100644 --- a/src/gtk1/win_gtk.c +++ b/src/gtk1/win_gtk.c @@ -30,7 +30,6 @@ extern "C" { (y >= G_MINSHORT) && (y <= G_MAXSHORT)) typedef struct _GtkPizzaAdjData GtkPizzaAdjData; -typedef struct _GtkPizzaChild GtkPizzaChild; struct _GtkPizzaAdjData { @@ -38,22 +37,13 @@ struct _GtkPizzaAdjData gint dy; }; -struct _GtkPizzaChild -{ - GtkWidget *widget; - gint x; - gint y; - gint width; - gint height; -}; - -static void gtk_pizza_class_init (GtkPizzaClass *klass); -static void gtk_pizza_init (GtkPizza *pizza); +static void gtk_pizza_class_init (GtkPizzaClass *klass); +static void gtk_pizza_init (GtkPizza *pizza); -static void gtk_pizza_realize (GtkWidget *widget); -static void gtk_pizza_unrealize (GtkWidget *widget); +static void gtk_pizza_realize (GtkWidget *widget); +static void gtk_pizza_unrealize (GtkWidget *widget); -static void gtk_pizza_map (GtkWidget *widget); +static void gtk_pizza_map (GtkWidget *widget); static void gtk_pizza_size_request (GtkWidget *widget, GtkRequisition *requisition); @@ -67,42 +57,42 @@ static void gtk_pizza_add (GtkContainer *container, GtkWidget *widget); static void gtk_pizza_remove (GtkContainer *container, GtkWidget *widget); -static void gtk_pizza_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data); +static void gtk_pizza_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data); static void gtk_pizza_position_child (GtkPizza *pizza, - GtkPizzaChild *child); + GtkPizzaChild *child); static void gtk_pizza_allocate_child (GtkPizza *pizza, - GtkPizzaChild *child); + GtkPizzaChild *child); static void gtk_pizza_position_children (GtkPizza *pizza); static void gtk_pizza_adjust_allocations_recurse (GtkWidget *widget, - gpointer cb_data); -static void gtk_pizza_adjust_allocations (GtkPizza *pizza, - gint dx, - gint dy); + gpointer cb_data); +static void gtk_pizza_adjust_allocations (GtkPizza *pizza, + gint dx, + gint dy); -static void gtk_pizza_expose_area (GtkPizza *pizza, - gint x, - gint y, - gint width, - gint height); +static void gtk_pizza_expose_area (GtkPizza *pizza, + gint x, + gint y, + gint width, + gint height); static void gtk_pizza_adjustment_changed (GtkAdjustment *adjustment, - GtkPizza *pizza); + GtkPizza *pizza); static GdkFilterReturn gtk_pizza_filter (GdkXEvent *gdk_xevent, - GdkEvent *event, - gpointer data); + GdkEvent *event, + gpointer data); static GdkFilterReturn gtk_pizza_main_filter (GdkXEvent *gdk_xevent, - GdkEvent *event, - gpointer data); + GdkEvent *event, + gpointer data); static GtkType gtk_pizza_child_type (GtkContainer *container); -static void gtk_pizza_scroll_set_adjustments (GtkPizza *pizza, +static void gtk_pizza_scroll_set_adjustments (GtkPizza *pizza, GtkAdjustment *hadj, GtkAdjustment *vadj); @@ -200,7 +190,7 @@ gtk_pizza_init (GtkPizza *pizza) pizza->visibility = GDK_VISIBILITY_PARTIAL; pizza->clear_on_draw = TRUE; - pizza->use_filter = FALSE; + pizza->use_filter = TRUE; } GtkWidget* @@ -222,7 +212,7 @@ gtk_pizza_scroll_set_adjustments (GtkPizza *pizza, } void -gtk_pizza_set_shadow_type (GtkPizza *pizza, +gtk_pizza_set_shadow_type (GtkPizza *pizza, GtkMyShadowType type) { g_return_if_fail (pizza != NULL); @@ -241,8 +231,8 @@ gtk_pizza_set_shadow_type (GtkPizza *pizza, } void -gtk_pizza_set_clear (GtkPizza *pizza, - gboolean clear) +gtk_pizza_set_clear (GtkPizza *pizza, + gboolean clear) { g_return_if_fail (pizza != NULL); g_return_if_fail (GTK_IS_PIZZA (pizza)); @@ -251,8 +241,8 @@ gtk_pizza_set_clear (GtkPizza *pizza, } void -gtk_pizza_set_filter (GtkPizza *pizza, - gboolean use) +gtk_pizza_set_filter (GtkPizza *pizza, + gboolean use) { g_return_if_fail (pizza != NULL); g_return_if_fail (GTK_IS_PIZZA (pizza)); @@ -261,12 +251,12 @@ gtk_pizza_set_filter (GtkPizza *pizza, } void -gtk_pizza_put (GtkPizza *pizza, - GtkWidget *widget, - gint x, - gint y, - gint width, - gint height) +gtk_pizza_put (GtkPizza *pizza, + GtkWidget *widget, + gint x, + gint y, + gint width, + gint height) { GtkPizzaChild *child_info; @@ -311,10 +301,10 @@ gtk_pizza_put (GtkPizza *pizza, } void -gtk_pizza_move (GtkPizza *pizza, - GtkWidget *widget, - gint x, - gint y) +gtk_pizza_move (GtkPizza *pizza, + GtkWidget *widget, + gint x, + gint y) { GtkPizzaChild *child; GList *children; @@ -345,10 +335,10 @@ gtk_pizza_move (GtkPizza *pizza, } void -gtk_pizza_resize (GtkPizza *pizza, - GtkWidget *widget, - gint width, - gint height) +gtk_pizza_resize (GtkPizza *pizza, + GtkWidget *widget, + gint width, + gint height) { GtkPizzaChild *child; GList *children; @@ -381,12 +371,12 @@ gtk_pizza_resize (GtkPizza *pizza, } void -gtk_pizza_set_size (GtkPizza *pizza, - GtkWidget *widget, - gint x, - gint y, - gint width, - gint height) +gtk_pizza_set_size (GtkPizza *pizza, + GtkWidget *widget, + gint x, + gint y, + gint width, + gint height) { GtkPizzaChild *child; GList *children; @@ -539,7 +529,7 @@ gtk_pizza_realize (GtkWidget *widget) widget->style = gtk_style_attach (widget->style, widget->window); gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL); - gtk_style_set_background (widget->style, pizza->bin_window, GTK_STATE_NORMAL); + gtk_style_set_background (widget->style, pizza->bin_window, GTK_STATE_NORMAL ); /* add filters for intercepting visibility and expose events */ gdk_window_add_filter (widget->window, gtk_pizza_main_filter, pizza); @@ -579,7 +569,7 @@ gtk_pizza_unrealize (GtkWidget *widget) static void gtk_pizza_size_request (GtkWidget *widget, - GtkRequisition *requisition) + GtkRequisition *requisition) { GtkPizza *pizza; GtkPizzaChild *child; @@ -612,7 +602,7 @@ gtk_pizza_size_request (GtkWidget *widget, static void gtk_pizza_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) + GtkAllocation *allocation) { GtkPizza *pizza; gint border; @@ -660,70 +650,17 @@ gtk_pizza_size_allocate (GtkWidget *widget, static void gtk_pizza_draw (GtkWidget *widget, - GdkRectangle *area) + GdkRectangle *area) { - GtkPizza *pizza; - GtkPizzaChild *child; - GdkRectangle child_area; - GList *children; - - g_return_if_fail (widget != NULL); - g_return_if_fail (GTK_IS_PIZZA (widget)); - - pizza = GTK_PIZZA (widget); - - children = pizza->children; - if ( !(GTK_WIDGET_APP_PAINTABLE (widget)) && - (pizza->clear_on_draw)) - { - gdk_window_clear_area( pizza->bin_window, - area->x, area->y, area->width, area->height); - } - - while (children) - { - child = children->data; - children = children->next; - - if (gtk_widget_intersect (child->widget, area, &child_area)) - gtk_widget_draw (child->widget, &child_area); - } + /* We handle all draws events in window.cpp now. */ + return; } static gint gtk_pizza_expose (GtkWidget *widget, - GdkEventExpose *event) + GdkEventExpose *event) { - GtkPizza *pizza; - GtkPizzaChild *child; - GdkEventExpose child_event; - GList *children; - - g_return_val_if_fail (widget != NULL, FALSE); - g_return_val_if_fail (GTK_IS_PIZZA (widget), FALSE); - g_return_val_if_fail (event != NULL, FALSE); - - pizza = GTK_PIZZA (widget); - - if (event->window != pizza->bin_window) - return FALSE; - - children = pizza->children; - while (children) - { - child = children->data; - children = children->next; - - child_event = *event; - - if (GTK_WIDGET_NO_WINDOW (child->widget) && - GTK_WIDGET_DRAWABLE (child->widget) && - gtk_widget_intersect (child->widget, &event->area, &child_event.area)) - { - gtk_widget_event (child->widget, (GdkEvent*) &child_event); - } - } - + /* We handle all expose events in window.cpp now. */ return FALSE; } @@ -740,7 +677,7 @@ gtk_pizza_add (GtkContainer *container, static void gtk_pizza_remove (GtkContainer *container, - GtkWidget *widget) + GtkWidget *widget) { GtkPizza *pizza; GtkPizzaChild *child; @@ -782,9 +719,9 @@ gtk_pizza_remove (GtkContainer *container, static void gtk_pizza_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data) + gboolean include_internals, + GtkCallback callback, + gpointer callback_data) { GtkPizza *pizza; GtkPizzaChild *child; @@ -812,7 +749,7 @@ gtk_pizza_forall (GtkContainer *container, static void gtk_pizza_position_child (GtkPizza *pizza, - GtkPizzaChild *child) + GtkPizzaChild *child) { gint x; gint y; @@ -844,7 +781,7 @@ gtk_pizza_position_child (GtkPizza *pizza, static void gtk_pizza_allocate_child (GtkPizza *pizza, - GtkPizzaChild *child) + GtkPizzaChild *child) { GtkAllocation allocation; GtkRequisition requisition; @@ -1166,6 +1103,9 @@ gtk_pizza_filter (GdkXEvent *gdk_xevent, pizza = GTK_PIZZA (data); + if (!pizza->use_filter) + return GDK_FILTER_CONTINUE; + switch (xevent->type) { case Expose: @@ -1210,6 +1150,9 @@ gtk_pizza_main_filter (GdkXEvent *gdk_xevent, xevent = (XEvent *)gdk_xevent; pizza = GTK_PIZZA (data); + + if (!pizza->use_filter) + return GDK_FILTER_CONTINUE; if (xevent->type == VisibilityNotify) { diff --git a/src/gtk1/window.cpp b/src/gtk1/window.cpp index 7525485937..06e4797192 100644 --- a/src/gtk1/window.cpp +++ b/src/gtk1/window.cpp @@ -381,10 +381,13 @@ static void draw_frame( GtkWidget *widget, wxWindow *win ) // "expose_event" of m_widget //----------------------------------------------------------------------------- -static void gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win ) +gint gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win ) { - if (gdk_event->count > 0) return; + if (gdk_event->count > 0) return FALSE; + draw_frame( widget, win ); + + return TRUE; } //----------------------------------------------------------------------------- @@ -610,12 +613,18 @@ static long map_to_wx_keysym( KeySym keysym ) // "expose_event" of m_wxwindow //----------------------------------------------------------------------------- -static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExpose *gdk_event, wxWindow *win ) +static int gtk_window_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win ) { DEBUG_MAIN_THREAD + if (g_isIdle) + wxapp_install_idle_handler(); + + if (win->m_queuedFullRedraw) + return TRUE; + /* - if (win->GetName() == wxT("grid window")) + if (win->GetName() == wxT("htmlWindow")) { wxPrintf( wxT("OnExpose from ") ); if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) @@ -634,10 +643,7 @@ static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExp if (gdk_event->count > 0) - return; - - if (!win->m_hasVMT) - return; + return TRUE; wxEraseEvent eevent( win->GetId() ); eevent.SetEventObject( win ); @@ -648,25 +654,85 @@ static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExp win->GetEventHandler()->ProcessEvent( event ); win->GetUpdateRegion().Clear(); + + /* The following code will result in all window-less widgets + being redrawn if the wxWindows class is given a chance to + paint *anything* because it will then be allowed to paint + over the window-less widgets */ + + GtkPizza *pizza = GTK_PIZZA (widget); + + GList *children = pizza->children; + while (children) + { + GtkPizzaChild *child = (GtkPizzaChild*) children->data; + children = children->next; + + GdkEventExpose child_event = *gdk_event; + + if (GTK_WIDGET_NO_WINDOW (child->widget) && + GTK_WIDGET_DRAWABLE (child->widget)) + { + child_event.area.x = child->widget->allocation.x; + child_event.area.y = child->widget->allocation.y; + child_event.area.width = child->widget->allocation.width; + child_event.area.height = child->widget->allocation.height; + gtk_widget_event (child->widget, (GdkEvent*) &child_event); + } + } + + return TRUE; +} + +//----------------------------------------------------------------------------- +// "event" of m_wxwindow +//----------------------------------------------------------------------------- + +/* GTK thinks it is clever and filters out a certain amount of "unneeded" + expose events. We need them, of course, so we override the main event + procedure in GtkWidget by giving our own handler for all system events, + looking for the expose events and then we can always send them. */ + +gint gtk_window_event_event_callback( GtkWidget *widget, GdkEventExpose *event, wxWindow *win ) +{ + if (event->type == GDK_EXPOSE) + { + gint ret = gtk_window_expose_callback( widget, event, win ); + return ret; + } + + + return FALSE; } //----------------------------------------------------------------------------- // "draw" of m_wxwindow //----------------------------------------------------------------------------- -static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget), - GdkRectangle *rect, wxWindow *win ) +/* This callback is a complete replacement of the gtk_pizza_draw() function, + which disabled. */ + +static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxWindow *win ) { DEBUG_MAIN_THREAD if (g_isIdle) wxapp_install_idle_handler(); - if ((rect->x == 0) && (rect->y == 0) && (rect->width <= 1) && (rect->height <= 1)) + if (win->m_queuedFullRedraw) return; + GtkPizza *pizza = GTK_PIZZA (widget); + + if ( !(GTK_WIDGET_APP_PAINTABLE (widget)) && + (pizza->clear_on_draw)) + { + gdk_window_clear_area( pizza->bin_window, + rect->x, rect->y, rect->width, rect->height); + } + /* - if (win->GetName() == wxT("grid window")) + if (win->GetName() == wxT("htmlWindow")) { wxPrintf( wxT("OnDraw from ") ); if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) @@ -677,13 +743,10 @@ static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget), (int)rect->height ); } */ - + win->GetUpdateRegion().Union( rect->x, rect->y, rect->width, rect->height ); - if (!win->m_hasVMT) - return; - wxEraseEvent eevent( win->GetId() ); eevent.SetEventObject( win ); win->GetEventHandler()->ProcessEvent(eevent); @@ -693,6 +756,17 @@ static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget), win->GetEventHandler()->ProcessEvent( event ); win->GetUpdateRegion().Clear(); + + GList *children = pizza->children; + while (children) + { + GtkPizzaChild *child = (GtkPizzaChild*) children->data; + children = children->next; + + GdkRectangle child_area; + if (gtk_widget_intersect (child->widget, rect, &child_area)) + gtk_widget_draw (child->widget, (GdkRectangle*) NULL ); + } } //----------------------------------------------------------------------------- @@ -1974,6 +2048,9 @@ void wxWindow::Init() m_isFrame = FALSE; m_acceptsFocus = FALSE; + m_clipPaintRegion = FALSE; + m_queuedFullRedraw = FALSE; + m_cursor = *wxSTANDARD_CURSOR; #ifdef HAVE_XIM @@ -2008,21 +2085,12 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, } m_insertCallback = wxInsertChildInWindow; - + m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL ); GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); -#ifdef __WXDEBUG__ - debug_focus_in( m_widget, wxT("wxWindow::m_widget"), name ); -#endif - GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(m_widget); -#ifdef __WXDEBUG__ - debug_focus_in( scrolledWindow->hscrollbar, wxT("wxWindow::hsrcollbar"), name ); - debug_focus_in( scrolledWindow->vscrollbar, wxT("wxWindow::vsrcollbar"), name ); -#endif - GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass ); scroll_class->scrollbar_spacing = 0; @@ -2033,10 +2101,6 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, m_wxwindow = gtk_pizza_new(); -#ifdef __WXDEBUG__ - debug_focus_in( m_wxwindow, wxT("wxWindow::m_wxwindow"), name ); -#endif - gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow ); #if (GTK_MINOR_VERSION > 0) @@ -2221,6 +2285,9 @@ void wxWindow::PostCreation() if (!m_noExpose) { /* these get reported to wxWindows -> wxPaintEvent */ + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "event", + GTK_SIGNAL_FUNC(gtk_window_event_event_callback), (gpointer)this ); + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event", GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this ); @@ -2320,6 +2387,24 @@ bool wxWindow::Destroy() void wxWindow::DoMoveWindow(int x, int y, int width, int height) { + if (m_wxwindow && GTK_PIZZA(m_wxwindow)->bin_window) + { + /* Normally, GTK will send expose events only for the regions + which actually got exposed. Sadly, wxMSW invalidates + the whole window so we have to do that, too. We could + simply add a complete refresh, but we would then get + the normal GTK expose events in surplus, so we shut + off the expose events and schedule a full redraw to + be done in OnInternalIdle, where we restore the handling + of expose events. */ + + m_queuedFullRedraw = TRUE; + + GdkEventMask mask = gdk_window_get_events( GTK_PIZZA(m_wxwindow)->bin_window ); + mask = (GdkEventMask)(mask & ~GDK_EXPOSURE_MASK); + gdk_window_set_events( GTK_PIZZA(m_wxwindow)->bin_window, mask ); + } + gtk_pizza_set_size( GTK_PIZZA(m_parent->m_wxwindow), m_widget, x, y, width, height ); } @@ -2330,7 +2415,7 @@ void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags ) if (m_resizing) return; /* I don't like recursions */ m_resizing = TRUE; - + if (m_parent->m_wxwindow == NULL) /* i.e. wxNotebook */ { /* don't set the size for children of wxNotebook, just take the values. */ @@ -2391,6 +2476,12 @@ void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags ) if (m_hasScrolling) { + /* Sometimes the client area changes size without the + whole windows's size changing, but if the whole + windows's size doesn't change, no wxSizeEvent will + normally be sent. Here we add an extra test if + the client test has been changed and this will + be used then. */ GetClientSize( &m_oldClientWidth, &m_oldClientHeight ); } @@ -2461,6 +2552,27 @@ void wxWindow::OnInternalIdle() } UpdateWindowUI(); + + if (m_queuedFullRedraw) + { + /* See also wxWindow::DoMoveWindow for explanation of this code. What + we test here is if the requested size of the window is the same as + the actual size of window, in which case all expose events that resulted + from resizing the window have been sent (and discarded) and we can + now do our full redraw and switch on expose event handling again. */ + + if ((m_width == m_widget->allocation.width) && (m_height == m_widget->allocation.height)) + { + m_queuedFullRedraw = FALSE; + m_updateRegion.Clear(); + m_updateRegion.Union( 0,0,m_width,m_height ); + gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL ); + + GdkEventMask mask = gdk_window_get_events( GTK_PIZZA(m_wxwindow)->bin_window ); + mask = (GdkEventMask)(mask | GDK_EXPOSURE_MASK); + gdk_window_set_events( GTK_PIZZA(m_wxwindow)->bin_window, mask ); + } + } } void wxWindow::DoGetSize( int *width, int *height ) const @@ -2898,37 +3010,65 @@ void wxWindow::Refresh( bool eraseBackground, const wxRect *rect ) { if (m_wxwindow) { + +/* GtkPizza *pizza = GTK_PIZZA(m_wxwindow); gboolean old_clear = pizza->clear_on_draw; gtk_pizza_set_clear( pizza, FALSE ); - gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL ); - gtk_pizza_set_clear( pizza, old_clear ); +*/ + GdkEventExpose gdk_event; + gdk_event.count = 0; + gdk_event.area.x = 0; + gdk_event.area.y = 0; + gdk_event.area.width = m_wxwindow->allocation.width; + gdk_event.area.height = m_wxwindow->allocation.height; + gtk_window_expose_callback( m_wxwindow, &gdk_event, this ); + } else + { gtk_widget_draw( m_widget, (GdkRectangle*) NULL ); + } } else { - GdkRectangle gdk_rect; - gdk_rect.x = rect->x; - gdk_rect.y = rect->y; - gdk_rect.width = rect->width; - gdk_rect.height = rect->height; if (m_wxwindow) { +/* GtkPizza *pizza = GTK_PIZZA(m_wxwindow); gboolean old_clear = pizza->clear_on_draw; gtk_pizza_set_clear( pizza, FALSE ); + GdkRectangle gdk_rect; + gdk_rect.x = rect->x; + gdk_rect.y = rect->y; + gdk_rect.width = rect->width; + gdk_rect.height = rect->height; gtk_widget_draw( m_wxwindow, &gdk_rect ); + gtk_window_draw_callback( m_wxwindow, &gdk_rect, this ); gtk_pizza_set_clear( pizza, old_clear ); +*/ + GdkEventExpose gdk_event; + gdk_event.count = 0; + gdk_event.area.x = rect->x; + gdk_event.area.y = rect->y; + gdk_event.area.width = rect->width; + gdk_event.area.height = rect->height; + gtk_window_expose_callback( m_wxwindow, &gdk_event, this ); } else + { + GdkRectangle gdk_rect; + gdk_rect.x = rect->x; + gdk_rect.y = rect->y; + gdk_rect.width = rect->width; + gdk_rect.height = rect->height; gtk_widget_draw( m_widget, &gdk_rect ); + } } } @@ -3452,7 +3592,9 @@ void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) ) if ((dx == 0) && (dy == 0)) return; + m_clipPaintRegion = TRUE; gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy ); + m_clipPaintRegion = FALSE; /* if (m_children.GetCount() > 0) -- 2.47.2