]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk1/window.cpp
Visualage C++ V4.0 duplicate symbol fixes
[wxWidgets.git] / src / gtk1 / window.cpp
index 6be2cdd8c583ece185db64058568f155212fe62d..c12549013e45d8471db958267e60df16d0aa8cb3 100644 (file)
 #include "wx/settings.h"
 #include "wx/log.h"
 
+#ifdef __WXDEBUG__
+    #include "wx/thread.h"
+#endif
+
 #include <math.h>
 
-#include "gdk/gdk.h"
-#include "gtk/gtk.h"
-#include "gdk/gdkprivate.h"
-#include "gdk/gdkkeysyms.h"
-#include "wx/gtk/win_gtk.h"
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkprivate.h>
+#include <gdk/gdkkeysyms.h>
+#include <wx/gtk/win_gtk.h>
 
-#include "gdk/gdkx.h"
+#include <gdk/gdkx.h>
 
 //-----------------------------------------------------------------------------
 // documentation on internals
@@ -198,12 +202,20 @@ static int        g_sendActivateEvent = -1;
    the last click here */
 static guint32 gs_timeLastClick = 0;
 
+extern bool g_mainThreadLocked;
+
 //-----------------------------------------------------------------------------
 // debug
 //-----------------------------------------------------------------------------
 
 #ifdef __WXDEBUG__
 
+#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),
                                          const wxChar *WXUNUSED(name) )
@@ -240,6 +252,8 @@ void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window
     }
 }
 
+#else
+#define DEBUG_MAIN_THREAD
 #endif // Debug
 
 //-----------------------------------------------------------------------------
@@ -287,29 +301,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);
+            
+            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 );
 
-/*
-            GtkWidget *hscrollbar = scroll_window->hscrollbar;
-            GtkWidget *vscrollbar = scroll_window->vscrollbar;
+            GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget)->klass );
 
-            we use this instead:  range.slider_width = 11 + 2*2pts edge
-*/
-
-        if (scroll_window->vscrollbar_visible)
-        {
-            dw += 15;   /* dw += vscrollbar->allocation.width; */
-            dw += scroll_class->scrollbar_spacing;
-        }
+            if (scroll_window->vscrollbar_visible)
+            {
+                dw += vscroll_req.width;
+                dw += scroll_class->scrollbar_spacing;
+            }
 
-        if (scroll_window->hscrollbar_visible)
-        {
-            dh += 15;   /* dh += hscrollbar->allocation.height; */
-            dh += scroll_class->scrollbar_spacing;
-        }
+            if (scroll_window->hscrollbar_visible)
+            {
+                dh += hscroll_req.height;
+                dh += scroll_class->scrollbar_spacing;
+            }
     }
 
     int dx = 0;
@@ -327,7 +347,7 @@ static void draw_frame( GtkWidget *widget, wxWindow *win )
                          GTK_STATE_NORMAL,
                          GTK_SHADOW_OUT,
                          dx, dy,
-                         win->m_width-dw, win->m_height-dh );
+                         widget->allocation.width-dw, widget->allocation.height-dh );
         return;
     }
 
@@ -338,7 +358,7 @@ static void draw_frame( GtkWidget *widget, wxWindow *win )
                          GTK_STATE_NORMAL,
                          GTK_SHADOW_IN,
                          dx, dy,
-                         win->m_width-dw, win->m_height-dh );
+                         widget->allocation.width-dw, widget->allocation.height-dh );
         return;
     }
 
@@ -349,7 +369,7 @@ static void draw_frame( GtkWidget *widget, wxWindow *win )
         gdk_gc_set_foreground( gc, &widget->style->black );
         gdk_draw_rectangle( widget->window, gc, FALSE,
                          dx, dy,
-                         win->m_width-dw-1, win->m_height-dh-1 );
+                         widget->allocation.width-dw-1, widget->allocation.height-dh-1 );
         gdk_gc_unref( gc );
         return;
     }
