]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk1/window.cpp
fixed (rare but fatal) bug in wxWindowDisabler
[wxWidgets.git] / src / gtk1 / window.cpp
index 623abc1151d41a5965f0bd5ad38f3170423e87ef..769973db09f18af322b94945c1903f87135f5e61 100644 (file)
@@ -208,9 +208,15 @@ extern bool g_mainThreadLocked;
 // debug
 //-----------------------------------------------------------------------------
 
+#define DISABLE_STYLE_IF_BROKEN_THEME 1
+
 #ifdef __WXDEBUG__
 
-#define DEBUG_MAIN_THREAD if (wxThread::IsMain() && g_mainThreadLocked) printf("gui reentrance");
+#if wxUSE_THREADS
+#   define DEBUG_MAIN_THREAD if (wxThread::IsMain() && g_mainThreadLocked) printf("gui reentrance");
+#else
+#   define DEBUG_MAIN_THREAD
+#endif
 
 static gint gtk_debug_focus_in_callback( GtkWidget *WXUNUSED(widget),
                                          GdkEvent *WXUNUSED(event),
@@ -297,29 +303,35 @@ static void draw_frame( GtkWidget *widget, wxWindow *win )
     int dw = 0;
     int dh = 0;
 
-    if (win->HasScrolling())
+    if (win->m_hasScrolling)
     {
-        GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(widget);
-        GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget)->klass );
+            GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(widget);
 
-/*
-            GtkWidget *hscrollbar = scroll_window->hscrollbar;
-            GtkWidget *vscrollbar = scroll_window->vscrollbar;
+            GtkRequisition vscroll_req;
+            vscroll_req.width = 2;
+            vscroll_req.height = 2;
+            (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window->vscrollbar)->klass )->size_request )
+                (scroll_window->vscrollbar, &vscroll_req );
 
-            we use this instead:  range.slider_width = 11 + 2*2pts edge
-*/
+            GtkRequisition hscroll_req;
+            hscroll_req.width = 2;
+            hscroll_req.height = 2;
+            (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window->hscrollbar)->klass )->size_request )
+                (scroll_window->hscrollbar, &hscroll_req );
 
-        if (scroll_window->vscrollbar_visible)
-        {
-            dw += 15;   /* dw += vscrollbar->allocation.width; */
-            dw += scroll_class->scrollbar_spacing;
-        }
+            GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget)->klass );
 
-        if (scroll_window->hscrollbar_visible)
-        {
-            dh += 15;   /* dh += hscrollbar->allocation.height; */
-            dh += scroll_class->scrollbar_spacing;
-        }
+            if (scroll_window->vscrollbar_visible)
+            {
+                dw += vscroll_req.width;
+                dw += scroll_class->scrollbar_spacing;
+            }
+
+            if (scroll_window->hscrollbar_visible)
+            {
+                dh += hscroll_req.height;
+                dh += scroll_class->scrollbar_spacing;
+            }
     }
 
     int dx = 0;
@@ -369,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;
 }
 
 //-----------------------------------------------------------------------------
@@ -598,79 +613,167 @@ 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 (!win->m_hasVMT)
-        return;
-
-    win->GetUpdateRegion().Union( gdk_event->area.x,
-                                  gdk_event->area.y,
-                                  gdk_event->area.width,
-                                  gdk_event->area.height );
-
+    if (g_isIdle)
+        wxapp_install_idle_handler();
+        
 /*
-    wxPrintf( "OnExpose from " );
-    if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
-        wxPrintf( win->GetClassInfo()->GetClassName() );
-    wxPrintf( " %d %d %d %d\n", (int)gdk_event->area.x,
-                                (int)gdk_event->area.y,
-                                (int)gdk_event->area.width,
-                                (int)gdk_event->area.height );
+    if (win->GetName() == wxT("htmlWindow"))
+    {
+        wxPrintf( wxT("OnExpose from ") );
+        if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+            wxPrintf( win->GetClassInfo()->GetClassName() );
+        wxPrintf( wxT(" %d %d %d %d\n"), (int)gdk_event->area.x,
+                                         (int)gdk_event->area.y,
+                                         (int)gdk_event->area.width,
+                                         (int)gdk_event->area.height );
+    }
 */
