]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/window.cpp
capture mouse to be notified when it exists the popup rect (bug 1372228)
[wxWidgets.git] / src / gtk / window.cpp
index a10119d5ada06e88e0edecf73d354a3c557217d2..c631f3b014e8dc5e0626a60e35d26254424d79bb 100644 (file)
 #include "wx/window.h"
 
 #ifndef WX_PRECOMP
-    #include "wx/intl.h"
     #include "wx/log.h"
     #include "wx/app.h"
-    #include "wx/utils.h"
     #include "wx/frame.h"
     #include "wx/dcclient.h"
     #include "wx/menu.h"
-    #include "wx/dialog.h"
     #include "wx/settings.h"
     #include "wx/msgdlg.h"
     #include "wx/textctrl.h"
+    #include "wx/radiobut.h"
     #include "wx/toolbar.h"
     #include "wx/combobox.h"
     #include "wx/layout.h"
-    #include "wx/statusbr.h"
     #include "wx/math.h"
-    #include "wx/module.h"
 #endif
 
-#if wxUSE_DRAG_AND_DROP
-    #include "wx/dnd.h"
-#endif
-
-#if wxUSE_TOOLTIPS
-    #include "wx/tooltip.h"
-#endif
-
-#if wxUSE_CARET
-    #include "wx/caret.h"
-#endif // wxUSE_CARET
-
+#include "wx/dnd.h"
+#include "wx/tooltip.h"
+#include "wx/caret.h"
 #include "wx/fontutil.h"
 
 #ifdef __WXDEBUG__
 // FIXME: Due to a hack we use GtkCombo in here, which is deprecated since gtk2.3.0
 #include <gtk/gtkversion.h>
 #if defined(GTK_DISABLE_DEPRECATED) && GTK_CHECK_VERSION(2,3,0)
-#undef GTK_DISABLE_DEPRECATED
+    #undef GTK_DISABLE_DEPRECATED
+    #include <gtk/gtkcombo.h>
+    #define GTK_DISABLE_DEPRECATED
 #endif
 
 #include "wx/gtk/private.h"
-#include <gdk/gdkprivate.h>
+#include "wx/gtk/win_gtk.h"
 #include <gdk/gdkkeysyms.h>
 #include <gdk/gdkx.h>
 
-#include <gtk/gtk.h>
-#include <gtk/gtkprivate.h>
-
-#include "wx/gtk/win_gtk.h"
-
-#include <pango/pangox.h>
-
-#ifdef HAVE_XIM
-    #undef HAVE_XIM
-#endif
-
-extern GtkContainerClass *pizza_parent_class;
-
 //-----------------------------------------------------------------------------
 // documentation on internals
 //-----------------------------------------------------------------------------
@@ -340,14 +316,6 @@ static void draw_frame( GtkWidget *widget, wxWindowGTK *win )
     if (!win->m_hasVMT)
         return;
 
-    int dw = 0;
-    int dh = 0;
-
-    if (win->m_hasScrolling)
-    {
-        GetScrollbarWidth(widget, dw, dh);
-    }
-
     int dx = 0;
     int dy = 0;
     if (GTK_WIDGET_NO_WINDOW (widget))
@@ -356,6 +324,27 @@ static void draw_frame( GtkWidget *widget, wxWindowGTK *win )
         dy += widget->allocation.y;
     }
 
+    int x = dx;
+    int y = dy;
+    
+    int dw = 0;
+    int dh = 0;
+    if (win->m_hasScrolling)
+    {
+        GetScrollbarWidth(widget, dw, dh);
+        
+        if (win->GetLayoutDirection() == wxLayout_RightToLeft)
+        {
+            // This is actually wrong for old GTK+ version
+            // which do not display the scrollbar on the
+            // left side in RTL
+            x += dw;
+        }
+    }
+
+    int w = widget->allocation.width-dw;
+    int h = widget->allocation.height-dh;
+
     if (win->HasFlag(wxRAISED_BORDER))
     {
         gtk_paint_shadow (widget->style,
@@ -363,8 +352,7 @@ static void draw_frame( GtkWidget *widget, wxWindowGTK *win )
                           GTK_STATE_NORMAL,
                           GTK_SHADOW_OUT,
                           NULL, NULL, NULL, // FIXME: No clipping?
-                          dx, dy,
-                          widget->allocation.width-dw, widget->allocation.height-dh );
+                          x, y, w, h );
         return;
     }
 