@@ -590,6 +610,8 @@ static long map_to_wx_keysym( KeySym keysym )
 
 static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExpose *gdk_event, wxWindow *win )
 {
+    DEBUG_MAIN_THREAD
+
     if (!win->m_hasVMT)
         return;
 
@@ -629,6 +651,8 @@ static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExp
 static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget),
                                       GdkRectangle *rect, wxWindow *win )
 {
+    DEBUG_MAIN_THREAD
+
     if (g_isIdle)
         wxapp_install_idle_handler();
 
@@ -665,6 +689,8 @@ static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget),
 
 static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxWindow *win )
 {
+    DEBUG_MAIN_THREAD
+
     if (g_isIdle)
         wxapp_install_idle_handler();
 
@@ -752,13 +778,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) */
@@ -817,6 +843,8 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e
 
 static gint gtk_window_key_release_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxWindow *win )
 {
+    DEBUG_MAIN_THREAD
+
     if (g_isIdle)
         wxapp_install_idle_handler();
 
@@ -873,6 +901,8 @@ static gint gtk_window_key_release_callback( GtkWidget *widget, GdkEventKey *gdk
 
 static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindow *win )
 {
+    DEBUG_MAIN_THREAD
+
     if (g_isIdle)
         wxapp_install_idle_handler();
 
@@ -1037,6 +1067,8 @@ static gint gtk_window_button_press_callback( GtkWidget *widget, GdkEventButton
 
 static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButton *gdk_event, wxWindow *win )
 {
+    DEBUG_MAIN_THREAD
+
     if (g_isIdle)
         wxapp_install_idle_handler();
 
@@ -1155,6 +1187,8 @@ static gint gtk_window_button_release_callback( GtkWidget *widget, GdkEventButto
 
 static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event, wxWindow *win )
 {
+    DEBUG_MAIN_THREAD
+
     if (g_isIdle)
         wxapp_install_idle_handler();
 
@@ -1275,6 +1309,8 @@ static gint gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion
 
 static gint gtk_window_focus_in_callback( GtkWidget *widget, GdkEvent *WXUNUSED(event), wxWindow *win )
 {
+    DEBUG_MAIN_THREAD
+
     if (g_isIdle)
         wxapp_install_idle_handler();
 
@@ -1335,6 +1371,8 @@ static gint gtk_window_focus_in_callback( GtkWidget *widget, GdkEvent *WXUNUSED(
 
 static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEvent *WXUNUSED(event), wxWindow *win )
 {
+    DEBUG_MAIN_THREAD
+
     if (g_isIdle)
         wxapp_install_idle_handler();
 
@@ -1378,6 +1416,8 @@ static gint gtk_window_focus_out_callback( GtkWidget *widget, GdkEvent *WXUNUSED
 
 static gint gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindow *win )
 {
+    DEBUG_MAIN_THREAD
+
     if (g_isIdle)
         wxapp_install_idle_handler();
 
@@ -1424,6 +1464,8 @@ static gint gtk_window_enter_callback( GtkWidget *widget, GdkEventCrossing *gdk_
 
 static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_event, wxWindow *win )
 {
+    DEBUG_MAIN_THREAD
+
     if (g_isIdle)
         wxapp_install_idle_handler();
 
@@ -1470,6 +1512,8 @@ static gint gtk_window_leave_callback( GtkWidget *widget, GdkEventCrossing *gdk_
 
 static void gtk_window_vscroll_callback( GtkAdjustment *adjust, wxWindow *win )
 {
+    DEBUG_MAIN_THREAD
+
     if (g_isIdle)
         wxapp_install_idle_handler();
 
@@ -1504,6 +1548,8 @@ static void gtk_window_vscroll_callback( GtkAdjustment *adjust, wxWindow *win )
 
 static void gtk_window_hscroll_callback( GtkAdjustment *adjust, wxWindow *win )
 {
+    DEBUG_MAIN_THREAD
+
     if (g_isIdle)
         wxapp_install_idle_handler();
 
@@ -1537,6 +1583,8 @@ static void gtk_window_hscroll_callback( GtkAdjustment *adjust, wxWindow *win )
 
 static void gtk_window_vscroll_change_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
 {
+    DEBUG_MAIN_THREAD
+
     if (g_isIdle)
         wxapp_install_idle_handler();
 
@@ -1557,6 +1605,8 @@ static void gtk_window_vscroll_change_callback( GtkWidget *WXUNUSED(widget), wxW
 
 static void gtk_window_hscroll_change_callback( GtkWidget *WXUNUSED(widget), wxWindow *win )
 {
+    DEBUG_MAIN_THREAD
+
     if (g_isIdle)
         wxapp_install_idle_handler();
 
@@ -1577,8 +1627,10 @@ static void gtk_window_hscroll_change_callback( GtkWidget *WXUNUSED(widget), wxW
 
 static gint gtk_scrollbar_button_press_callback( GtkRange *WXUNUSED(widget),
                                                  GdkEventButton *WXUNUSED(gdk_event),
-                                                 wxWindow *win )
+                                                 wxWindow *win)
 {
+    DEBUG_MAIN_THREAD
+
     if (g_isIdle)
         wxapp_install_idle_handler();
 
@@ -1587,7 +1639,8 @@ static gint gtk_scrollbar_button_press_callback( GtkRange *WXUNUSED(widget),
 //
 //    if (gdk_event->window != widget->slider) return FALSE;
 
-    win->SetScrolling( TRUE );
+    g_blockEventsOnScroll = TRUE;
+    win->m_isScrolling = TRUE;
 
     return FALSE;
 }
@@ -1596,17 +1649,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 );
+    wxASSERT( win->m_isScrolling );
+
+    g_blockEventsOnScroll = FALSE;
+    win->m_isScrolling = FALSE;
+
+    wxEventType command = wxEVT_SCROLLWIN_THUMBTRACK;
+    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.SetScrolling( FALSE );
+    event.SetEventObject( win );
+    win->GetEventHandler()->ProcessEvent( event );
 
     return FALSE;
 }
@@ -1631,12 +1710,11 @@ wxWindow *wxWindowBase::FindFocus()
 static gint
 gtk_window_realized_callback( GtkWidget *WXUNUSED(m_widget), wxWindow *win )
 {
+    DEBUG_MAIN_THREAD
+
     if (g_isIdle)
         wxapp_install_idle_handler();
 
-    if (win->m_delayedFont)
-        win->SetFont( win->GetFont() );
-
     if (win->m_delayedBackgroundColour)
         win->SetBackgroundColour( win->GetBackgroundColour() );
 
@@ -1654,6 +1732,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
@@ -1663,13 +1769,13 @@ 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();
-
+        
 #ifdef HAVE_XIM
     if (!win->m_ic)
         return;
@@ -2158,11 +2264,15 @@ void wxWindow::PostCreation()
  
     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 );
     }
@@ -2274,6 +2384,11 @@ void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags )
                       m_height+border+bottom_border );
     }
 
+    if (m_hasScrolling)
+    {
+        GetClientSize( &m_oldClientWidth, &m_oldClientHeight );
+    }
+
 /*
     wxPrintf( "OnSize sent from " );
     if (GetClassInfo() && GetClassInfo()->GetClassName())
@@ -2364,24 +2479,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 */
@@ -2394,32 +2491,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;
-
-            we use this instead:  range.slider_width = 11 + 2*2pts edge
-*/
-
             GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
+            
+            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 );
+
             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 );
     }
@@ -2439,24 +2541,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 */
@@ -2469,28 +2553,34 @@ void wxWindow::DoGetClientSize( int *width, int *height ) const
             dw += 1 * 2;
             dh += 1 * 2;
         }
-#endif
-        if (HasScrolling())
-        {
-/*
-            GtkWidget *hscrollbar = scroll_window->hscrollbar;
-            GtkWidget *vscrollbar = scroll_window->vscrollbar;
-
-            we use this instead:  range.slider_width = 11 + 2*2pts edge
-*/
 
+        if (m_hasScrolling)
+        {
             GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(m_widget);
+            
+            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 );
+
             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;
             }
         }
@@ -2892,7 +2982,8 @@ bool wxWindow::SetBackgroundColour( const wxColour &colour )
         return TRUE;
     }
 
-    if (m_wxwindow)
+    if ((m_wxwindow) &&
+        (m_backgroundColour != wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNFACE)))
     {
         /* wxMSW doesn't clear the window here. I don't do that either to
           provide compatibility. call Clear() to do the job. */
@@ -2901,17 +2992,7 @@ bool wxWindow::SetBackgroundColour( const wxColour &colour )
         gdk_window_set_background( window, m_backgroundColour.GetColor() );
     }
 
-    wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
-    if (sysbg == m_backgroundColour)
-    {
-        m_backgroundColour = wxNullColour;
-        ApplyWidgetStyle();
-        m_backgroundColour = sysbg;
-    }
-    else
-    {
-        ApplyWidgetStyle();
-    }
+    ApplyWidgetStyle();
 
     return TRUE;
 }
@@ -2944,26 +3025,22 @@ bool wxWindow::SetForegroundColour( const wxColour &colour )
         return TRUE;
     }
 
-    wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
-    if ( sysbg == m_backgroundColour )
-    {
-        m_backgroundColour = wxNullColour;
-        ApplyWidgetStyle();
-        m_backgroundColour = sysbg;
-    }
-    else
-    {
-        ApplyWidgetStyle();
-    }
+    ApplyWidgetStyle();
 
     return TRUE;
 }
 
 GtkStyle *wxWindow::GetWidgetStyle()
 {
-    if (m_widgetStyle) gtk_style_unref( m_widgetStyle );
+    if (m_widgetStyle) return m_widgetStyle;
+
+    GtkStyle *def = gtk_rc_get_style( m_widget );
 
-    m_widgetStyle = gtk_style_copy( gtk_widget_get_style( m_widget ) );
+    if (!def)
+        def = gtk_widget_get_default_style();
+
+    m_widgetStyle = gtk_style_copy( def );
+    m_widgetStyle->klass = def->klass;
 
     return m_widgetStyle;
 }