+                                
+    if (!win->m_queuedFullRedraw)
+    {
 
-    if (gdk_event->count > 0)
-        return;
+        win->GetUpdateRegion().Union( gdk_event->area.x,
+                                      gdk_event->area.y,
+                                      gdk_event->area.width,
+                                      gdk_event->area.height );
 
-    wxEraseEvent eevent( win->GetId() );
-    eevent.SetEventObject( win );
-    win->GetEventHandler()->ProcessEvent(eevent);
+        if (gdk_event->count == 0)
+        {
+            wxEraseEvent eevent( win->GetId() );
+            eevent.SetEventObject( win );
+            win->GetEventHandler()->ProcessEvent(eevent);
 
-    wxPaintEvent event( win->GetId() );
-    event.SetEventObject( win );
-    win->GetEventHandler()->ProcessEvent( event );
+            wxPaintEvent event( win->GetId() );
+            event.SetEventObject( win );
+            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;
 
-    win->GetUpdateRegion().Clear();
+            if (GTK_WIDGET_NO_WINDOW (child->widget) &&
+                GTK_WIDGET_DRAWABLE (child->widget) /* &&
+                gtk_widget_intersect (child->widget, &gdk_event->area, &child_event.area)*/ )
+            {
+                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.
+   There, we look for expose events ourselves whereas all other events are
+   handled normally. */
+
+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 (!win->m_hasVMT)
-        return;
-
-    win->GetUpdateRegion().Union( rect->x, rect->y,
-                                  rect->width, rect->height );
-
+        
 /*
-    wxPrintf( "OnDraw from " );
-    if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
-        printf( win->GetClassInfo()->GetClassName() );
-    wxPrintf( " %d %d %d %d\n", (int)rect->x,
-                                (int)rect->y,
-                                (int)rect->width,
-                                (int)rect->height );
+    if (win->GetName() == wxT("htmlWindow"))
+    {
+        wxPrintf( wxT("OnDraw from ") );
+        if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+            wxPrintf( win->GetClassInfo()->GetClassName() );
+        wxPrintf( wxT(" %d %d %d %d\n"), (int)rect->x,
+                                         (int)rect->y,
+                                         (int)rect->width,
+                                         (int)rect->height );
+    }
 */
+   
+    GtkPizza *pizza = GTK_PIZZA (widget);
+        
+    if (!win->m_queuedFullRedraw)
+    {
+        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);
+        }
+    
+        win->GetUpdateRegion().Union( rect->x, rect->y, rect->width, rect->height );
+
+        win->m_clipPaintRegion = TRUE;
+    
+        wxEraseEvent eevent( win->GetId() );
+        eevent.SetEventObject( win );
+        win->GetEventHandler()->ProcessEvent(eevent);
 
-    wxEraseEvent eevent( win->GetId() );
-    eevent.SetEventObject( win );
-    win->GetEventHandler()->ProcessEvent(eevent);
+        wxPaintEvent event( win->GetId() );
+        event.SetEventObject( win );
+        win->GetEventHandler()->ProcessEvent( event );
 
-    wxPaintEvent event( win->GetId() );
-    event.SetEventObject( win );
-    win->GetEventHandler()->ProcessEvent( event );
+        win->GetUpdateRegion().Clear();
+    
+        win->m_clipPaintRegion = FALSE;
+    
+    
+        GList *children = pizza->children;
+        while (children)
+        {
+            GtkPizzaChild *child = (GtkPizzaChild*) children->data;
+            children = children->next;
 
-    win->GetUpdateRegion().Clear();
+            GdkRectangle child_area;
+            if (gtk_widget_intersect (child->widget, rect, &child_area))
+            {
+                gtk_widget_draw (child->widget, &child_area /* (GdkRectangle*) NULL*/ );
+            }
+        }
+    }
 }
 
 //-----------------------------------------------------------------------------
@@ -693,7 +796,7 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e
     printf( "KeyDown-Code is: %s.\n", tmp.c_str() );
     printf( "KeyDown-ScanCode is: %d.\n", gdk_event->keyval );
 */
-    
+
     int x = 0;
     int y = 0;
     GdkModifierType state;
@@ -768,13 +871,13 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e
          (win->GetParent()->HasFlag( wxTAB_TRAVERSAL)) )
     {
         wxNavigationKeyEvent new_event;
-        new_event.SetEventObject( win );
+        new_event.SetEventObject( win->GetParent() );
         /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */
         new_event.SetDirection( (gdk_event->keyval == GDK_Tab) );
         /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */
         new_event.SetWindowChange( (gdk_event->state & GDK_CONTROL_MASK) );
         new_event.SetCurrentFocus( win );
-        ret = win->GetEventHandler()->ProcessEvent( new_event );
+        ret = win->GetParent()->GetEventHandler()->ProcessEvent( new_event );
     }
 
     /* generate wxID_CANCEL if <esc> has been pressed (typically in dialogs) */
@@ -885,6 +988,38 @@ static gint gtk_window_key_release_callback( GtkWidget *widget, GdkEventKey *gdk
     return FALSE;
 }
 