@@ -375,8 +363,7 @@ static void draw_frame( GtkWidget *widget, wxWindowGTK *win )
                           GTK_STATE_NORMAL,
                           GTK_SHADOW_IN,
                           NULL, NULL, NULL, // FIXME: No clipping?
-                          dx, dy,
-                          widget->allocation.width-dw, widget->allocation.height-dh );
+                          x, y, w, h );
         return;
     }
 
@@ -385,9 +372,7 @@ static void draw_frame( GtkWidget *widget, wxWindowGTK *win )
         GdkGC *gc;
         gc = gdk_gc_new( widget->window );
         gdk_gc_set_foreground( gc, &widget->style->black );
-        gdk_draw_rectangle( widget->window, gc, FALSE,
-                         dx, dy,
-                         widget->allocation.width-dw-1, widget->allocation.height-dh-1 );
+        gdk_draw_rectangle( widget->window, gc, FALSE, x, y, w-1, h-1 );
         g_object_unref (gc);
         return;
     }
@@ -404,13 +389,9 @@ gtk_window_own_expose_callback( GtkWidget *widget,
                                 GdkEventExpose *gdk_event,
                                 wxWindowGTK *win )
 {
-    if (gdk_event->count > 0) return FALSE;
-
-    draw_frame( widget, win );
-
-    (* GTK_WIDGET_CLASS (pizza_parent_class)->expose_event) (widget, gdk_event);
-
-    return TRUE;
+    if (gdk_event->count == 0)
+        draw_frame(widget, win);
+    return false;
 }
 }
 
@@ -457,10 +438,16 @@ void wxgtk_combo_size_request_callback(GtkWidget *widget,
     GtkRequisition entry_req;
     entry_req.width = 2;
     entry_req.height = 2;
-    (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(gcombo->button) )->size_request )
-        (gcombo->button, &entry_req );
+    (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(gcombo->entry) )->size_request )
+        (gcombo->entry, &entry_req );
 
-    requisition->width = w - entry_req.width;
+    GtkRequisition button_req;
+    button_req.width = 2;
+    button_req.height = 2;
+    (* GTK_WIDGET_CLASS( GTK_OBJECT_GET_CLASS(gcombo->button) )->size_request )
+        (gcombo->button, &button_req );
+        
+    requisition->width = w - button_req.width;
     requisition->height = entry_req.height;
 }
 }
@@ -484,7 +471,13 @@ gtk_window_expose_callback( GtkWidget *widget,
     // time anymore.
 
     GtkPizza *pizza = GTK_PIZZA( widget );
-    if (gdk_event->window != pizza->bin_window) return FALSE;
+    if (gdk_event->window != pizza->bin_window)
+    {
+        // block expose events on GTK_WIDGET(pizza)->window,
+        //   all drawing is done on pizza->bin_window
+        return true;
+    }
+
 
 #if 0
     if (win->GetName())
@@ -515,10 +508,7 @@ gtk_window_expose_callback( GtkWidget *widget,
 
     win->GtkSendPaintEvents();
 
-
     // Let parent window draw window-less widgets
-    (* GTK_WIDGET_CLASS (pizza_parent_class)->expose_event) (widget, gdk_event);
-
     return FALSE;
 }
 }