@@ -2972,28 +3049,37 @@ void wxWindow::SetWidgetStyle()
 {
     GtkStyle *style = GetWidgetStyle();
 
-    gdk_font_unref( style->font );
-    style->font = gdk_font_ref( m_font.GetInternalFont( 1.0 ) );
+    if (m_font != wxSystemSettings::GetSystemFont( wxSYS_DEFAULT_GUI_FONT ))
+    {
+        gdk_font_unref( style->font );
+        style->font = gdk_font_ref( m_font.GetInternalFont( 1.0 ) );
+    }
 
     if (m_foregroundColour.Ok())
     {
         m_foregroundColour.CalcPixel( gtk_widget_get_colormap( m_widget ) );
-        style->fg[GTK_STATE_NORMAL] = *m_foregroundColour.GetColor();
-        style->fg[GTK_STATE_PRELIGHT] = *m_foregroundColour.GetColor();
-        style->fg[GTK_STATE_ACTIVE] = *m_foregroundColour.GetColor();
+        if (m_foregroundColour != wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNTEXT))
+        {
+            style->fg[GTK_STATE_NORMAL] = *m_foregroundColour.GetColor();
+            style->fg[GTK_STATE_PRELIGHT] = *m_foregroundColour.GetColor();
+            style->fg[GTK_STATE_ACTIVE] = *m_foregroundColour.GetColor();
+        }
     }
 
     if (m_backgroundColour.Ok())
     {
         m_backgroundColour.CalcPixel( gtk_widget_get_colormap( m_widget ) );
-        style->bg[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
-        style->base[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
-        style->bg[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor();
-        style->base[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor();
-        style->bg[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor();
-        style->base[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor();
-        style->bg[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor();
-        style->base[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor();
+        if (m_backgroundColour != wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNFACE))
+        {
+            style->bg[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
+            style->base[GTK_STATE_NORMAL] = *m_backgroundColour.GetColor();
+            style->bg[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor();
+            style->base[GTK_STATE_PRELIGHT] = *m_backgroundColour.GetColor();
+            style->bg[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor();
+            style->base[GTK_STATE_ACTIVE] = *m_backgroundColour.GetColor();
+            style->bg[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor();
+            style->base[GTK_STATE_INSENSITIVE] = *m_backgroundColour.GetColor();
+       }
     }
 }
 
@@ -3274,20 +3360,13 @@ 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)
-                gtk_signal_emit_by_name( GTK_OBJECT(m_hAdjust), "value_changed" );
-            else
-                gtk_signal_emit_by_name( GTK_OBJECT(m_vAdjust), "value_changed" );
-        }
-/*
+        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" );
     }
-*/
 }
 
 int wxWindow::GetScrollThumb( int orient ) const
@@ -3390,8 +3469,3 @@ void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
     }
 */
 }
-
-void wxWindow::SetScrolling(bool scroll)
-{
-    m_isScrolling = g_blockEventsOnScroll = scroll;
-}