+// ----------------------------------------------------------------------------
+// mouse event processing helper
+// ----------------------------------------------------------------------------
+
+static void AdjustEventButtonState(wxMouseEvent& event)
+{
+    // GDK reports the old state of the button for a button press event, but
+    // for compatibility with MSW and common sense we want m_leftDown be TRUE
+    // for a LEFT_DOWN event, not FALSE, so we will invert
+    // left/right/middleDown for the corresponding click events
+    switch ( event.GetEventType() )
+    {
+        case wxEVT_LEFT_DOWN:
+        case wxEVT_LEFT_DCLICK:
+        case wxEVT_LEFT_UP:
+            event.m_leftDown = !event.m_leftDown;
+            break;
+
+        case wxEVT_MIDDLE_DOWN:
+        case wxEVT_MIDDLE_DCLICK:
+        case wxEVT_MIDDLE_UP:
+            event.m_middleDown = !event.m_middleDown;
+            break;
+
+        case wxEVT_RIGHT_DOWN:
+        case wxEVT_RIGHT_DCLICK:
+        case wxEVT_RIGHT_UP:
+            event.m_rightDown = !event.m_rightDown;
+            break;
+    }
+}
+
 //-----------------------------------------------------------------------------
 // "button_press_event"
 //-----------------------------------------------------------------------------
@@ -924,7 +1059,7 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton
         }
     }
 
-    wxEventType event_type = wxEVT_LEFT_DOWN;
+    wxEventType event_type = wxEVT_NULL;
 
     if (gdk_event->button == 1)
     {
@@ -954,6 +1089,12 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton
         }
     }
 
+    if ( event_type == wxEVT_NULL )
+    {
+        // unknown mouse button or click type
+        return FALSE;
+    }
+
     wxMouseEvent event( event_type );
     event.SetTimestamp( gdk_event->time );
     event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK);
@@ -967,6 +1108,8 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton
     event.m_x = (wxCoord)gdk_event->x;
     event.m_y = (wxCoord)gdk_event->y;
 
+    AdjustEventButtonState(event);
+
     // Some control don't have their own X window and thus cannot get
     // any events.
 
@@ -1082,6 +1225,7 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto
         case 1: event_type = wxEVT_LEFT_UP; break;
         case 2: event_type = wxEVT_MIDDLE_UP; break;
         case 3: event_type = wxEVT_RIGHT_UP; break;
+        default: return FALSE;
     }
 
     wxMouseEvent event( event_type );
@@ -1096,6 +1240,8 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto
     event.m_x = (wxCoord)gdk_event->x;
     event.m_y = (wxCoord)gdk_event->y;
 
+    AdjustEventButtonState(event);
+
     // Some control don't have their own X window and thus cannot get
     // any events.
 
@@ -1567,69 +1713,21 @@ static void gtk_window_hscroll_callback( GtkAdjustment *adjust, wxWindow *win )
     win->GetEventHandler()->ProcessEvent( event );
 }
 
-//-----------------------------------------------------------------------------
-// "changed" from m_vAdjust
-//-----------------------------------------------------------------------------
-
-static void gtk_window_vscroll_change_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
-{
-    DEBUG_MAIN_THREAD
-
-    if (g_isIdle)
-        wxapp_install_idle_handler();
-
-    if (g_blockEventsOnDrag) return;
-    if (!win->m_hasVMT) return;
-
-    wxEventType command = wxEVT_SCROLLWIN_THUMBTRACK;
-    int value = (int)(win->m_vAdjust->value+0.5);
-
-    wxScrollWinEvent event( command, value, wxVERTICAL );
-    event.SetEventObject( win );
-    win->GetEventHandler()->ProcessEvent( event );
-}
-
-//-----------------------------------------------------------------------------
-// "changed" from m_hAdjust
-//-----------------------------------------------------------------------------
-
-static void gtk_window_hscroll_change_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
-{
-    DEBUG_MAIN_THREAD
-
-    if (g_isIdle)
-        wxapp_install_idle_handler();
-
-    if (g_blockEventsOnDrag) return;
-    if (!win->m_hasVMT) return;
-
-    wxEventType command = wxEVT_SCROLLWIN_THUMBTRACK;
-    int value = (int)(win->m_hAdjust->value+0.5);
-
-    wxScrollWinEvent event( command, value, wxHORIZONTAL );
-    event.SetEventObject( win );
-    win->GetEventHandler()->ProcessEvent( event );
-}
-
 //-----------------------------------------------------------------------------
 // "button_press_event" from scrollbar
 //-----------------------------------------------------------------------------
 