@@ -1282,6 +1272,13 @@ template<typename T> void InitMouseEvent(wxWindowGTK *win,
     wxPoint pt = win->GetClientAreaOrigin();
     event.m_x = (wxCoord)gdk_event->x - pt.x;
     event.m_y = (wxCoord)gdk_event->y - pt.y;
+    
+    if ((win->m_wxwindow) && (win->GetLayoutDirection() == wxLayout_RightToLeft))
+    {
+        // origin in the upper right corner
+        int window_width = gtk_pizza_get_rtl_offset( GTK_PIZZA(win->m_wxwindow) );
+        event.m_x = window_width - event.m_x;
+    }
 
     event.SetEventObject( win );
     event.SetId( win->GetId() );
@@ -1330,8 +1327,8 @@ wxWindowGTK *FindWindowForMouseEvent(wxWindowGTK *win, wxCoord& x, wxCoord& y)
     if (win->m_wxwindow)
     {
         GtkPizza *pizza = GTK_PIZZA(win->m_wxwindow);
-        xx += pizza->xoffset;
-        yy += pizza->yoffset;
+        xx += gtk_pizza_get_xoffset( pizza );
+        yy += gtk_pizza_get_yoffset( pizza );
     }
 
     wxWindowList::compatibility_iterator node = win->GetChildren().GetFirst();
@@ -1473,7 +1470,7 @@ gtk_window_button_press_callback( GtkWidget *widget,
     // GDK sends surplus button down events
     // before a double click event. We
     // need to filter these out.
-    if (gdk_event->type == GDK_BUTTON_PRESS)
+    if ((gdk_event->type == GDK_BUTTON_PRESS) && (win->m_wxwindow))
     {
         GdkEvent *peek_event = gdk_event_peek();
         if (peek_event)
@@ -1819,11 +1816,6 @@ gtk_window_focus_in_callback( GtkWidget *widget,
     wxLogTrace(TRACE_FOCUS,
                _T("%s: focus in"), win->GetName().c_str());
 
-#ifdef HAVE_XIM
-    if (win->m_ic)
-        gdk_im_begin(win->m_ic, win->m_wxwindow->window);
-#endif
-
 #if wxUSE_CARET
     // caret needs to be informed about focus change
     wxCaret *caret = win->GetCaret();
@@ -1880,11 +1872,6 @@ gtk_window_focus_out_callback( GtkWidget *widget,
 
     g_focusWindow = (wxWindowGTK *)NULL;
 
-#ifdef HAVE_XIM
-    if (win->m_ic)
-        gdk_im_end();
-#endif
-
 #if wxUSE_CARET
     // caret needs to be informed about focus change
     wxCaret *caret = win->GetCaret();
@@ -2012,7 +1999,7 @@ gtk_scrollbar_value_changed(GtkRange* range, wxWindow* win)
         wxWindowGTK::ScrollDir dir = win->ScrollDirFromRange(range);
 
         // generate the corresponding wx event
-        const int orient = win->OrientFromScrollDir(dir);
+        const int orient = wxWindow::OrientFromScrollDir(dir);
         wxScrollWinEvent event(eventType, win->GetScrollPos(orient), orient);
         event.SetEventObject(win);
 
@@ -2050,7 +2037,7 @@ gtk_scrollbar_event_after(GtkRange* range, GdkEvent* event, wxWindow* win)
     {
         g_signal_handlers_block_by_func(range, (void*)gtk_scrollbar_event_after, win);
 
-        const int orient = win->OrientFromScrollDir(
+        const int orient = wxWindow::OrientFromScrollDir(
                                         win->ScrollDirFromRange(range));
         wxScrollWinEvent event(wxEVT_SCROLLWIN_THUMBRELEASE, win->GetScrollPos(orient), orient);
         event.SetEventObject(win);
@@ -2115,7 +2102,7 @@ gtk_window_realized_callback( GtkWidget *m_widget, wxWindow *win )
 
 static
 void gtk_window_size_callback( GtkWidget *WXUNUSED(widget),
-                               GtkAllocation *WXUNUSED(alloc),
+                               GtkAllocation *alloc,
                                wxWindow *win )
 {
     if (g_isIdle)
@@ -2127,6 +2114,17 @@ void gtk_window_size_callback( GtkWidget *WXUNUSED(widget),
     if ((client_width == win->m_oldClientWidth) && (client_height == win->m_oldClientHeight))
         return;
 
+#if 0
+        wxPrintf( wxT("size_allocate ") );
+        if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
+            wxPrintf( win->GetClassInfo()->GetClassName() );
+        wxPrintf( wxT(" %d %d %d %d\n"),
+                alloc->x,
+                alloc->y,
+                alloc->width,
+                alloc->height );
+#endif
+                
     win->m_oldClientWidth = client_width;
     win->m_oldClientHeight = client_height;
 
@@ -2138,129 +2136,6 @@ void gtk_window_size_callback( GtkWidget *WXUNUSED(widget),
     }
 }
 
-
-#ifdef HAVE_XIM
-    #define WXUNUSED_UNLESS_XIM(param)  param
-#else
-    #define WXUNUSED_UNLESS_XIM(param)  WXUNUSED(param)
-#endif
-
-/* Resize XIM window */
-static
-void gtk_wxwindow_size_callback( GtkWidget* WXUNUSED_UNLESS_XIM(widget),
-                                 GtkAllocation* WXUNUSED_UNLESS_XIM(alloc),
-                                 wxWindowGTK* WXUNUSED_UNLESS_XIM(win) )
-{
-    if (g_isIdle)
-        wxapp_install_idle_handler();
-
-#ifdef HAVE_XIM
-    if (!win->m_ic)
-        return;
-
-    if  (gdk_ic_get_style (win->m_ic) & GDK_IM_PREEDIT_POSITION)
-    {
-        gint width, height;
-
-        gdk_drawable_get_size (widget->window, &width, &height);
-        win->m_icattr->preedit_area.width = width;
-        win->m_icattr->preedit_area.height = height;
-        gdk_ic_set_attr (win->m_ic, win->m_icattr, GDK_IC_PREEDIT_AREA);
-    }
-#endif // HAVE_XIM
-}
-
-//-----------------------------------------------------------------------------
-// "realize" from m_wxwindow
-//-----------------------------------------------------------------------------
-
-/* Initialize XIM support */
-
-static void
-gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget),
-                                wxWindowGTK * WXUNUSED_UNLESS_XIM(win) )
-{
-    if (g_isIdle)
-        wxapp_install_idle_handler();
-
-#ifdef HAVE_XIM
-    if (win->m_ic) return;
-    if (!widget) return;
-    if (!gdk_im_ready()) return;
-
-    win->m_icattr = gdk_ic_attr_new();
-    if (!win->m_icattr) return;
-
-    gint width, height;
-    GdkEventMask mask;
-    GdkColormap *colormap;
-    GdkICAttr *attr = win->m_icattr;
-    unsigned attrmask = GDK_IC_ALL_REQ;
-    GdkIMStyle style;
-    GdkIMStyle supported_style = (GdkIMStyle)
-                                  (GDK_IM_PREEDIT_NONE |
-                                   GDK_IM_PREEDIT_NOTHING |
-                                   GDK_IM_PREEDIT_POSITION |
-                                   GDK_IM_STATUS_NONE |
-                                   GDK_IM_STATUS_NOTHING);
-
-    if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)
-        supported_style = (GdkIMStyle)(supported_style & ~GDK_IM_PREEDIT_POSITION);
-
-    attr->style = style = gdk_im_decide_style (supported_style);
-    attr->client_window = widget->window;
-
-    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_FOREGROUND;
-    attrmask |= GDK_IC_PREEDIT_BACKGROUND;
-    attr->preedit_foreground = widget->style->fg[GTK_STATE_NORMAL];
-    attr->preedit_background = widget->style->base[GTK_STATE_NORMAL];
-
-    switch (style & GDK_IM_PREEDIT_MASK)
-    {
-        case GDK_IM_PREEDIT_POSITION:
-            if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)
-            {
-                g_warning ("over-the-spot style requires fontset");
-                break;
-            }
-
-            gdk_drawable_get_size (widget->window, &width, &height);
-
-            attrmask |= GDK_IC_PREEDIT_POSITION_REQ;
-            attr->spot_location.x = 0;
-            attr->spot_location.y = height;
-            attr->preedit_area.x = 0;
-            attr->preedit_area.y = 0;
-            attr->preedit_area.width = width;
-            attr->preedit_area.height = height;
-            attr->preedit_fontset = widget->style->font;
-
-            break;
-    }
-
-      win->m_ic = gdk_ic_new (attr, (GdkICAttributesType)attrmask);
-
-      if (win->m_ic == NULL)
-          g_warning ("Can't create input context.");
-      else
-      {
-          mask = gdk_window_get_events (widget->window);
-          mask = (GdkEventMask)(mask | gdk_ic_get_events (win->m_ic));
-          gdk_window_set_events (widget->window, mask);
-
-          if (GTK_WIDGET_HAS_FOCUS(widget))
-              gdk_im_begin (win->m_ic, widget->window);
-      }
-#endif // HAVE_XIM
-}
-
 } // extern "C"
 
 // ----------------------------------------------------------------------------
@@ -2290,8 +2165,8 @@ static void wxInsertChildInWindow( wxWindowGTK* parent, wxWindowGTK* child )
     /* the window might have been scrolled already, do we
        have to adapt the position */
     GtkPizza *pizza = GTK_PIZZA(parent->m_wxwindow);
-    child->m_x += pizza->xoffset;
-    child->m_y += pizza->yoffset;
+    child->m_x += gtk_pizza_get_xoffset( pizza );
+    child->m_y += gtk_pizza_get_yoffset( pizza );
 
     gtk_pizza_put( GTK_PIZZA(parent->m_wxwindow),
                      GTK_WIDGET(child->m_widget),
@@ -2444,32 +2319,30 @@ bool wxWindowGTK::Create( wxWindow *parent,
     GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT_GET_CLASS(m_widget) );
     scroll_class->scrollbar_spacing = 0;
 
-    gtk_scrolled_window_set_policy( scrolledWindow, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
+    if (HasFlag(wxALWAYS_SHOW_SB))
+    {
+        gtk_scrolled_window_set_policy( scrolledWindow, GTK_POLICY_ALWAYS, GTK_POLICY_ALWAYS );
+
+        scrolledWindow->hscrollbar_visible = TRUE;
+        scrolledWindow->vscrollbar_visible = TRUE;
+    } 
+    else
+    {
+        gtk_scrolled_window_set_policy( scrolledWindow, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
+    }
 
     m_scrollBar[ScrollDir_Horz] = GTK_RANGE(scrolledWindow->hscrollbar);
     m_scrollBar[ScrollDir_Vert] = GTK_RANGE(scrolledWindow->vscrollbar);
+    if (GetLayoutDirection() == wxLayout_RightToLeft)
+        gtk_range_set_inverted( m_scrollBar[ScrollDir_Horz], TRUE );
 
     m_wxwindow = gtk_pizza_new();
 
 #ifndef __WXUNIVERSAL__
-    GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
-
-    if (HasFlag(wxRAISED_BORDER))
-    {
-        gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_OUT );
-    }
-    else if (HasFlag(wxSUNKEN_BORDER))
-    {
-        gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_IN );
-    }
-    else if (HasFlag(wxSIMPLE_BORDER))
-    {
-        gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_THIN );
-    }
-    else
-    {
-        gtk_pizza_set_shadow_type( pizza, GTK_MYSHADOW_NONE );
-    }
+    if (HasFlag(wxSIMPLE_BORDER))
+        gtk_container_set_border_width((GtkContainer*)m_wxwindow, 1);
+    else if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER))
+        gtk_container_set_border_width((GtkContainer*)m_wxwindow, 2);
 #endif // __WXUNIVERSAL__
 
     gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow );
@@ -2540,13 +2413,6 @@ wxWindowGTK::~wxWindowGTK()
     if (m_widget)
         Show( false );
 
-#ifdef HAVE_XIM
-    if (m_ic)
-        gdk_ic_destroy (m_ic);
-    if (m_icattr)
-        gdk_ic_attr_destroy (m_icattr);
-#endif
-
     // delete before the widgets to avoid a crash on solaris
     delete m_imData;
 
@@ -2588,12 +2454,11 @@ void wxWindowGTK::PostCreation()
         {
             // these get reported to wxWidgets -> wxPaintEvent
 
-            gtk_pizza_set_external( GTK_PIZZA(m_wxwindow), TRUE );
-
             g_signal_connect (m_wxwindow, "expose_event",
                               G_CALLBACK (gtk_window_expose_callback), this);
 
-            gtk_widget_set_redraw_on_allocate( GTK_WIDGET(m_wxwindow), HasFlag( wxFULL_REPAINT_ON_RESIZE ) );
+            if (GetLayoutDirection() == wxLayout_LeftToRight)
+                gtk_widget_set_redraw_on_allocate( GTK_WIDGET(m_wxwindow), HasFlag( wxFULL_REPAINT_ON_RESIZE ) );
         }
 
         // Create input method handler
@@ -2649,14 +2514,6 @@ void wxWindowGTK::PostCreation()
         // Catch native resize events
         g_signal_connect (m_wxwindow, "size_allocate",
                           G_CALLBACK (gtk_window_size_callback), this);