-static gint gtk_scrollbar_button_press_callback( GtkRange *WXUNUSED(widget),
-                                                 GdkEventButton *WXUNUSED(gdk_event),
-                                                 wxWindow *win )
+static gint gtk_scrollbar_button_press_callback( GtkRange *widget,
+                                                 GdkEventButton *gdk_event,
+                                                 wxWindow *win)
 {
     DEBUG_MAIN_THREAD
 
     if (g_isIdle)
         wxapp_install_idle_handler();
 
-//  don't test here as we can release the mouse while being over
-//  a different window than the slider
-//
-//    if (gdk_event->window != widget->slider) return FALSE;
-
-    win->SetScrolling( TRUE );
+    g_blockEventsOnScroll = TRUE;
+    win->m_isScrolling = (gdk_event->window == widget->slider);
 
     return FALSE;
 }
@@ -1638,19 +1736,43 @@ static gint gtk_scrollbar_button_press_callback( GtkRange *WXUNUSED(widget),
 // "button_release_event" from scrollbar
 //-----------------------------------------------------------------------------
 
-static gint gtk_scrollbar_button_release_callback( GtkRange *WXUNUSED(widget),
+static gint gtk_scrollbar_button_release_callback( GtkRange *widget,
                                                    GdkEventButton *WXUNUSED(gdk_event),
-                                                   wxWindow *win )
+                                                   wxWindow *win)
 {
     DEBUG_MAIN_THREAD
 
-
 //  don't test here as we can release the mouse while being over
 //  a different window than the slider
 //
 //    if (gdk_event->window != widget->slider) return FALSE;
 
-    win->SetScrolling( FALSE );
+    g_blockEventsOnScroll = FALSE;
+
+    if (win->m_isScrolling)
+    {
+        wxEventType command = wxEVT_SCROLL_THUMBRELEASE;
+        int value = -1;
+        int dir = -1;
+
+        GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(win->m_widget);
+        if (widget == GTK_RANGE(scrolledWindow->hscrollbar))
+        {
+            value = (int)(win->m_hAdjust->value+0.5);
+            dir = wxHORIZONTAL;
+        }
+        if (widget == GTK_RANGE(scrolledWindow->vscrollbar))
+        {
+            value = (int)(win->m_vAdjust->value+0.5);
+            dir = wxVERTICAL;
+        }
+
+        wxScrollWinEvent event( command, value, dir );
+        event.SetEventObject( win );
+        win->GetEventHandler()->ProcessEvent( event );
+    }
+
+    win->m_isScrolling = FALSE;
 
     return FALSE;
 }
@@ -1689,7 +1811,7 @@ gtk_window_realized_callback( GtkWidget *WXUNUSED(m_widget), wxWindow *win )
     wxWindowCreateEvent event( win );
     event.SetEventObject( win );
     win->GetEventHandler()->ProcessEvent( event );
-
+    
     return FALSE;
 }
 
@@ -1697,6 +1819,34 @@ gtk_window_realized_callback( GtkWidget *WXUNUSED(m_widget), wxWindow *win )
 // "size_allocate"
 //-----------------------------------------------------------------------------
 
+static
+void gtk_window_size_callback( GtkWidget *WXUNUSED(widget),
+                               GtkAllocation *WXUNUSED(alloc),
+                               wxWindow *win )
+{
+    if (g_isIdle)
+        wxapp_install_idle_handler();
+
+    if (!win->m_hasScrolling) return;
+
+    int client_width = 0;
+    int client_height = 0;
+    win->GetClientSize( &client_width, &client_height );
+    if ((client_width == win->m_oldClientWidth) && (client_height == win->m_oldClientHeight))
+        return;
+
+    win->m_oldClientWidth = client_width;
+    win->m_oldClientHeight = client_height;
+
+    if (!win->m_nativeSizeEvent)
+    {
+        wxSizeEvent event( win->GetSize(), win->GetId() );
+        event.SetEventObject( win );
+        win->GetEventHandler()->ProcessEvent( event );
+    }
+}
+
+
 #ifdef HAVE_XIM
     #define WXUNUSED_UNLESS_XIM(param)  param
 #else
@@ -1706,9 +1856,9 @@ gtk_window_realized_callback( GtkWidget *WXUNUSED(m_widget), wxWindow *win )
 /* Resize XIM window */
 
 static
-void gtk_wxwindow_size_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget),
-                                 GtkAllocation * WXUNUSED_UNLESS_XIM(alloc),
-                                 wxFrame * WXUNUSED_UNLESS_XIM(win) )
+void gtk_wxwindow_size_callback( GtkWidget* WXUNUSED_UNLESS_XIM(widget),
+                                 GtkAllocation* WXUNUSED_UNLESS_XIM(alloc),
+                                 wxWindow* WXUNUSED_UNLESS_XIM(win) )
 {
     if (g_isIdle)
         wxapp_install_idle_handler();
@@ -1749,7 +1899,7 @@ gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget),
 
     win->m_icattr = gdk_ic_attr_new();
     if (!win->m_icattr) return FALSE;
-    
+
     gint width, height;
     GdkEventMask mask;
     GdkColormap *colormap;
@@ -1772,10 +1922,10 @@ gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget),
     if ((colormap = gtk_widget_get_colormap (widget)) !=
            gtk_widget_get_default_colormap ())
     {
-       attrmask |= GDK_IC_PREEDIT_COLORMAP;
-       attr->preedit_colormap = colormap;
+           attrmask |= GDK_IC_PREEDIT_COLORMAP;
+           attr->preedit_colormap = colormap;
     }
-    
+
     attrmask |= GDK_IC_PREEDIT_FOREGROUND;
     attrmask |= GDK_IC_PREEDIT_BACKGROUND;
     attr->preedit_foreground = widget->style->fg[GTK_STATE_NORMAL];
@@ -1803,9 +1953,9 @@ gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget),
 
          break;
     }
-       
+
       win->m_ic = gdk_ic_new (attr, (GdkICAttributesType)attrmask);
-     
+
       if (win->m_ic == NULL)
        g_warning ("Can't create input context.");
       else
@@ -1905,8 +2055,11 @@ void wxWindow::Init()
     m_isFrame = FALSE;
     m_acceptsFocus = FALSE;
 
+    m_clipPaintRegion = FALSE;
+    m_queuedFullRedraw = FALSE;
+
     m_cursor = *wxSTANDARD_CURSOR;
-    
+
 #ifdef HAVE_XIM
     m_ic = (GdkIC*) NULL;
     m_icattr = (GdkICAttr*) NULL;
@@ -1939,21 +2092,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;
 
@@ -1964,10 +2108,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)
@@ -2056,11 +2196,6 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id,
     gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed",
           (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this );
 
-    gtk_signal_connect( GTK_OBJECT(m_hAdjust), "changed",
-          (GtkSignalFunc) gtk_window_hscroll_change_callback, (gpointer) this );
-    gtk_signal_connect(GTK_OBJECT(m_vAdjust), "changed",
-          (GtkSignalFunc) gtk_window_vscroll_change_callback, (gpointer) this );
-
     gtk_widget_show( m_wxwindow );
 
     if (m_parent)
@@ -2095,7 +2230,11 @@ wxWindow::~wxWindow()
 
     if (m_widgetStyle)
     {
-        gtk_style_unref( m_widgetStyle );
+#if DISABLE_STYLE_IF_BROKEN_THEME
+        // don't delete if it's a pixmap theme style
+        if (!m_widgetStyle->engine_data)
+            gtk_style_unref( m_widgetStyle );
+#endif            
         m_widgetStyle = (GtkStyle*) NULL;
     }
 
@@ -2153,6 +2292,12 @@ void wxWindow::PostCreation()
         if (!m_noExpose)
         {
             /* these get reported to wxWindows -> wxPaintEvent */
+            
+            gtk_pizza_set_external( GTK_PIZZA(m_wxwindow), TRUE );
+
+            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 );
 
@@ -2182,7 +2327,7 @@ void wxWindow::PostCreation()
     {
         // For dialogs and frames, we are interested mainly in
        // m_widget's focus.
-       
+
         gtk_signal_connect( GTK_OBJECT(m_widget), "focus_in_event",
             GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this );
 
@@ -2198,18 +2343,22 @@ void wxWindow::PostCreation()
        been realized, so we do this directly after realization */
     gtk_signal_connect( GTK_OBJECT(connect_widget), "realize",
                             GTK_SIGNAL_FUNC(gtk_window_realized_callback), (gpointer) this );
+
     if (m_wxwindow)
     {
-        /* Initialize XIM support.  */
+        /* Catch native resize events. */
+        gtk_signal_connect( GTK_OBJECT(m_wxwindow), "size_allocate",
+                            GTK_SIGNAL_FUNC(gtk_window_size_callback), (gpointer)this );
+
+        /* Initialize XIM support. */
         gtk_signal_connect( GTK_OBJECT(m_wxwindow), "realize",
                             GTK_SIGNAL_FUNC(gtk_wxwindow_realized_callback), (gpointer) this );
-                           
-        /* And resize XIM window.  */
+
+        /* And resize XIM window. */
         gtk_signal_connect( GTK_OBJECT(m_wxwindow), "size_allocate",
                             GTK_SIGNAL_FUNC(gtk_wxwindow_size_callback), (gpointer)this );
     }
-    
+
     m_hasVMT = TRUE;
 }
 