-
-        // Initialize XIM support
-        g_signal_connect (m_wxwindow, "realize",
-                          G_CALLBACK (gtk_wxwindow_realized_callback), this);
-
-        // And resize XIM window
-        g_signal_connect (m_wxwindow, "size_allocate",
-                          G_CALLBACK (gtk_wxwindow_size_callback), this);
     }
 
     if (GTK_IS_COMBO(m_widget))
@@ -2668,7 +2525,7 @@ void wxWindowGTK::PostCreation()
                           this);
     }
 #ifdef GTK_IS_FILE_CHOOSER_BUTTON
-    else if (GTK_IS_FILE_CHOOSER_BUTTON(m_widget))
+    else if (!gtk_check_version(2,6,0) && GTK_IS_FILE_CHOOSER_BUTTON(m_widget))
     {
         // If we connect to the "size_request" signal of a GtkFileChooserButton
         // then that control won't be sized properly when placed inside sizers
@@ -2690,7 +2547,7 @@ void wxWindowGTK::PostCreation()
     InheritAttributes();
 
     m_hasVMT = true;
-    
+
     SetLayoutDirection(wxLayout_Default);
 
     // unless the window was created initially hidden (i.e. Hide() had been
@@ -2732,7 +2589,9 @@ bool wxWindowGTK::Destroy()
 
 void wxWindowGTK::DoMoveWindow(int x, int y, int width, int height)
 {
+    // inform the parent to perform the move
     gtk_pizza_set_size( GTK_PIZZA(m_parent->m_wxwindow), m_widget, x, y, width, height );
+    
 }
 
 void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags )
@@ -2740,10 +2599,6 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags
     wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") );
     wxASSERT_MSG( (m_parent != NULL), wxT("wxWindowGTK::SetSize requires parent.\n") );
 
-/*
-    printf( "DoSetSize: name %s, x,y,w,h: %d,%d,%d,%d \n", GetName().c_str(), x,y,width,height );
-*/
-
     if (m_resizing) return; /* I don't like recursions */
     m_resizing = true;
 
@@ -2803,13 +2658,13 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags
         GtkPizza *pizza = GTK_PIZZA(m_parent->m_wxwindow);
         if ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0)
         {
-            if (x != -1) m_x = x + pizza->xoffset;
-            if (y != -1) m_y = y + pizza->yoffset;
+            if (x != -1) m_x = x + gtk_pizza_get_xoffset( pizza );
+            if (y != -1) m_y = y + gtk_pizza_get_yoffset( pizza );
         }
         else
         {
-            m_x = x + pizza->xoffset;
-            m_y = y + pizza->yoffset;
+            m_x = x + gtk_pizza_get_xoffset( pizza );
+            m_y = y + gtk_pizza_get_yoffset( pizza );
         }
 
         int left_border = 0;
@@ -2964,20 +2819,9 @@ void wxWindowGTK::DoSetClientSize( int width, int height )
             GetScrollbarWidth(m_widget, dw, dh);
         }
 
-#ifndef __WXUNIVERSAL__
-        if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER))
-        {
-            // shadow border size is 2
-            dw += 2 * 2;
-            dh += 2 * 2;
-        }
-        if (HasFlag(wxSIMPLE_BORDER))
-        {
-            // simple border size is 1
-            dw += 1 * 2;
-            dh += 1 * 2;
-        }
-#endif // __WXUNIVERSAL__
+        const int border = GTK_CONTAINER(m_wxwindow)->border_width;
+        dw += 2 * border;
+        dh += 2 * border;
 
         width += dw;
         height += dh;
@@ -2999,27 +2843,18 @@ void wxWindowGTK::DoGetClientSize( int *width, int *height ) const
         int dh = 0;
 
         if (m_hasScrolling)
-        {
             GetScrollbarWidth(m_widget, dw, dh);
-        }
 
-#ifndef __WXUNIVERSAL__
-        if (HasFlag(wxRAISED_BORDER) || HasFlag(wxSUNKEN_BORDER))
-        {
-            // shadow border size is 2
-            dw += 2 * 2;
-            dh += 2 * 2;
-        }
-        if (HasFlag(wxSIMPLE_BORDER))
-        {
-            // simple border size is 1
-            dw += 1 * 2;
-            dh += 1 * 2;
-        }
-#endif // __WXUNIVERSAL__
+        const int border = GTK_CONTAINER(m_wxwindow)->border_width;
+        dw += 2 * border;
+        dh += 2 * border;
 
         w -= dw;
         h -= dh;
+        if (w < 0)
+            w = 0;
+        if (h < 0)
+            h = 0;
     }
 
     if (width) *width = w;
@@ -3035,8 +2870,30 @@ void wxWindowGTK::DoGetPosition( int *x, int *y ) const
     if (m_parent && m_parent->m_wxwindow)
     {
         GtkPizza *pizza = GTK_PIZZA(m_parent->m_wxwindow);
-        dx = pizza->xoffset;
-        dy = pizza->yoffset;
+        dx = gtk_pizza_get_xoffset( pizza );
+        dy = gtk_pizza_get_yoffset( pizza );
+    }
+
+    if (m_x == -1 && m_y == -1)
+    {
+        GdkWindow *source = (GdkWindow *) NULL;
+        if (m_wxwindow)
+            source = GTK_PIZZA(m_wxwindow)->bin_window;
+        else
+            source = m_widget->window;
+
+        if (source)
+        {
+            int org_x = 0;
+            int org_y = 0;
+            gdk_window_get_origin( source, &org_x, &org_y );
+
+            if (GetParent())
+                GetParent()->ScreenToClient(&org_x, &org_y);
+
+            wx_const_cast(wxWindowGTK*, this)->m_x = org_x;
+            wx_const_cast(wxWindowGTK*, this)->m_y = org_y;
+        }
     }
 
     if (x) (*x) = m_x - dx;