@@ -2248,9 +2397,27 @@ 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 );
 }
-    
+
 void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags )
 {
     wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") );
@@ -2258,7 +2425,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. */
@@ -2317,6 +2484,17 @@ void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags )
                       m_height+border+bottom_border );
     }
 
+    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 );
+    }
+
 /*
     wxPrintf( "OnSize sent from " );
     if (GetClassInfo() && GetClassInfo()->GetClassName())
@@ -2384,6 +2562,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
@@ -2407,24 +2606,6 @@ void wxWindow::DoSetClientSize( int width, int height )
         int dw = 0;
         int dh = 0;
 
-#if (GTK_MINOR_VERSION == 0)
-        if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER))
-        {
-            if (HasScrolling())
-            {
-                GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
-#if 0 // unused - if this is ok, just remove this line (VZ)
-                GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
-#endif // 0
-
-                GtkWidget *viewport = scroll_window->viewport;
-                GtkStyleClass *viewport_class = viewport->style->klass;
-
-                dw += 2 * viewport_class->xthickness;
-                dh += 2 * viewport_class->ythickness;
-            }
-        }
-#else
         if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER))
         {
             /* when using GTK 1.2 we set the shadow border size to 2 */
@@ -2437,32 +2618,37 @@ void wxWindow::DoSetClientSize( int width, int height )
             dw += 1 * 2;
             dh += 1 * 2;
         }
-#endif
 
-        if (HasScrolling())
+        if (m_hasScrolling)
         {
-/*
-            GtkWidget *hscrollbar = scroll_window->hscrollbar;
-            GtkWidget *vscrollbar = scroll_window->vscrollbar;
+            GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
 
-            we use this instead:  range.slider_width = 11 + 2*2pts edge
-*/
+            GtkRequisition vscroll_req;
+            vscroll_req.width = 2;
+            vscroll_req.height = 2;
+            (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window->vscrollbar)->klass )->size_request )
+                (scroll_window->vscrollbar, &vscroll_req );
+
+            GtkRequisition hscroll_req;
+            hscroll_req.width = 2;
+            hscroll_req.height = 2;
+            (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window->hscrollbar)->klass )->size_request )
+                (scroll_window->hscrollbar, &hscroll_req );
 
-            GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
             GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
 
             if (scroll_window->vscrollbar_visible)
             {
-                dw += 15;   /* dw += vscrollbar->allocation.width; */
+                dw += vscroll_req.width;
                 dw += scroll_class->scrollbar_spacing;
             }
 
             if (scroll_window->hscrollbar_visible)
             {
-                dh += 15;   /* dh += hscrollbar->allocation.height; */
+                dh += hscroll_req.height;
                 dh += scroll_class->scrollbar_spacing;
             }
-       }
+        }
 
        SetSize( width+dw, height+dh );
     }
@@ -2482,24 +2668,6 @@ void wxWindow::DoGetClientSize( int *width, int *height ) const
         int dw = 0;
         int dh = 0;
 
-#if (GTK_MINOR_VERSION == 0)
-        if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER))
-        {
-            if (HasScrolling())
-            {
-                GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
-#if 0 // unused - if this is ok, just remove this line (VZ)
-                GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
-#endif // 0
-
-                GtkWidget *viewport = scroll_window->viewport;
-                GtkStyleClass *viewport_class = viewport->style->klass;
-
-                dw += 2 * viewport_class->xthickness;
-                dh += 2 * viewport_class->ythickness;
-            }
-        }
-#else
         if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER))
         {
             /* when using GTK 1.2 we set the shadow border size to 2 */
@@ -2512,28 +2680,34 @@ void wxWindow::DoGetClientSize( int *width, int *height ) const
             dw += 1 * 2;
             dh += 1 * 2;
         }
-#endif
-        if (HasScrolling())
+
+        if (m_hasScrolling)
         {
-/*
-            GtkWidget *hscrollbar = scroll_window->hscrollbar;
-            GtkWidget *vscrollbar = scroll_window->vscrollbar;
+            GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
 
-            we use this instead:  range.slider_width = 11 + 2*2pts edge
-*/
+            GtkRequisition vscroll_req;
+            vscroll_req.width = 2;
+            vscroll_req.height = 2;
+            (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window->vscrollbar)->klass )->size_request )
+                (scroll_window->vscrollbar, &vscroll_req );
+
+            GtkRequisition hscroll_req;
+            hscroll_req.width = 2;
+            hscroll_req.height = 2;
+            (* GTK_WIDGET_CLASS( GTK_OBJECT(scroll_window->hscrollbar)->klass )->size_request )
+                (scroll_window->hscrollbar, &hscroll_req );
 
-            GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
             GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
 
             if (scroll_window->vscrollbar_visible)
             {
-                dw += 15;   /* dw += vscrollbar->allocation.width; */
+                dw += vscroll_req.width;
                 dw += scroll_class->scrollbar_spacing;
             }
 
             if (scroll_window->hscrollbar_visible)
             {
-                dh += 15;   /* dh += hscrollbar->allocation.height; */
+                dh += hscroll_req.height;
                 dh += scroll_class->scrollbar_spacing;
             }
         }
@@ -2697,7 +2871,7 @@ void wxWindow::GetTextExtent( const wxString& string,
 void wxWindow::SetFocus()
 {
     wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
-    
+
     if (m_wxwindow)
     {
         if (!GTK_WIDGET_HAS_FOCUS (m_wxwindow))
@@ -2846,37 +3020,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 );
+        }
     }
 }
 
@@ -2888,7 +3090,7 @@ void wxWindow::Clear()
 
     if (m_wxwindow && m_wxwindow->window)
     {
-        gdk_window_clear( m_wxwindow->window );
+//        gdk_window_clear( m_wxwindow->window );
     }
 }
 
@@ -2930,12 +3132,10 @@ bool wxWindow::SetBackgroundColour( const wxColour &colour )
         // but it couldn't get applied as the
         // widget hasn't been realized yet.
         m_delayedBackgroundColour = TRUE;
-
-        // pretend we have done something
-        return TRUE;
     }
 
     if ((m_wxwindow) &&
+        (m_wxwindow->window) &&
         (m_backgroundColour != wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNFACE)))
     {
         /* wxMSW doesn't clear the window here. I don't do that either to
@@ -2973,9 +3173,6 @@ bool wxWindow::SetForegroundColour( const wxColour &colour )
         // but it couldn't get applied as the
         // widget hasn't been realized yet.
         m_delayedForegroundColour = TRUE;
-
-        // pretend we have done something
-        return TRUE;
     }
 
     ApplyWidgetStyle();
@@ -2985,21 +3182,44 @@ bool wxWindow::SetForegroundColour( const wxColour &colour )
 
 GtkStyle *wxWindow::GetWidgetStyle()
 {
-    if (m_widgetStyle) return m_widgetStyle;
+    if (m_widgetStyle)
+    {
+        GtkStyle *remake = gtk_style_copy( m_widgetStyle );
+        remake->klass = m_widgetStyle->klass;
 
-    GtkStyle *def = gtk_rc_get_style( m_widget );
+        gtk_style_unref( m_widgetStyle );
+        m_widgetStyle = remake;
+    }
+    else
+    {
+        GtkStyle *def = gtk_rc_get_style( m_widget );
 
-    if (!def)
-        def = gtk_widget_get_default_style();
+        if (!def)
+            def = gtk_widget_get_default_style();
 
-    m_widgetStyle = gtk_style_copy( def );
-    m_widgetStyle->klass = def->klass;
+        m_widgetStyle = gtk_style_copy( def );
+        m_widgetStyle->klass = def->klass;
+    }
 
     return m_widgetStyle;
 }
 
 void wxWindow::SetWidgetStyle()
 {
+#if DISABLE_STYLE_IF_BROKEN_THEM
+    if (m_widget->style->engine_data)
+    {
+        static bool s_warningPrinted = FALSE;
+        if (!s_warningPrinted)
+        {
+            printf( "wxWindows warning: Widget styles disabled due to buggy GTK theme.\n" );
+            s_warningPrinted = TRUE;
+        }
+        m_widgetStyle = m_widget->style;
+        return;
+    }
+#endif
+
     GtkStyle *style = GetWidgetStyle();
 
     if (m_font != wxSystemSettings::GetSystemFont( wxSYS_DEFAULT_GUI_FONT ))
@@ -3313,20 +3533,29 @@ void wxWindow::SetScrollPos( int orient, int pos, bool WXUNUSED(refresh) )
         m_vAdjust->value = fpos;
     }
 
-/*
-    if (!m_isScrolling)
+    if (m_wxwindow->window)
     {
-*/
-        if (m_wxwindow->window)
+        if (orient == wxHORIZONTAL)
         {
-            if (orient == wxHORIZONTAL)
-                gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "value_changed" );
-            else
-                gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "value_changed" );
+            gtk_signal_disconnect_by_func( GTK_OBJECT(m_hAdjust),
+                (GtkSignalFunc) gtk_window_hscroll_callback, (gpointer) this );
+
+            gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "value_changed" );
+
+            gtk_signal_connect( GTK_OBJECT(m_hAdjust), "value_changed",
+                (GtkSignalFunc) gtk_window_hscroll_callback, (gpointer) this );
+        }
+        else
+        {
+            gtk_signal_disconnect_by_func( GTK_OBJECT(m_vAdjust),
+                (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this );
+
+            gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "value_changed" );
+
+            gtk_signal_connect( GTK_OBJECT(m_vAdjust), "value_changed",
+                (GtkSignalFunc) gtk_window_vscroll_callback, (gpointer) this );
         }