@@ -3068,7 +2925,15 @@ void wxWindowGTK::DoClientToScreen( int *x, int *y ) const
         }
     }
 
-    if (x) *x += org_x;
+
+    if (x)
+    {
+        if (GetLayoutDirection() == wxLayout_RightToLeft)
+            *x = (GetClientSize().x - *x) + org_x;
+        else 
+            *x += org_x;
+    }
+    
     if (y) *y += org_y;
 }
 
@@ -3097,7 +2962,13 @@ void wxWindowGTK::DoScreenToClient( int *x, int *y ) const
         }
     }
 
-    if (x) *x -= org_x;
+    if (x)
+    {
+        if (GetLayoutDirection() == wxLayout_RightToLeft)
+            *x = (GetClientSize().x - *x) - org_x;
+        else 
+            *x -= org_x;
+    }
     if (y) *y -= org_y;
 }
 
@@ -3315,6 +3186,12 @@ void wxWindowGTK::SetFocus()
     {
         if (GTK_IS_CONTAINER(m_widget))
         {
+            if (IsKindOf(CLASSINFO(wxRadioButton)))
+            {
+                gtk_widget_grab_focus (m_widget);
+                return;
+            }
+        
             gtk_widget_child_focus( m_widget, GTK_DIR_TAB_FORWARD );
         }
         else
@@ -3393,7 +3270,7 @@ bool wxWindowGTK::Reparent( wxWindowBase *newParentBase )
 
     /* reverse: prevent GTK from deleting the widget arbitrarily */
     gtk_widget_unref( m_widget );
-    
+
     SetLayoutDirection(wxLayout_Default);
 
     return true;
@@ -3473,6 +3350,18 @@ void wxWindowGTK::SetLayoutDirection(wxLayoutDirection dir)
         return;
 
     GTKSetLayout(m_widget, dir);
+    
+    if (m_wxwindow)
+        GTKSetLayout(m_wxwindow, dir);
+}
+
+wxCoord
+wxWindowGTK::AdjustForLayoutDirection(wxCoord x,
+                                      wxCoord WXUNUSED(width),
+                                      wxCoord WXUNUSED(widthTotal)) const
+{
+    // We now mirrors the coordinates of RTL windows in GtkPizza
+    return x;
 }
 
 void wxWindowGTK::DoMoveInTabOrder(wxWindow *win, MoveKind move)
@@ -3701,13 +3590,16 @@ void wxWindowGTK::Refresh( bool eraseBackground, const wxRect *rect )
             gdk_rect.y = rect->y;
             gdk_rect.width = rect->width;
             gdk_rect.height = rect->height;
+            if (GetLayoutDirection() == wxLayout_RightToLeft)
+                gdk_rect.x = GetClientSize().x - gdk_rect.x - gdk_rect.width;
+
             p = &gdk_rect;
         }
         else // invalidate everything
         {
             p = NULL;
         }
-
+        
         gdk_window_invalidate_rect( GTK_PIZZA(m_wxwindow)->bin_window, p, TRUE );
     }
 }
@@ -3741,6 +3633,20 @@ void wxWindowGTK::GtkUpdate()
     }
 }
 
+bool wxWindowGTK::DoIsExposed( int x, int y ) const
+{
+    return m_updateRegion.Contains(x, y) != wxOutRegion;
+}
+
+
+bool wxWindowGTK::DoIsExposed( int x, int y, int w, int h ) const
+{
+    if (GetLayoutDirection() == wxLayout_RightToLeft)
+        return m_updateRegion.Contains(x-w, y, w, h) != wxOutRegion;
+    else
+        return m_updateRegion.Contains(x, y, w, h) != wxOutRegion;
+}
+
 void wxWindowGTK::GtkSendPaintEvents()
 {
     if (!m_wxwindow)
@@ -3752,6 +3658,33 @@ void wxWindowGTK::GtkSendPaintEvents()
     // Clip to paint region in wxClientDC
     m_clipPaintRegion = true;
 
+    m_nativeUpdateRegion = m_updateRegion;
+
+    if (GetLayoutDirection() == wxLayout_RightToLeft)
+    {
+        // Transform m_updateRegion under RTL
+        m_updateRegion.Clear();
+        
+        gint width;
+        gdk_window_get_geometry( GTK_PIZZA(m_wxwindow)->bin_window,
+                                 NULL, NULL, &width, NULL, NULL );
+        
+        wxRegionIterator upd( m_nativeUpdateRegion );
+        while (upd)
+        {
+            wxRect rect;
+            rect.x = upd.GetX();
+            rect.y = upd.GetY();
+            rect.width = upd.GetWidth();
+            rect.height = upd.GetHeight();
+            
+            rect.x = width - rect.x - rect.width;
+            m_updateRegion.Union( rect );
+            
+            ++upd;
+        }
+    }
+    
     // widget to draw on
     GtkPizza *pizza = GTK_PIZZA (m_wxwindow);
 
@@ -3764,7 +3697,7 @@ void wxWindowGTK::GtkSendPaintEvents()
 
         if (GTK_WIDGET_MAPPED(parent->m_widget))
         {
-            wxRegionIterator upd( m_updateRegion );
+            wxRegionIterator upd( m_nativeUpdateRegion );
             while (upd)
             {
                 GdkRectangle rect;
@@ -3787,7 +3720,6 @@ void wxWindowGTK::GtkSendPaintEvents()
         }
     }
     else
-
     {
         wxWindowDC dc( (wxWindow*)this );
         dc.SetClippingRegion( m_updateRegion );
@@ -3809,6 +3741,7 @@ void wxWindowGTK::GtkSendPaintEvents()
     m_clipPaintRegion = false;
 
     m_updateRegion.Clear();
+    m_nativeUpdateRegion.Clear();
 }
 
 void wxWindowGTK::SetDoubleBuffered( bool on )
@@ -3819,6 +3752,11 @@ void wxWindowGTK::SetDoubleBuffered( bool on )
         gtk_widget_set_double_buffered( m_wxwindow, on );
 }
 
+bool wxWindowGTK::IsDoubleBuffered() const
+{
+    return GTK_WIDGET_DOUBLE_BUFFERED( m_wxwindow );
+}
+
 void wxWindowGTK::ClearBackground()
 {
     wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
@@ -3835,8 +3773,15 @@ void wxWindowGTK::DoSetToolTip( wxToolTip *tip )
 
 void wxWindowGTK::ApplyToolTip( GtkTooltips *tips, const wxChar *tip )
 {
-    wxString tmp( tip );
-    gtk_tooltips_set_tip( tips, GetConnectWidget(), wxGTK_CONV(tmp), (gchar*) NULL );
+    if (tip)
+    {
+        wxString tmp( tip );
+        gtk_tooltips_set_tip( tips, GetConnectWidget(), wxGTK_CONV(tmp), (gchar*) NULL );
+    }
+    else
+    {
+        gtk_tooltips_set_tip( tips, GetConnectWidget(), NULL, NULL);
+    }
 }
 #endif // wxUSE_TOOLTIPS
 
@@ -4182,8 +4127,8 @@ void wxWindowGTK::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh))
             pos = max;
         if (pos < 0)
             pos = 0;
-        m_scrollPos[dir] =
-        adj->value = pos;
+        m_scrollPos[dir] = adj->value = pos;
+        
         // If a "value_changed" signal emission is not already in progress
         if (!m_blockValueChanged[dir])
         {
@@ -4236,7 +4181,9 @@ wxEventType wxWindowGTK::GetScrollEventType(GtkRange* range)
 
     const int barIndex = range == m_scrollBar[1];
     GtkAdjustment* adj = range->adjustment;
+    
     const int value = int(adj->value + 0.5);
+    
     // save previous position
     const double oldPos = m_scrollPos[barIndex];
     // update current position
@@ -4282,9 +4229,32 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
 
     m_clipPaintRegion = true;
 
-    gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy );
+    if (GetLayoutDirection() == wxLayout_RightToLeft)
+        gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), dx, -dy );
+    else
+        gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy );
 
     m_clipPaintRegion = false;
+
+    bool restoreCaret = (GetCaret() != NULL && GetCaret()->IsVisible());
+    if (restoreCaret)
+    {
+        wxRect caretRect(GetCaret()->GetPosition(), GetCaret()->GetSize());
+        if (dx > 0)
+            caretRect.width += dx;
+        else
+       {
+            caretRect.x += dx; caretRect.width -= dx;
+       }
+        if (dy > 0)
+            caretRect.height += dy;
+        else
+       {
+            caretRect.y += dy; caretRect.height -= dy;
+       }
+     
+        RefreshRect(caretRect);
+    }
 }
 
 void wxWindowGTK::GtkScrolledWindowSetBorder(GtkWidget* w, int wxstyle)