-/*
     }
-*/
 }
 
 int wxWindow::GetScrollThumb( int orient ) const
@@ -3370,67 +3599,62 @@ void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
     wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
 
     wxCHECK_RET( m_wxwindow != NULL, wxT("window needs client area for scrolling") );
+    
+    if ((dx == 0) && (dy == 0)) return;
 
-/*
-    printf( "ScrollWindow: %d %d\n", dx, dy );
-*/
-
+    m_clipPaintRegion = TRUE;
     gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy );
-
-/*
-    if (!m_scrollGC)
-    {
-        m_scrollGC = gdk_gc_new( m_wxwindow->window );
-        gdk_gc_set_exposures( m_scrollGC, TRUE );
-    }
-
-    wxNode *node = m_children.First();
-    while (node)
-    {
-        wxWindow *child = (wxWindow*) node->Data();
-        int sx = 0;
-        int sy = 0;
-        child->GetSize( &sx, &sy );
-        child->SetSize( child->m_x + dx, child->m_y + dy, sx, sy, wxSIZE_ALLOW_MINUS_ONE );
-        node = node->Next();
-    }
-
-    int cw = 0;
-    int ch = 0;
-    GetClientSize( &cw, &ch );
-    int w = cw - abs(dx);
-    int h = ch - abs(dy);
-
-    if ((h < 0) || (w < 0))
+    m_clipPaintRegion = FALSE;
+    
+/*    
+    if (m_children.GetCount() > 0)
     {
-        Refresh();
+        gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy );
     }
     else
     {
-        int s_x = 0;
-        int s_y = 0;
-        if (dx < 0) s_x = -dx;
-        if (dy < 0) s_y = -dy;
-        int d_x = 0;
-        int d_y = 0;
-        if (dx > 0) d_x = dx;
-        if (dy > 0) d_y = dy;
-
-        gdk_window_copy_area( m_wxwindow->window, m_scrollGC, d_x, d_y,
-            m_wxwindow->window, s_x, s_y, w, h );
+        GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
+    
+        pizza->xoffset -= dx;
+        pizza->yoffset -= dy;
+        
+        GdkGC *m_scrollGC = gdk_gc_new( pizza->bin_window );
+        gdk_gc_set_exposures( m_scrollGC, TRUE );
 
-        wxRect rect;
-        if (dx < 0) rect.x = cw+dx; else rect.x = 0;
-        if (dy < 0) rect.y = ch+dy; else rect.y = 0;
-        if (dy != 0) rect.width = cw; else rect.width = abs(dx);
-        if (dx != 0) rect.height = ch; else rect.height = abs(dy);
+        int cw = 0;
+        int ch = 0;
+        GetClientSize( &cw, &ch );
+        int w = cw - abs(dx);
+        int h = ch - abs(dy);
 
-        Refresh( TRUE, &rect );
+        if ((h < 0) || (w < 0))
+        {
+            Refresh();
+        } 
+        else
+        {
+            int s_x = 0;
+            int s_y = 0;
+            if (dx < 0) s_x = -dx;
+            if (dy < 0) s_y = -dy;
+            int d_x = 0;
+            int d_y = 0;
+            if (dx > 0) d_x = dx;
+            if (dy > 0) d_y = dy;
+
+            gdk_window_copy_area( pizza->bin_window, m_scrollGC, d_x, d_y,
+                pizza->bin_window, s_x, s_y, w, h );
+
+            wxRect rect;
+            if (dx < 0) rect.x = cw+dx; else rect.x = 0;
+            if (dy < 0) rect.y = ch+dy; else rect.y = 0;
+            if (dy != 0) rect.width = cw; else rect.width = abs(dx);
+            if (dx != 0) rect.height = ch; else rect.height = abs(dy);
+
+            Refresh( TRUE, &rect );
+        }
+        
+        gdk_gc_unref( m_scrollGC );
     }
 */
 }
-
-void wxWindow::SetScrolling(bool scroll)
-{
-    m_isScrolling = g_blockEventsOnScroll = scroll;
-}