]> git.saurik.com Git - wxWidgets.git/blobdiff - src/gtk/window.cpp
move addition of -lX11 to better place
[wxWidgets.git] / src / gtk / window.cpp
index 759ebc9afe77e9ac6e06937059bbaa3beca5915c..ed6255467389e9201bec58cadabdcb635356c4bf 100644 (file)
 
 #include "wx/gtk/private.h"
 #include "wx/gtk/private/win_gtk.h"
 
 #include "wx/gtk/private.h"
 #include "wx/gtk/private/win_gtk.h"
-#include <gdk/gdkkeysyms.h>
+
 #include <gdk/gdkx.h>
 
 #include <gdk/gdkx.h>
 
+#include <gdk/gdkkeysyms.h>
+#if GTK_CHECK_VERSION(3,0,0)
+#include <gdk/gdkkeysyms-compat.h>
+#endif
+
 #if !GTK_CHECK_VERSION(2,10,0)
     // GTK+ can reliably detect Meta key state only since 2.10 when
     // GDK_META_MASK was introduced -- there wasn't any way to detect it
 #if !GTK_CHECK_VERSION(2,10,0)
     // GTK+ can reliably detect Meta key state only since 2.10 when
     // GDK_META_MASK was introduced -- there wasn't any way to detect it
 
    Cursors, too, have been a constant source of pleasure. The main difficulty
    is that a GdkWindow inherits a cursor if the programmer sets a new cursor
 
    Cursors, too, have been a constant source of pleasure. The main difficulty
    is that a GdkWindow inherits a cursor if the programmer sets a new cursor
-   for the parent. To prevent this from doing too much harm, I use idle time
-   to set the cursor over and over again, starting from the toplevel windows
-   and ending with the youngest generation (speaking of parent and child windows).
+   for the parent. To prevent this from doing too much harm, SetCursor calls
+   GTKUpdateCursor, which will recursively re-set the cursors of all child windows.
    Also don't forget that cursors (like much else) are connected to GdkWindows,
    not GtkWidgets and that the "window" field of a GtkWidget might very well
    point to the GdkWindow of the parent widget (-> "window-less widget") and
    that the two obviously have very different meanings.
    Also don't forget that cursors (like much else) are connected to GdkWindows,
    not GtkWidgets and that the "window" field of a GtkWidget might very well
    point to the GdkWindow of the parent widget (-> "window-less widget") and
    that the two obviously have very different meanings.
-
 */
 
 //-----------------------------------------------------------------------------
 */
 
 //-----------------------------------------------------------------------------
@@ -281,11 +284,11 @@ wxgtk_window_size_request_callback(GtkWidget * WXUNUSED(widget),
 
 extern "C" {
 static gboolean
 
 extern "C" {
 static gboolean
-gtk_window_expose_callback( GtkWidget* widget,
+gtk_window_expose_callback( GtkWidget*,
                             GdkEventExpose *gdk_event,
                             wxWindow *win )
 {
                             GdkEventExpose *gdk_event,
                             wxWindow *win )
 {
-    if (gdk_event->window == widget->window)
+    if (gdk_event->window == win->GTKGetDrawingWindow())
     {
         win->GetUpdateRegion() = wxRegion( gdk_event->region );
         win->GtkSendPaintEvents();
     {
         win->GetUpdateRegion() = wxRegion( gdk_event->region );
         win->GtkSendPaintEvents();
@@ -304,10 +307,14 @@ extern "C" {
 static gboolean
 expose_event_border(GtkWidget* widget, GdkEventExpose* gdk_event, wxWindow* win)
 {
 static gboolean
 expose_event_border(GtkWidget* widget, GdkEventExpose* gdk_event, wxWindow* win)
 {
-    if (gdk_event->window != widget->window)
+    if (gdk_event->window != gtk_widget_get_parent_window(win->m_wxwindow))
         return false;
 
         return false;
 
-    const GtkAllocation& alloc = win->m_wxwindow->allocation;
+    if (!win->IsShown())
+        return false;
+
+    GtkAllocation alloc;
+    gtk_widget_get_allocation(win->m_wxwindow, &alloc);
     const int x = alloc.x;
     const int y = alloc.y;
     const int w = alloc.width;
     const int x = alloc.x;
     const int y = alloc.y;
     const int w = alloc.width;
@@ -319,7 +326,7 @@ expose_event_border(GtkWidget* widget, GdkEventExpose* gdk_event, wxWindow* win)
     if (win->HasFlag(wxBORDER_SIMPLE))
     {
         gdk_draw_rectangle(gdk_event->window,
     if (win->HasFlag(wxBORDER_SIMPLE))
     {
         gdk_draw_rectangle(gdk_event->window,
-            widget->style->black_gc, false, x, y, w - 1, h - 1);
+            gtk_widget_get_style(widget)->black_gc, false, x, y, w - 1, h - 1);
     }
     else
     {
     }
     else
     {
@@ -336,9 +343,12 @@ expose_event_border(GtkWidget* widget, GdkEventExpose* gdk_event, wxWindow* win)
             // for scrollable ones
             detail = "viewport";
 
             // for scrollable ones
             detail = "viewport";
 
+        // clip rect is required to avoid painting background
+        // over upper left (w,h) of parent window
+        GdkRectangle clipRect = { x, y, w, h };
         gtk_paint_shadow(
         gtk_paint_shadow(
-           win->m_wxwindow->style, gdk_event->window, GTK_STATE_NORMAL,
-           shadow, NULL, wxGTKPrivate::GetEntryWidget(), detail, x, y, w, h);
+           gtk_widget_get_style(win->m_wxwindow), gdk_event->window, GTK_STATE_NORMAL,
+           shadow, &clipRect, wxGTKPrivate::GetEntryWidget(), detail, x, y, w, h);
     }
     return false;
 }
     }
     return false;
 }
@@ -357,9 +367,10 @@ parent_set(GtkWidget* widget, GtkObject* old_parent, wxWindow* win)
         g_signal_handlers_disconnect_by_func(
             old_parent, (void*)expose_event_border, win);
     }
         g_signal_handlers_disconnect_by_func(
             old_parent, (void*)expose_event_border, win);
     }
-    if (widget->parent)
+    GtkWidget* parent = gtk_widget_get_parent(widget);
+    if (parent)
     {
     {
-        g_signal_connect_after(widget->parent, "expose_event",
+        g_signal_connect_after(parent, "expose_event",
             G_CALLBACK(expose_event_border), win);
     }
 }
             G_CALLBACK(expose_event_border), win);
     }
 }
@@ -671,27 +682,61 @@ static void wxFillOtherKeyEventFields(wxKeyEvent& event,
                                       wxWindowGTK *win,
                                       GdkEventKey *gdk_event)
 {
                                       wxWindowGTK *win,
                                       GdkEventKey *gdk_event)
 {
-    int x = 0;
-    int y = 0;
-    GdkModifierType state;
-    if (gdk_event->window)
-        gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
-
     event.SetTimestamp( gdk_event->time );
     event.SetId(win->GetId());
     event.SetTimestamp( gdk_event->time );
     event.SetId(win->GetId());
+
     event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK) != 0;
     event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK) != 0;
     event.m_altDown = (gdk_event->state & GDK_MOD1_MASK) != 0;
     event.m_metaDown = (gdk_event->state & GDK_META_MASK) != 0;
     event.m_shiftDown = (gdk_event->state & GDK_SHIFT_MASK) != 0;
     event.m_controlDown = (gdk_event->state & GDK_CONTROL_MASK) != 0;
     event.m_altDown = (gdk_event->state & GDK_MOD1_MASK) != 0;
     event.m_metaDown = (gdk_event->state & GDK_META_MASK) != 0;
+
+    // Normally we take the state of modifiers directly from the low level GDK
+    // event but unfortunately GDK uses a different convention from MSW for the
+    // key events corresponding to the modifier keys themselves: in it, when
+    // e.g. Shift key is pressed, GDK_SHIFT_MASK is not set while it is set
+    // when Shift is released. Under MSW the situation is exactly reversed and
+    // the modifier corresponding to the key is set when it is pressed and
+    // unset when it is released. To ensure consistent behaviour between
+    // platforms (and because it seems to make slightly more sense, although
+    // arguably both behaviours are reasonable) we follow MSW here.
+    //
+    // Final notice: we set the flags to the desired value instead of just
+    // inverting them because they are not set correctly (i.e. in the same way
+    // as for the real events generated by the user) for wxUIActionSimulator-
+    // produced events and it seems better to keep that class code the same
+    // among all platforms and fix the discrepancy here instead of adding
+    // wxGTK-specific code to wxUIActionSimulator.
+    const bool isPress = gdk_event->type == GDK_KEY_PRESS;
+    switch ( gdk_event->keyval )
+    {
+        case GDK_Shift_L:
+        case GDK_Shift_R:
+            event.m_shiftDown = isPress;
+            break;
+
+        case GDK_Control_L:
+        case GDK_Control_R:
+            event.m_controlDown = isPress;
+            break;
+
+        case GDK_Alt_L:
+        case GDK_Alt_R:
+            event.m_altDown = isPress;
+            break;
+
+        case GDK_Meta_L:
+        case GDK_Meta_R:
+        case GDK_Super_L:
+        case GDK_Super_R:
+            event.m_metaDown = isPress;
+            break;
+    }
+
     event.m_rawCode = (wxUint32) gdk_event->keyval;
     event.m_rawCode = (wxUint32) gdk_event->keyval;
-    event.m_rawFlags = 0;
-#if wxUSE_UNICODE
-    event.m_uniChar = gdk_keyval_to_unicode(gdk_event->keyval);
-#endif
-    wxGetMousePosition( &x, &y );
-    win->ScreenToClient( &x, &y );
-    event.m_x = x;
-    event.m_y = y;
+    event.m_rawFlags = gdk_event->hardware_keycode;
+
+    wxGetMousePosition(&event.m_x, &event.m_y);
+    win->ScreenToClient(&event.m_x, &event.m_y);
     event.SetEventObject( win );
 }
 
     event.SetEventObject( win );
 }
 
@@ -790,16 +835,21 @@ wxTranslateGTKKeyEventToWx(wxKeyEvent& event,
     if ( !key_code )
         return false;
 
     if ( !key_code )
         return false;
 
-    // now fill all the other fields
-    wxFillOtherKeyEventFields(event, win, gdk_event);
-
     event.m_keyCode = key_code;
     event.m_keyCode = key_code;
+
 #if wxUSE_UNICODE
 #if wxUSE_UNICODE
-    if ( gdk_event->type == GDK_KEY_PRESS ||  gdk_event->type == GDK_KEY_RELEASE )
+    event.m_uniChar = gdk_keyval_to_unicode(key_code ? key_code : keysym);
+    if ( !event.m_uniChar && event.m_keyCode <= WXK_DELETE )
     {
     {
-        event.m_uniChar = key_code;
+        // Set Unicode key code to the ASCII equivalent for compatibility. E.g.
+        // let RETURN generate the key event with both key and Unicode key
+        // codes of 13.
+        event.m_uniChar = event.m_keyCode;
     }
     }
-#endif
+#endif // wxUSE_UNICODE
+
+    // now fill all the other fields
+    wxFillOtherKeyEventFields(event, win, gdk_event);
 
     return true;
 }
 
     return true;
 }
@@ -821,6 +871,41 @@ struct wxGtkIMData
     }
 };
 
     }
 };
 
+namespace
+{
+
+// Send wxEVT_CHAR_HOOK event to the parent of the window and if it wasn't
+// processed, send wxEVT_CHAR to the window itself. Return true if either of
+// them was handled.
+bool
+SendCharHookAndCharEvents(const wxKeyEvent& event, wxWindow *win)
+{
+    // wxEVT_CHAR_HOOK must be sent to the top level parent window to allow it
+    // to handle key events in all of its children unless the mouse is captured
+    // in which case we consider that the keyboard should be "captured" too.
+    if ( !g_captureWindow )
+    {
+        wxWindow * const parent = wxGetTopLevelParent(win);
+        if ( parent )
+        {
+            // We need to make a copy of the event object because it is
+            // modified while it's handled, notably its WasProcessed() flag
+            // is set after it had been processed once.
+            wxKeyEvent eventCharHook(event);
+            eventCharHook.SetEventType(wxEVT_CHAR_HOOK);
+            if ( parent->HandleWindowEvent(eventCharHook) )
+                return true;
+        }
+    }
+
+    // As above, make a copy of the event first.
+    wxKeyEvent eventChar(event);
+    eventChar.SetEventType(wxEVT_CHAR);
+    return win->HandleWindowEvent(eventChar);
+}
+
+} // anonymous namespace
+
 extern "C" {
 static gboolean
 gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget),
 extern "C" {
 static gboolean
 gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget),
@@ -848,8 +933,10 @@ gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget),
         return_after_IM = true;
     }
 
         return_after_IM = true;
     }
 
-    if ((!ret) && (win->m_imData != NULL))
+    if (!ret && win->m_imData)
     {
     {
+        win->m_imData->lastKeyEvent = gdk_event;
+
         // We should let GTK+ IM filter key event first. According to GTK+ 2.0 API
         // docs, if IM filter returns true, no further processing should be done.
         // we should send the key_down event anyway.
         // We should let GTK+ IM filter key event first. According to GTK+ 2.0 API
         // docs, if IM filter returns true, no further processing should be done.
         // we should send the key_down event anyway.
@@ -937,21 +1024,7 @@ gtk_window_key_press_callback( GtkWidget *WXUNUSED(widget),
 #endif
             }
 
 #endif
             }
 
-            // Implement OnCharHook by checking ancestor top level windows
-            wxWindow *parent = win;
-            while (parent && !parent->IsTopLevel())
-                parent = parent->GetParent();
-            if (parent)
-            {
-                event.SetEventType( wxEVT_CHAR_HOOK );
-                ret = parent->HandleWindowEvent( event );
-            }
-
-            if (!ret)
-            {
-                event.SetEventType(wxEVT_CHAR);
-                ret = win->HandleWindowEvent( event );
-            }
+            ret = SendCharHookAndCharEvents(event, win);
         }
     }
 
         }
     }
 
@@ -983,13 +1056,6 @@ gtk_wxwindow_commit_cb (GtkIMContext * WXUNUSED(context),
     if( data.empty() )
         return;
 
     if( data.empty() )
         return;
 
-    bool ret = false;
-
-    // Implement OnCharHook by checking ancestor top level windows
-    wxWindow *parent = window;
-    while (parent && !parent->IsTopLevel())
-        parent = parent->GetParent();
-
     for( wxString::const_iterator pstr = data.begin(); pstr != data.end(); ++pstr )
     {
 #if wxUSE_UNICODE
     for( wxString::const_iterator pstr = data.begin(); pstr != data.end(); ++pstr )
     {
 #if wxUSE_UNICODE
@@ -1017,17 +1083,7 @@ gtk_wxwindow_commit_cb (GtkIMContext * WXUNUSED(context),
 #endif
         }
 
 #endif
         }
 
-        if (parent)
-        {
-            event.SetEventType( wxEVT_CHAR_HOOK );
-            ret = parent->HandleWindowEvent( event );
-        }
-
-        if (!ret)
-        {
-            event.SetEventType(wxEVT_CHAR);
-            ret = window->HandleWindowEvent( event );
-        }
+        SendCharHookAndCharEvents(event, window);
     }
 }
 }
     }
 }
 }
@@ -1081,6 +1137,10 @@ template<typename T> void InitMouseEvent(wxWindowGTK *win,
     event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK) != 0;
     event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK) != 0;
     event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK) != 0;
     event.m_leftDown = (gdk_event->state & GDK_BUTTON1_MASK) != 0;
     event.m_middleDown = (gdk_event->state & GDK_BUTTON2_MASK) != 0;
     event.m_rightDown = (gdk_event->state & GDK_BUTTON3_MASK) != 0;
+
+    // In gdk/win32 VK_XBUTTON1 is translated to GDK_BUTTON4_MASK
+    // and VK_XBUTTON2 to GDK_BUTTON5_MASK. In x11/gdk buttons 4/5
+    // are wheel rotation and buttons 8/9 don't change the state.
     event.m_aux1Down = (gdk_event->state & GDK_BUTTON4_MASK) != 0;
     event.m_aux2Down = (gdk_event->state & GDK_BUTTON5_MASK) != 0;
 
     event.m_aux1Down = (gdk_event->state & GDK_BUTTON4_MASK) != 0;
     event.m_aux2Down = (gdk_event->state & GDK_BUTTON5_MASK) != 0;
 
@@ -1091,7 +1151,9 @@ template<typename T> void InitMouseEvent(wxWindowGTK *win,
     if ((win->m_wxwindow) && (win->GetLayoutDirection() == wxLayout_RightToLeft))
     {
         // origin in the upper right corner
     if ((win->m_wxwindow) && (win->GetLayoutDirection() == wxLayout_RightToLeft))
     {
         // origin in the upper right corner
-        int window_width = win->m_wxwindow->allocation.width;
+        GtkAllocation a;
+        gtk_widget_get_allocation(win->m_wxwindow, &a);
+        int window_width = a.width;
         event.m_x = window_width - event.m_x;
     }
 
         event.m_x = window_width - event.m_x;
     }
 
@@ -1130,6 +1192,20 @@ static void AdjustEventButtonState(wxMouseEvent& event)
         event.m_rightDown = !event.m_rightDown;
         return;
     }
         event.m_rightDown = !event.m_rightDown;
         return;
     }
+
+    if ((event.GetEventType() == wxEVT_AUX1_DOWN) ||
+        (event.GetEventType() == wxEVT_AUX1_DCLICK))
+    {
+        event.m_aux1Down = true;
+        return;
+    }
+
+    if ((event.GetEventType() == wxEVT_AUX2_DOWN) ||
+        (event.GetEventType() == wxEVT_AUX2_DCLICK))
+    {
+        event.m_aux2Down = true;
+        return;
+    }
 }
 
 // find the window to send the mouse event too
 }
 
 // find the window to send the mouse event too
@@ -1359,6 +1435,42 @@ gtk_window_button_press_callback( GtkWidget *widget,
         }
     }
 
         }
     }
 
+    else if (gdk_event->button == 8)
+    {
+        switch (gdk_event->type)
+        {
+            case GDK_3BUTTON_PRESS:
+            case GDK_BUTTON_PRESS:
+                event_type = wxEVT_AUX1_DOWN;
+                break;
+
+            case GDK_2BUTTON_PRESS:
+                event_type = wxEVT_AUX1_DCLICK;
+                break;
+
+            default:
+                ;
+        }
+    }
+
+    else if (gdk_event->button == 9)
+    {
+        switch (gdk_event->type)
+        {
+            case GDK_3BUTTON_PRESS:
+            case GDK_BUTTON_PRESS:
+                event_type = wxEVT_AUX2_DOWN;
+                break;
+
+            case GDK_2BUTTON_PRESS:
+                event_type = wxEVT_AUX2_DCLICK;
+                break;
+
+            default:
+                ;
+        }
+    }
+
     if ( event_type == wxEVT_NULL )
     {
         // unknown mouse button or click type
     if ( event_type == wxEVT_NULL )
     {
         // unknown mouse button or click type
@@ -1442,6 +1554,14 @@ gtk_window_button_release_callback( GtkWidget *WXUNUSED(widget),
             event_type = wxEVT_RIGHT_UP;
             break;
 
             event_type = wxEVT_RIGHT_UP;
             break;
 
+        case 8:
+            event_type = wxEVT_AUX1_UP;
+            break;
+
+        case 9:
+            event_type = wxEVT_AUX2_UP;
+            break;
+
         default:
             // unknown button, don't process
             return FALSE;
         default:
             // unknown button, don't process
             return FALSE;
@@ -1553,22 +1673,16 @@ window_scroll_event_hscrollbar(GtkWidget*, GdkEventScroll* gdk_event, wxWindow*
         return false;
     }
 
         return false;
     }
 
-    wxMouseEvent event(wxEVT_MOUSEWHEEL);
-    InitMouseEvent(win, event, gdk_event);
-
     GtkRange *range = win->m_scrollBar[wxWindow::ScrollDir_Horz];
     GtkRange *range = win->m_scrollBar[wxWindow::ScrollDir_Horz];
-    if (!range) return FALSE;
 
 
-    if (range && GTK_WIDGET_VISIBLE (range))
+    if (range && gtk_widget_get_visible(GTK_WIDGET(range)))
     {
     {
-        GtkAdjustment *adj = range->adjustment;
-        gdouble delta = adj->step_increment * 3;
+        GtkAdjustment* adj = gtk_range_get_adjustment(range);
+        double delta = gtk_adjustment_get_step_increment(adj) * 3;
         if (gdk_event->direction == GDK_SCROLL_LEFT)
             delta = -delta;
 
         if (gdk_event->direction == GDK_SCROLL_LEFT)
             delta = -delta;
 
-        gdouble new_value = CLAMP (adj->value + delta, adj->lower, adj->upper - adj->page_size);
-
-        gtk_adjustment_set_value (adj, new_value);
+        gtk_range_set_value(range, gtk_adjustment_get_value(adj) + delta);
 
         return TRUE;
     }
 
         return TRUE;
     }
@@ -1600,18 +1714,15 @@ window_scroll_event(GtkWidget*, GdkEventScroll* gdk_event, wxWindow* win)
       return TRUE;
 
     GtkRange *range = win->m_scrollBar[wxWindow::ScrollDir_Vert];
       return TRUE;
 
     GtkRange *range = win->m_scrollBar[wxWindow::ScrollDir_Vert];
-    if (!range) return FALSE;
 
 
-    if (range && GTK_WIDGET_VISIBLE (range))
+    if (range && gtk_widget_get_visible(GTK_WIDGET(range)))
     {
     {
-        GtkAdjustment *adj = range->adjustment;
-        gdouble delta = adj->step_increment * 3;
+        GtkAdjustment* adj = gtk_range_get_adjustment(range);
+        double delta = gtk_adjustment_get_step_increment(adj) * 3;
         if (gdk_event->direction == GDK_SCROLL_UP)
         if (gdk_event->direction == GDK_SCROLL_UP)
-          delta = -delta;
-
-        gdouble new_value = CLAMP (adj->value + delta, adj->lower, adj->upper - adj->page_size);
+            delta = -delta;
 
 
-        gtk_adjustment_set_value (adj, new_value);
+        gtk_range_set_value(range, gtk_adjustment_get_value(adj) + delta);
 
         return TRUE;
     }
 
         return TRUE;
     }
@@ -1694,7 +1805,7 @@ gtk_window_enter_callback( GtkWidget *widget,
     int y = 0;
     GdkModifierType state = (GdkModifierType)0;
 
     int y = 0;
     GdkModifierType state = (GdkModifierType)0;
 
-    gdk_window_get_pointer( widget->window, &x, &y, &state );
+    gdk_window_get_pointer(gtk_widget_get_window(widget), &x, &y, &state);
 
     wxMouseEvent event( wxEVT_ENTER_WINDOW );
     InitMouseEvent(win, event, gdk_event);
 
     wxMouseEvent event( wxEVT_ENTER_WINDOW );
     InitMouseEvent(win, event, gdk_event);
@@ -1734,7 +1845,7 @@ gtk_window_leave_callback( GtkWidget *widget,
     int y = 0;
     GdkModifierType state = (GdkModifierType)0;
 
     int y = 0;
     GdkModifierType state = (GdkModifierType)0;
 
-    gdk_window_get_pointer( widget->window, &x, &y, &state );
+    gdk_window_get_pointer(gtk_widget_get_window(widget), &x, &y, &state);
 
     InitMouseEvent(win, event, gdk_event);
 
 
     InitMouseEvent(win, event, gdk_event);
 
@@ -1831,7 +1942,7 @@ gtk_window_realized_callback(GtkWidget* widget, wxWindow* win)
     if (win->m_imData)
     {
         gtk_im_context_set_client_window( win->m_imData->context,
     if (win->m_imData)
     {
         gtk_im_context_set_client_window( win->m_imData->context,
-                                          widget->window);
+            win->m_wxwindow ? win->GTKGetDrawingWindow() : gtk_widget_get_window(widget));
     }
 
     // We cannot set colours and fonts before the widget
     }
 
     // We cannot set colours and fonts before the widget
@@ -1847,6 +1958,8 @@ gtk_window_realized_callback(GtkWidget* widget, wxWindow* win)
     wxWindowCreateEvent event( win );
     event.SetEventObject( win );
     win->GTKProcessEvent( event );
     wxWindowCreateEvent event( win );
     event.SetEventObject( win );
     win->GTKProcessEvent( event );
+
+    win->GTKUpdateCursor(true, false);
 }
 
 //-----------------------------------------------------------------------------
 }
 
 //-----------------------------------------------------------------------------
@@ -1873,8 +1986,10 @@ size_allocate(GtkWidget*, GtkAllocation* alloc, wxWindow* win)
         win->m_oldClientHeight = h;
         // this callback can be connected to m_wxwindow,
         // so always get size from m_widget->allocation
         win->m_oldClientHeight = h;
         // this callback can be connected to m_wxwindow,
         // so always get size from m_widget->allocation
-        win->m_width  = win->m_widget->allocation.width;
-        win->m_height = win->m_widget->allocation.height;
+        GtkAllocation a;
+        gtk_widget_get_allocation(win->m_widget, &a);
+        win->m_width  = a.width;
+        win->m_height = a.height;
         if (!win->m_nativeSizeEvent)
         {
             wxSizeEvent event(win->GetSize(), win->GetId());
         if (!win->m_nativeSizeEvent)
         {
             wxSizeEvent event(win->GetSize(), win->GetId());
@@ -1949,8 +2064,7 @@ void wxWindowGTK::AddChildGTK(wxWindowGTK* child)
 
     gtk_widget_set_size_request(
         child->m_widget, child->m_width, child->m_height);
 
     gtk_widget_set_size_request(
         child->m_widget, child->m_width, child->m_height);
-    gtk_fixed_put(
-        GTK_FIXED(m_wxwindow), child->m_widget, child->m_x, child->m_y);
+    pizza->put(child->m_widget, child->m_x, child->m_y);
 }
 
 //-----------------------------------------------------------------------------
 }
 
 //-----------------------------------------------------------------------------
@@ -1978,6 +2092,7 @@ wxMouseState wxGetMouseState()
     ms.SetLeftDown((mask & GDK_BUTTON1_MASK) != 0);
     ms.SetMiddleDown((mask & GDK_BUTTON2_MASK) != 0);
     ms.SetRightDown((mask & GDK_BUTTON3_MASK) != 0);
     ms.SetLeftDown((mask & GDK_BUTTON1_MASK) != 0);
     ms.SetMiddleDown((mask & GDK_BUTTON2_MASK) != 0);
     ms.SetRightDown((mask & GDK_BUTTON3_MASK) != 0);
+    // see the comment in InitMouseEvent()
     ms.SetAux1Down((mask & GDK_BUTTON4_MASK) != 0);
     ms.SetAux2Down((mask & GDK_BUTTON5_MASK) != 0);
 
     ms.SetAux1Down((mask & GDK_BUTTON4_MASK) != 0);
     ms.SetAux2Down((mask & GDK_BUTTON5_MASK) != 0);
 
@@ -1997,9 +2112,7 @@ wxMouseState wxGetMouseState()
 // method
 #ifdef __WXUNIVERSAL__
     IMPLEMENT_ABSTRACT_CLASS(wxWindowGTK, wxWindowBase)
 // method
 #ifdef __WXUNIVERSAL__
     IMPLEMENT_ABSTRACT_CLASS(wxWindowGTK, wxWindowBase)
-#else // __WXGTK__
-    IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
-#endif // __WXUNIVERSAL__/__WXGTK__
+#endif // __WXUNIVERSAL__
 
 void wxWindowGTK::Init()
 {
 
 void wxWindowGTK::Init()
 {
@@ -2124,17 +2237,14 @@ bool wxWindowGTK::Create( wxWindow *parent,
         if (HasFlag(wxALWAYS_SHOW_SB))
         {
             gtk_scrolled_window_set_policy( scrolledWindow, GTK_POLICY_ALWAYS, GTK_POLICY_ALWAYS );
         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 );
         }
 
         }
         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);
+        m_scrollBar[ScrollDir_Horz] = GTK_RANGE(gtk_scrolled_window_get_hscrollbar(scrolledWindow));
+        m_scrollBar[ScrollDir_Vert] = GTK_RANGE(gtk_scrolled_window_get_vscrollbar(scrolledWindow));
         if (GetLayoutDirection() == wxLayout_RightToLeft)
             gtk_range_set_inverted( m_scrollBar[ScrollDir_Horz], TRUE );
 
         if (GetLayoutDirection() == wxLayout_RightToLeft)
             gtk_range_set_inverted( m_scrollBar[ScrollDir_Horz], TRUE );
 
@@ -2211,6 +2321,12 @@ wxWindowGTK::~wxWindowGTK()
     // delete before the widgets to avoid a crash on solaris
     delete m_imData;
 
     // delete before the widgets to avoid a crash on solaris
     delete m_imData;
 
+    // avoid problem with GTK+ 2.18 where a frozen window causes the whole
+    // TLW to be frozen, and if the window is then destroyed, nothing ever
+    // gets painted again
+    if (IsFrozen())
+        DoThaw();
+
     if (m_widget)
     {
         // Note that gtk_widget_destroy() does not destroy the widget, it just
     if (m_widget)
     {
         // Note that gtk_widget_destroy() does not destroy the widget, it just
@@ -2399,8 +2515,6 @@ void wxWindowGTK::ConnectWidget( GtkWidget *widget )
 
 bool wxWindowGTK::Destroy()
 {
 
 bool wxWindowGTK::Destroy()
 {
-    wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") );
-
     m_hasVMT = false;
 
     return wxWindowBase::Destroy();
     m_hasVMT = false;
 
     return wxWindowBase::Destroy();
@@ -2475,7 +2589,7 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags
         int bottom_border = 0;
 
         /* the default button has a border around it */
         int bottom_border = 0;
 
         /* the default button has a border around it */
-        if (GTK_WIDGET_CAN_DEFAULT(m_widget))
+        if (gtk_widget_get_can_default(m_widget))
         {
             GtkBorder *default_border = NULL;
             gtk_widget_style_get( m_widget, "default_border", &default_border, NULL );
         {
             GtkBorder *default_border = NULL;
             gtk_widget_style_get( m_widget, "default_border", &default_border, NULL );
@@ -2519,7 +2633,7 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags
 
 bool wxWindowGTK::GTKShowFromOnIdle()
 {
 
 bool wxWindowGTK::GTKShowFromOnIdle()
 {
-    if (IsShown() && m_showOnIdle && !GTK_WIDGET_VISIBLE (m_widget))
+    if (IsShown() && m_showOnIdle && !gtk_widget_get_visible (m_widget))
     {
         GtkAllocation alloc;
         alloc.x = m_x;
     {
         GtkAllocation alloc;
         alloc.x = m_x;
@@ -2560,40 +2674,7 @@ void wxWindowGTK::OnInternalIdle()
         m_needsStyleChange = false;
     }
 
         m_needsStyleChange = false;
     }
 
-    wxCursor cursor = m_cursor;
-    if (g_globalCursor.Ok()) cursor = g_globalCursor;
-
-    if (cursor.Ok())
-    {
-        /* I now set the cursor anew in every OnInternalIdle call
-           as setting the cursor in a parent window also effects the
-           windows above so that checking for the current cursor is
-           not possible. */
-
-        if (m_wxwindow && (m_wxwindow != m_widget))
-        {
-            GdkWindow *window = m_wxwindow->window;
-            if (window)
-                gdk_window_set_cursor( window, cursor.GetCursor() );
-
-            if (!g_globalCursor.Ok())
-                cursor = *wxSTANDARD_CURSOR;
-
-            window = m_widget->window;
-            if ((window) && !(GTK_WIDGET_NO_WINDOW(m_widget)))
-                gdk_window_set_cursor( window, cursor.GetCursor() );
-
-        }
-        else if ( m_widget )
-        {
-            GdkWindow *window = m_widget->window;
-            if ( window && !GTK_WIDGET_NO_WINDOW(m_widget) )
-               gdk_window_set_cursor( window, cursor.GetCursor() );
-        }
-    }
-
-    if (wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen())
-        UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
+    wxWindowBase::OnInternalIdle();
 }
 
 void wxWindowGTK::DoGetSize( int *width, int *height ) const
 }
 
 void wxWindowGTK::DoGetSize( int *width, int *height ) const
@@ -2651,7 +2732,7 @@ void wxWindowGTK::DoGetClientSize( int *width, int *height ) const
                     case GTK_POLICY_AUTOMATIC:
                         // may be shown or not, check
                         GtkAdjustment *adj = gtk_range_get_adjustment(range);
                     case GTK_POLICY_AUTOMATIC:
                         // may be shown or not, check
                         GtkAdjustment *adj = gtk_range_get_adjustment(range);
-                        if ( adj->upper <= adj->page_size )
+                        if (gtk_adjustment_get_upper(adj) <= gtk_adjustment_get_page_size(adj))
                             continue;
                 }
 
                             continue;
                 }
 
@@ -2667,10 +2748,9 @@ void wxWindowGTK::DoGetClientSize( int *width, int *height ) const
             }
         }
 
             }
         }
 
-        int border_x, border_y;
-        WX_PIZZA(m_wxwindow)->get_border_widths(border_x, border_y);
-        w -= 2 * border_x;
-        h -= 2 * border_y;
+        const wxSize sizeBorders = DoGetBorderSize();
+        w -= sizeBorders.x;
+        h -= sizeBorders.y;
 
         if (w < 0)
             w = 0;
 
         if (w < 0)
             w = 0;
@@ -2682,6 +2762,17 @@ void wxWindowGTK::DoGetClientSize( int *width, int *height ) const
     if (height) *height = h;
 }
 
     if (height) *height = h;
 }
 
+wxSize wxWindowGTK::DoGetBorderSize() const
+{
+    if ( !m_wxwindow )
+        return wxWindowBase::DoGetBorderSize();
+
+    int x, y;
+    WX_PIZZA(m_wxwindow)->get_border_widths(x, y);
+
+    return 2*wxSize(x, y);
+}
+
 void wxWindowGTK::DoGetPosition( int *x, int *y ) const
 {
     wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
 void wxWindowGTK::DoGetPosition( int *x, int *y ) const
 {
     wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
@@ -2699,9 +2790,9 @@ void wxWindowGTK::DoGetPosition( int *x, int *y ) const
     {
         GdkWindow *source = NULL;
         if (m_wxwindow)
     {
         GdkWindow *source = NULL;
         if (m_wxwindow)
-            source = m_wxwindow->window;
+            source = gtk_widget_get_window(m_wxwindow);
         else
         else
-            source = m_widget->window;
+            source = gtk_widget_get_window(m_widget);
 
         if (source)
         {
 
         if (source)
         {
@@ -2725,13 +2816,13 @@ void wxWindowGTK::DoClientToScreen( int *x, int *y ) const
 {
     wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
 
 {
     wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
 
-    if (!m_widget->window) return;
+    if (gtk_widget_get_window(m_widget) == NULL) return;
 
     GdkWindow *source = NULL;
     if (m_wxwindow)
 
     GdkWindow *source = NULL;
     if (m_wxwindow)
-        source = m_wxwindow->window;
+        source = gtk_widget_get_window(m_wxwindow);
     else
     else
-        source = m_widget->window;
+        source = gtk_widget_get_window(m_widget);
 
     int org_x = 0;
     int org_y = 0;
 
     int org_x = 0;
     int org_y = 0;
@@ -2739,10 +2830,12 @@ void wxWindowGTK::DoClientToScreen( int *x, int *y ) const
 
     if (!m_wxwindow)
     {
 
     if (!m_wxwindow)
     {
-        if (GTK_WIDGET_NO_WINDOW (m_widget))
+        if (!gtk_widget_get_has_window(m_widget))
         {
         {
-            org_x += m_widget->allocation.x;
-            org_y += m_widget->allocation.y;
+            GtkAllocation a;
+            gtk_widget_get_allocation(m_widget, &a);
+            org_x += a.x;
+            org_y += a.y;
         }
     }
 
         }
     }
 
@@ -2762,13 +2855,13 @@ void wxWindowGTK::DoScreenToClient( int *x, int *y ) const
 {
     wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
 
 {
     wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
 
-    if (!m_widget->window) return;
+    if (!gtk_widget_get_realized(m_widget)) return;
 
     GdkWindow *source = NULL;
     if (m_wxwindow)
 
     GdkWindow *source = NULL;
     if (m_wxwindow)
-        source = m_wxwindow->window;
+        source = gtk_widget_get_window(m_wxwindow);
     else
     else
-        source = m_widget->window;
+        source = gtk_widget_get_window(m_widget);
 
     int org_x = 0;
     int org_y = 0;
 
     int org_x = 0;
     int org_y = 0;
@@ -2776,10 +2869,12 @@ void wxWindowGTK::DoScreenToClient( int *x, int *y ) const
 
     if (!m_wxwindow)
     {
 
     if (!m_wxwindow)
     {
-        if (GTK_WIDGET_NO_WINDOW (m_widget))
+        if (!gtk_widget_get_has_window(m_widget))
         {
         {
-            org_x += m_widget->allocation.x;
-            org_y += m_widget->allocation.y;
+            GtkAllocation a;
+            gtk_widget_get_allocation(m_widget, &a);
+            org_x += a.x;
+            org_y += a.y;
         }
     }
 
         }
     }
 
@@ -2846,7 +2941,7 @@ int wxWindowGTK::GetCharHeight() const
     wxCHECK_MSG( (m_widget != NULL), 12, wxT("invalid window") );
 
     wxFont font = GetFont();
     wxCHECK_MSG( (m_widget != NULL), 12, wxT("invalid window") );
 
     wxFont font = GetFont();
-    wxCHECK_MSG( font.Ok(), 12, wxT("invalid font") );
+    wxCHECK_MSG( font.IsOk(), 12, wxT("invalid font") );
 
     PangoContext* context = gtk_widget_get_pango_context(m_widget);
 
 
     PangoContext* context = gtk_widget_get_pango_context(m_widget);
 
@@ -2872,7 +2967,7 @@ int wxWindowGTK::GetCharWidth() const
     wxCHECK_MSG( (m_widget != NULL), 8, wxT("invalid window") );
 
     wxFont font = GetFont();
     wxCHECK_MSG( (m_widget != NULL), 8, wxT("invalid window") );
 
     wxFont font = GetFont();
-    wxCHECK_MSG( font.Ok(), 8, wxT("invalid font") );
+    wxCHECK_MSG( font.IsOk(), 8, wxT("invalid font") );
 
     PangoContext* context = gtk_widget_get_pango_context(m_widget);
 
 
     PangoContext* context = gtk_widget_get_pango_context(m_widget);
 
@@ -2902,7 +2997,7 @@ void wxWindowGTK::DoGetTextExtent( const wxString& string,
 {
     wxFont fontToUse = theFont ? *theFont : GetFont();
 
 {
     wxFont fontToUse = theFont ? *theFont : GetFont();
 
-    wxCHECK_RET( fontToUse.Ok(), wxT("invalid font") );
+    wxCHECK_RET( fontToUse.IsOk(), wxT("invalid font") );
 
     if (string.empty())
     {
 
     if (string.empty())
     {
@@ -3121,7 +3216,7 @@ void wxWindowGTK::SetFocus()
     // within its toplevel", i.e. returns true for one widget per TLW, not
     // globally) returns true immediately after grabbing focus,
     // GTK_WIDGET_HAS_FOCUS (which returns true only for the one widget that
     // within its toplevel", i.e. returns true for one widget per TLW, not
     // globally) returns true immediately after grabbing focus,
     // GTK_WIDGET_HAS_FOCUS (which returns true only for the one widget that
-    // has focus at the moment) takes affect only after the window is shown
+    // has focus at the moment) takes effect only after the window is shown
     // (if it was hidden at the moment of the call) or at the next event loop
     // iteration.
     //
     // (if it was hidden at the moment of the call) or at the next event loop
     // iteration.
     //
@@ -3133,7 +3228,7 @@ void wxWindowGTK::SetFocus()
     GtkWidget *widget = m_wxwindow ? m_wxwindow : m_focusWidget;
 
     if ( GTK_IS_CONTAINER(widget) &&
     GtkWidget *widget = m_wxwindow ? m_wxwindow : m_focusWidget;
 
     if ( GTK_IS_CONTAINER(widget) &&
-         !GTK_WIDGET_CAN_FOCUS(widget) )
+         !gtk_widget_get_can_focus(widget) )
     {
         wxLogTrace(TRACE_FOCUS,
                    wxT("Setting focus to a child of %s(%p, %s)"),
     {
         wxLogTrace(TRACE_FOCUS,
                    wxT("Setting focus to a child of %s(%p, %s)"),
@@ -3151,17 +3246,11 @@ void wxWindowGTK::SetFocus()
 
 void wxWindowGTK::SetCanFocus(bool canFocus)
 {
 
 void wxWindowGTK::SetCanFocus(bool canFocus)
 {
-    if ( canFocus )
-        GTK_WIDGET_SET_FLAGS(m_widget, GTK_CAN_FOCUS);
-    else
-        GTK_WIDGET_UNSET_FLAGS(m_widget, GTK_CAN_FOCUS);
+    gtk_widget_set_can_focus(m_widget, canFocus);
 
     if ( m_wxwindow && (m_widget != m_wxwindow) )
     {
 
     if ( m_wxwindow && (m_widget != m_wxwindow) )
     {
-        if ( canFocus )
-            GTK_WIDGET_SET_FLAGS(m_wxwindow, GTK_CAN_FOCUS);
-        else
-            GTK_WIDGET_UNSET_FLAGS(m_wxwindow, GTK_CAN_FOCUS);
+        gtk_widget_set_can_focus(m_wxwindow, canFocus);
     }
 }
 
     }
 }
 
@@ -3169,8 +3258,7 @@ bool wxWindowGTK::Reparent( wxWindowBase *newParentBase )
 {
     wxCHECK_MSG( (m_widget != NULL), false, wxT("invalid window") );
 
 {
     wxCHECK_MSG( (m_widget != NULL), false, wxT("invalid window") );
 
-    wxWindowGTK *oldParent = m_parent,
-             *newParent = (wxWindowGTK *)newParentBase;
+    wxWindowGTK * const newParent = (wxWindowGTK *)newParentBase;
 
     wxASSERT( GTK_IS_WIDGET(m_widget) );
 
 
     wxASSERT( GTK_IS_WIDGET(m_widget) );
 
@@ -3179,14 +3267,17 @@ bool wxWindowGTK::Reparent( wxWindowBase *newParentBase )
 
     wxASSERT( GTK_IS_WIDGET(m_widget) );
 
 
     wxASSERT( GTK_IS_WIDGET(m_widget) );
 
-    if (oldParent)
-        gtk_container_remove( GTK_CONTAINER(m_widget->parent), m_widget );
+    // Notice that old m_parent pointer might be non-NULL here but the widget
+    // still not have any parent at GTK level if it's a notebook page that had
+    // been removed from the notebook so test this at GTK level and not wx one.
+    if ( GtkWidget *parentGTK = gtk_widget_get_parent(m_widget) )
+        gtk_container_remove(GTK_CONTAINER(parentGTK), m_widget);
 
     wxASSERT( GTK_IS_WIDGET(m_widget) );
 
     if (newParent)
     {
 
     wxASSERT( GTK_IS_WIDGET(m_widget) );
 
     if (newParent)
     {
-        if (GTK_WIDGET_VISIBLE (newParent->m_widget))
+        if (gtk_widget_get_visible (newParent->m_widget))
         {
             m_showOnIdle = true;
             gtk_widget_hide( m_widget );
         {
             m_showOnIdle = true;
             gtk_widget_hide( m_widget );
@@ -3344,18 +3435,20 @@ void wxWindowGTK::RealizeTabOrder()
             {
                 wxWindowGTK *win = *i;
 
             {
                 wxWindowGTK *win = *i;
 
+                bool focusableFromKeyboard = win->AcceptsFocusFromKeyboard();
+
                 if ( mnemonicWindow )
                 {
                 if ( mnemonicWindow )
                 {
-                    if ( win->AcceptsFocusFromKeyboard() )
+                    if ( focusableFromKeyboard )
                     {
                         // wxComboBox et al. needs to focus on on a different
                         // widget than m_widget, so if the main widget isn't
                         // focusable try the connect widget
                         GtkWidget* w = win->m_widget;
                     {
                         // wxComboBox et al. needs to focus on on a different
                         // widget than m_widget, so if the main widget isn't
                         // focusable try the connect widget
                         GtkWidget* w = win->m_widget;
-                        if ( !GTK_WIDGET_CAN_FOCUS(w) )
+                        if ( !gtk_widget_get_can_focus(w) )
                         {
                             w = win->GetConnectWidget();
                         {
                             w = win->GetConnectWidget();
-                            if ( !GTK_WIDGET_CAN_FOCUS(w) )
+                            if ( !gtk_widget_get_can_focus(w) )
                                 w = NULL;
                         }
 
                                 w = NULL;
                         }
 
@@ -3371,7 +3464,8 @@ void wxWindowGTK::RealizeTabOrder()
                     mnemonicWindow = win;
                 }
 
                     mnemonicWindow = win;
                 }
 
-                chain = g_list_prepend(chain, win->m_widget);
+                if ( focusableFromKeyboard )
+                    chain = g_list_prepend(chain, win->m_widget);
             }
 
             chain = g_list_reverse(chain);
             }
 
             chain = g_list_reverse(chain);
@@ -3390,13 +3484,13 @@ void wxWindowGTK::Raise()
 {
     wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
 
 {
     wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
 
-    if (m_wxwindow && m_wxwindow->window)
+    if (m_wxwindow && gtk_widget_get_window(m_wxwindow))
     {
     {
-        gdk_window_raise( m_wxwindow->window );
+        gdk_window_raise(gtk_widget_get_window(m_wxwindow));
     }
     }
-    else if (m_widget->window)
+    else if (gtk_widget_get_window(m_widget))
     {
     {
-        gdk_window_raise( m_widget->window );
+        gdk_window_raise(gtk_widget_get_window(m_widget));
     }
 }
 
     }
 }
 
@@ -3404,19 +3498,19 @@ void wxWindowGTK::Lower()
 {
     wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
 
 {
     wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
 
-    if (m_wxwindow && m_wxwindow->window)
+    if (m_wxwindow && gtk_widget_get_window(m_wxwindow))
     {
     {
-        gdk_window_lower( m_wxwindow->window );
+        gdk_window_lower(gtk_widget_get_window(m_wxwindow));
     }
     }
-    else if (m_widget->window)
+    else if (gtk_widget_get_window(m_widget))
     {
     {
-        gdk_window_lower( m_widget->window );
+        gdk_window_lower(gtk_widget_get_window(m_widget));
     }
 }
 
 bool wxWindowGTK::SetCursor( const wxCursor &cursor )
 {
     }
 }
 
 bool wxWindowGTK::SetCursor( const wxCursor &cursor )
 {
-    if ( !wxWindowBase::SetCursor(cursor.Ok() ? cursor : *wxSTANDARD_CURSOR) )
+    if ( !wxWindowBase::SetCursor(cursor.IsOk() ? cursor : *wxSTANDARD_CURSOR) )
         return false;
 
     GTKUpdateCursor();
         return false;
 
     GTKUpdateCursor();
@@ -3424,33 +3518,40 @@ bool wxWindowGTK::SetCursor( const wxCursor &cursor )
     return true;
 }
 
     return true;
 }
 
-void wxWindowGTK::GTKUpdateCursor()
+void wxWindowGTK::GTKUpdateCursor(bool update_self /*=true*/, bool recurse /*=true*/)
 {
 {
-    wxCursor cursor(g_globalCursor.Ok() ? g_globalCursor : GetCursor());
-    if ( cursor.Ok() )
+    if (update_self)
     {
     {
-        wxArrayGdkWindows windowsThis;
-        GdkWindow * const winThis = GTKGetWindow(windowsThis);
-        if ( winThis )
-        {
-            gdk_window_set_cursor(winThis, cursor.GetCursor());
-        }
-        else
+        wxCursor cursor(g_globalCursor.IsOk() ? g_globalCursor : GetCursor());
+        if ( cursor.IsOk() )
         {
         {
-            const size_t count = windowsThis.size();
-            for ( size_t n = 0; n < count; n++ )
+            wxArrayGdkWindows windowsThis;
+            GdkWindow* window = GTKGetWindow(windowsThis);
+            if (window)
+                gdk_window_set_cursor( window, cursor.GetCursor() );
+            else
             {
             {
-                GdkWindow *win = windowsThis[n];
-                if ( !win )
+                const size_t count = windowsThis.size();
+                for ( size_t n = 0; n < count; n++ )
                 {
                 {
-                    wxFAIL_MSG(wxT("NULL window returned by GTKGetWindow()?"));
-                    continue;
+                    GdkWindow *win = windowsThis[n];
+                    // It can be zero if the window has not been realized yet.
+                    if ( win )
+                    {
+                        gdk_window_set_cursor(win, cursor.GetCursor());
+                    }
                 }
                 }
-
-                gdk_window_set_cursor(win, cursor.GetCursor());
             }
         }
     }
             }
         }
     }
+
+    if (recurse)
+    {
+        for (wxWindowList::iterator it = GetChildren().begin(); it != GetChildren().end(); ++it)
+        {
+            (*it)->GTKUpdateCursor( true );
+        }
+    }
 }
 
 void wxWindowGTK::WarpPointer( int x, int y )
 }
 
 void wxWindowGTK::WarpPointer( int x, int y )
@@ -3462,9 +3563,9 @@ void wxWindowGTK::WarpPointer( int x, int y )
 
     GdkWindow *window = NULL;
     if (m_wxwindow)
 
     GdkWindow *window = NULL;
     if (m_wxwindow)
-        window = m_wxwindow->window;
+        window = gtk_widget_get_window(m_wxwindow);
     else
     else
-        window = GetConnectWidget()->window;
+        window = gtk_widget_get_window(GetConnectWidget());
 
     if (window)
         gdk_window_warp_pointer( window, x, y );
 
     if (window)
         gdk_window_warp_pointer( window, x, y );
@@ -3490,14 +3591,14 @@ bool wxWindowGTK::DoScrollByUnits(ScrollDir dir, ScrollUnit unit, int units)
     GtkRange* range = m_scrollBar[dir];
     if ( range && units )
     {
     GtkRange* range = m_scrollBar[dir];
     if ( range && units )
     {
-        GtkAdjustment* adj = range->adjustment;
-        gdouble inc = unit == ScrollUnit_Line ? adj->step_increment
-                                              : adj->page_increment;
+        GtkAdjustment* adj = gtk_range_get_adjustment(range);
+        double inc = unit == ScrollUnit_Line ? gtk_adjustment_get_step_increment(adj)
+                                             : gtk_adjustment_get_page_increment(adj);
 
 
-        const int posOld = int(adj->value + 0.5);
+        const int posOld = wxRound(gtk_adjustment_get_value(adj));
         gtk_range_set_value(range, posOld + units*inc);
 
         gtk_range_set_value(range, posOld + units*inc);
 
-        changed = int(adj->value + 0.5) != posOld;
+        changed = wxRound(gtk_adjustment_get_value(adj)) != posOld;
     }
 
     return changed;
     }
 
     return changed;
@@ -3534,10 +3635,11 @@ void wxWindowGTK::Refresh(bool WXUNUSED(eraseBackground),
     {
         // Just return if the widget or one of its ancestors isn't mapped
         GtkWidget *w;
     {
         // Just return if the widget or one of its ancestors isn't mapped
         GtkWidget *w;
-        for (w = m_wxwindow; w != NULL; w = w->parent)
-            if (!GTK_WIDGET_MAPPED (w))
+        for (w = m_wxwindow; w != NULL; w = gtk_widget_get_parent(w))
+            if (!gtk_widget_get_mapped (w))
                 return;
 
                 return;
 
+        GdkWindow* window = GTKGetDrawingWindow();
         if (rect)
         {
             int x = rect->x;
         if (rect)
         {
             int x = rect->x;
@@ -3548,23 +3650,26 @@ void wxWindowGTK::Refresh(bool WXUNUSED(eraseBackground),
             r.y = rect->y;
             r.width = rect->width;
             r.height = rect->height;
             r.y = rect->y;
             r.width = rect->width;
             r.height = rect->height;
-            gdk_window_invalidate_rect( m_wxwindow->window, &r, TRUE );
+            gdk_window_invalidate_rect(window, &r, true);
         }
         else
         }
         else
-            gdk_window_invalidate_rect( m_wxwindow->window, NULL, TRUE );
+            gdk_window_invalidate_rect(window, NULL, true);
     }
 }
 
 void wxWindowGTK::Update()
 {
     }
 }
 
 void wxWindowGTK::Update()
 {
-    if (m_widget && m_widget->window)
+    if (m_widget && gtk_widget_get_mapped(m_widget))
     {
         GdkDisplay* display = gtk_widget_get_display(m_widget);
         // Flush everything out to the server, and wait for it to finish.
         // This ensures nothing will overwrite the drawing we are about to do.
         gdk_display_sync(display);
 
     {
         GdkDisplay* display = gtk_widget_get_display(m_widget);
         // Flush everything out to the server, and wait for it to finish.
         // This ensures nothing will overwrite the drawing we are about to do.
         gdk_display_sync(display);
 
-        gdk_window_process_updates(m_widget->window, TRUE);
+        GdkWindow* window = GTKGetDrawingWindow();
+        if (window == NULL)
+            window = gtk_widget_get_window(m_widget);
+        gdk_window_process_updates(window, true);
 
         // Flush again, but no need to wait for it to finish
         gdk_display_flush(display);
 
         // Flush again, but no need to wait for it to finish
         gdk_display_flush(display);
@@ -3603,7 +3708,7 @@ void wxWindowGTK::GtkSendPaintEvents()
         m_updateRegion.Clear();
 
         gint width;
         m_updateRegion.Clear();
 
         gint width;
-        gdk_drawable_get_size(m_wxwindow->window, &width, NULL);
+        gdk_drawable_get_size(gtk_widget_get_window(m_wxwindow), &width, NULL);
 
         wxRegionIterator upd( m_nativeUpdateRegion );
         while (upd)
 
         wxRegionIterator upd( m_nativeUpdateRegion );
         while (upd)
@@ -3657,7 +3762,7 @@ void wxWindowGTK::GtkSendPaintEvents()
                 if (!parent)
                     parent = (wxWindow*)this;
 
                 if (!parent)
                     parent = (wxWindow*)this;
 
-                if (GTK_WIDGET_MAPPED(parent->m_widget))
+                if (gtk_widget_get_mapped(parent->m_widget))
                 {
                     wxRegionIterator upd( m_nativeUpdateRegion );
                     while (upd)
                 {
                     wxRegionIterator upd( m_nativeUpdateRegion );
                     while (upd)
@@ -3668,9 +3773,9 @@ void wxWindowGTK::GtkSendPaintEvents()
                         rect.width = upd.GetWidth();
                         rect.height = upd.GetHeight();
 
                         rect.width = upd.GetWidth();
                         rect.height = upd.GetHeight();
 
-                        gtk_paint_flat_box( parent->m_widget->style,
-                                    m_wxwindow->window,
-                                    (GtkStateType)GTK_WIDGET_STATE(m_wxwindow),
+                        gtk_paint_flat_box(gtk_widget_get_style(parent->m_widget),
+                                    GTKGetDrawingWindow(),
+                                    gtk_widget_get_state(m_wxwindow),
                                     GTK_SHADOW_NONE,
                                     &rect,
                                     parent->m_widget,
                                     GTK_SHADOW_NONE,
                                     &rect,
                                     parent->m_widget,
@@ -3715,7 +3820,7 @@ void wxWindowGTK::SetDoubleBuffered( bool on )
 
 bool wxWindowGTK::IsDoubleBuffered() const
 {
 
 bool wxWindowGTK::IsDoubleBuffered() const
 {
-    return GTK_WIDGET_DOUBLE_BUFFERED( m_wxwindow );
+    return gtk_widget_get_double_buffered( m_wxwindow );
 }
 
 void wxWindowGTK::ClearBackground()
 }
 
 void wxWindowGTK::ClearBackground()
@@ -3726,29 +3831,20 @@ void wxWindowGTK::ClearBackground()
 #if wxUSE_TOOLTIPS
 void wxWindowGTK::DoSetToolTip( wxToolTip *tip )
 {
 #if wxUSE_TOOLTIPS
 void wxWindowGTK::DoSetToolTip( wxToolTip *tip )
 {
-    wxWindowBase::DoSetToolTip(tip);
-
-    if (m_tooltip)
-    {
-        m_tooltip->GTKApply( (wxWindow *)this );
-    }
-    else
+    if (m_tooltip != tip)
     {
     {
-        GtkWidget *w = GetConnectWidget();
-        wxToolTip::GTKApply(w, NULL);
-#if GTK_CHECK_VERSION(2, 12, 0)
-        // Just applying NULL doesn't work on 2.12.0, so also use
-        // gtk_widget_set_has_tooltip. It is part of the new GtkTooltip API
-        // but seems also to work with the old GtkTooltips.
-        if (gtk_check_version(2, 12, 0) == NULL)
-            gtk_widget_set_has_tooltip(w, FALSE);
-#endif
+        wxWindowBase::DoSetToolTip(tip);
+
+        if (m_tooltip)
+            m_tooltip->GTKSetWindow(static_cast<wxWindow*>(this));
+        else
+            GTKApplyToolTip(NULL);
     }
 }
 
     }
 }
 
-void wxWindowGTK::GTKApplyToolTip( GtkTooltips *tips, const gchar *tip )
+void wxWindowGTK::GTKApplyToolTip(const char* tip)
 {
 {
-    gtk_tooltips_set_tip(tips, GetConnectWidget(), tip, NULL);
+    wxToolTip::GTKApply(GetConnectWidget(), tip);
 }
 #endif // wxUSE_TOOLTIPS
 
 }
 #endif // wxUSE_TOOLTIPS
 
@@ -3759,7 +3855,7 @@ bool wxWindowGTK::SetBackgroundColour( const wxColour &colour )
     if (!wxWindowBase::SetBackgroundColour(colour))
         return false;
 
     if (!wxWindowBase::SetBackgroundColour(colour))
         return false;
 
-    if (colour.Ok())
+    if (colour.IsOk())
     {
         // We need the pixel value e.g. for background clearing.
         m_backgroundColour.CalcPixel(gtk_widget_get_colormap(m_widget));
     {
         // We need the pixel value e.g. for background clearing.
         m_backgroundColour.CalcPixel(gtk_widget_get_colormap(m_widget));
@@ -3781,7 +3877,7 @@ bool wxWindowGTK::SetForegroundColour( const wxColour &colour )
         return false;
     }
 
         return false;
     }
 
-    if (colour.Ok())
+    if (colour.IsOk())
     {
         // We need the pixel value e.g. for background clearing.
         m_foregroundColour.CalcPixel(gtk_widget_get_colormap(m_widget));
     {
         // We need the pixel value e.g. for background clearing.
         m_foregroundColour.CalcPixel(gtk_widget_get_colormap(m_widget));
@@ -3803,15 +3899,15 @@ GtkRcStyle *wxWindowGTK::GTKCreateWidgetStyle(bool forceStyle)
 {
     // do we need to apply any changes at all?
     if ( !forceStyle &&
 {
     // do we need to apply any changes at all?
     if ( !forceStyle &&
-         !m_font.Ok() &&
-         !m_foregroundColour.Ok() && !m_backgroundColour.Ok() )
+         !m_font.IsOk() &&
+         !m_foregroundColour.IsOk() && !m_backgroundColour.IsOk() )
     {
         return NULL;
     }
 
     GtkRcStyle *style = gtk_rc_style_new();
 
     {
         return NULL;
     }
 
     GtkRcStyle *style = gtk_rc_style_new();
 
-    if ( m_font.Ok() )
+    if ( m_font.IsOk() )
     {
         style->font_desc =
             pango_font_description_copy( m_font.GetNativeFontInfo()->description );
     {
         style->font_desc =
             pango_font_description_copy( m_font.GetNativeFontInfo()->description );
@@ -3822,7 +3918,7 @@ GtkRcStyle *wxWindowGTK::GTKCreateWidgetStyle(bool forceStyle)
         flagsActive = 0,
         flagsInsensitive = 0;
 
         flagsActive = 0,
         flagsInsensitive = 0;
 
-    if ( m_foregroundColour.Ok() )
+    if ( m_foregroundColour.IsOk() )
     {
         const GdkColor *fg = m_foregroundColour.GetColor();
 
     {
         const GdkColor *fg = m_foregroundColour.GetColor();
 
@@ -3839,7 +3935,7 @@ GtkRcStyle *wxWindowGTK::GTKCreateWidgetStyle(bool forceStyle)
         flagsActive |= GTK_RC_FG | GTK_RC_TEXT;
     }
 
         flagsActive |= GTK_RC_FG | GTK_RC_TEXT;
     }
 
-    if ( m_backgroundColour.Ok() )
+    if ( m_backgroundColour.IsOk() )
     {
         const GdkColor *bg = m_backgroundColour.GetColor();
 
     {
         const GdkColor *bg = m_backgroundColour.GetColor();
 
@@ -3874,7 +3970,7 @@ void wxWindowGTK::GTKApplyWidgetStyle(bool forceStyle)
     if ( style )
     {
         DoApplyWidgetStyle(style);
     if ( style )
     {
         DoApplyWidgetStyle(style);
-        gtk_rc_style_unref(style);
+        g_object_unref(style);
     }
 
     // Style change may affect GTK+'s size calculation:
     }
 
     // Style change may affect GTK+'s size calculation:
@@ -3918,12 +4014,12 @@ bool wxWindowGTK::SetBackgroundStyle(wxBackgroundStyle style)
         GdkWindow *window;
         if ( m_wxwindow )
         {
         GdkWindow *window;
         if ( m_wxwindow )
         {
-            window = m_wxwindow->window;
+            window = GTKGetDrawingWindow();
         }
         else
         {
             GtkWidget * const w = GetConnectWidget();
         }
         else
         {
             GtkWidget * const w = GetConnectWidget();
-            window = w ? w->window : NULL;
+            window = w ? gtk_widget_get_window(w) : NULL;
         }
 
         if (window)
         }
 
         if (window)
@@ -3961,23 +4057,6 @@ bool wxWindowGTK::SetBackgroundStyle(wxBackgroundStyle style)
 
 #if wxUSE_MENUS_NATIVE
 
 
 #if wxUSE_MENUS_NATIVE
 
-static void SetInvokingWindow( wxMenu *menu, wxWindow* win )
-{
-    menu->SetInvokingWindow( win );
-
-    wxMenuItemList::compatibility_iterator node = menu->GetMenuItems().GetFirst();
-    while (node)
-    {
-        wxMenuItem *menuitem = node->GetData();
-        if (menuitem->IsSubMenu())
-        {
-            SetInvokingWindow( menuitem->GetSubMenu(), win );
-        }
-
-        node = node->GetNext();
-    }
-}
-
 extern "C" {
 static
 void wxPopupMenuPositionCallback( GtkMenu *menu,
 extern "C" {
 static
 void wxPopupMenuPositionCallback( GtkMenu *menu,
@@ -4004,10 +4083,6 @@ bool wxWindowGTK::DoPopupMenu( wxMenu *menu, int x, int y )
 {
     wxCHECK_MSG( m_widget != NULL, false, wxT("invalid window") );
 
 {
     wxCHECK_MSG( m_widget != NULL, false, wxT("invalid window") );
 
-    wxCHECK_MSG( menu != NULL, false, wxT("invalid popup-menu") );
-
-    SetInvokingWindow( menu, this );
-
     menu->UpdateUI();
 
     wxPoint pos;
     menu->UpdateUI();
 
     wxPoint pos;
@@ -4084,7 +4159,7 @@ bool wxWindowGTK::GTKIsOwnWindow(GdkWindow *window) const
 
 GdkWindow *wxWindowGTK::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
 {
 
 GdkWindow *wxWindowGTK::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
 {
-    return m_wxwindow ? m_wxwindow->window : m_widget->window;
+    return m_wxwindow ? GTKGetDrawingWindow() : gtk_widget_get_window(m_widget);
 }
 
 bool wxWindowGTK::SetFont( const wxFont &font )
 }
 
 bool wxWindowGTK::SetFont( const wxFont &font )
@@ -4107,14 +4182,14 @@ void wxWindowGTK::DoCaptureMouse()
 
     GdkWindow *window = NULL;
     if (m_wxwindow)
 
     GdkWindow *window = NULL;
     if (m_wxwindow)
-        window = m_wxwindow->window;
+        window = GTKGetDrawingWindow();
     else
     else
-        window = GetConnectWidget()->window;
+        window = gtk_widget_get_window(GetConnectWidget());
 
     wxCHECK_RET( window, wxT("CaptureMouse() failed") );
 
     const wxCursor* cursor = &m_cursor;
 
     wxCHECK_RET( window, wxT("CaptureMouse() failed") );
 
     const wxCursor* cursor = &m_cursor;
-    if (!cursor->Ok())
+    if (!cursor->IsOk())
         cursor = wxSTANDARD_CURSOR;
 
     gdk_pointer_grab( window, FALSE,
         cursor = wxSTANDARD_CURSOR;
 
     gdk_pointer_grab( window, FALSE,
@@ -4140,9 +4215,9 @@ void wxWindowGTK::DoReleaseMouse()
 
     GdkWindow *window = NULL;
     if (m_wxwindow)
 
     GdkWindow *window = NULL;
     if (m_wxwindow)
-        window = m_wxwindow->window;
+        window = GTKGetDrawingWindow();
     else
     else
-        window = GetConnectWidget()->window;
+        window = gtk_widget_get_window(GetConnectWidget());
 
     if (!window)
         return;
 
     if (!window)
         return;
@@ -4186,17 +4261,14 @@ void wxWindowGTK::SetScrollbar(int orient,
         thumbVisible = 1;
     }
 
         thumbVisible = 1;
     }
 
-    GtkAdjustment * const adj = sb->adjustment;
-    adj->step_increment = 1;
-    adj->page_increment =
-    adj->page_size = thumbVisible;
-    adj->value = pos;
-
     g_signal_handlers_block_by_func(
         sb, (void*)gtk_scrollbar_value_changed, this);
 
     g_signal_handlers_block_by_func(
         sb, (void*)gtk_scrollbar_value_changed, this);
 
+    gtk_range_set_increments(sb, 1, thumbVisible);
+    gtk_adjustment_set_page_size(gtk_range_get_adjustment(sb), thumbVisible);
     gtk_range_set_range(sb, 0, range);
     gtk_range_set_range(sb, 0, range);
-    m_scrollPos[dir] = sb->adjustment->value;
+    gtk_range_set_value(sb, pos);
+    m_scrollPos[dir] = gtk_range_get_value(sb);
 
     g_signal_handlers_unblock_by_func(
         sb, (void*)gtk_scrollbar_value_changed, this);
 
     g_signal_handlers_unblock_by_func(
         sb, (void*)gtk_scrollbar_value_changed, this);
@@ -4216,7 +4288,7 @@ void wxWindowGTK::SetScrollPos(int orient, int pos, bool WXUNUSED(refresh))
             sb, (void*)gtk_scrollbar_value_changed, this);
 
         gtk_range_set_value(sb, pos);
             sb, (void*)gtk_scrollbar_value_changed, this);
 
         gtk_range_set_value(sb, pos);
-        m_scrollPos[dir] = sb->adjustment->value;
+        m_scrollPos[dir] = gtk_range_get_value(sb);
 
         g_signal_handlers_unblock_by_func(
             sb, (void*)gtk_scrollbar_value_changed, this);
 
         g_signal_handlers_unblock_by_func(
             sb, (void*)gtk_scrollbar_value_changed, this);
@@ -4228,7 +4300,7 @@ int wxWindowGTK::GetScrollThumb(int orient) const
     GtkRange * const sb = m_scrollBar[ScrollDirFromOrient(orient)];
     wxCHECK_MSG( sb, 0, wxT("this window is not scrollable") );
 
     GtkRange * const sb = m_scrollBar[ScrollDirFromOrient(orient)];
     wxCHECK_MSG( sb, 0, wxT("this window is not scrollable") );
 
-    return wxRound(sb->adjustment->page_size);
+    return wxRound(gtk_adjustment_get_page_size(gtk_range_get_adjustment(sb)));
 }
 
 int wxWindowGTK::GetScrollPos( int orient ) const
 }
 
 int wxWindowGTK::GetScrollPos( int orient ) const
@@ -4236,7 +4308,7 @@ int wxWindowGTK::GetScrollPos( int orient ) const
     GtkRange * const sb = m_scrollBar[ScrollDirFromOrient(orient)];
     wxCHECK_MSG( sb, 0, wxT("this window is not scrollable") );
 
     GtkRange * const sb = m_scrollBar[ScrollDirFromOrient(orient)];
     wxCHECK_MSG( sb, 0, wxT("this window is not scrollable") );
 
-    return wxRound(sb->adjustment->value);
+    return wxRound(gtk_range_get_value(sb));
 }
 
 int wxWindowGTK::GetScrollRange( int orient ) const
 }
 
 int wxWindowGTK::GetScrollRange( int orient ) const
@@ -4244,7 +4316,7 @@ int wxWindowGTK::GetScrollRange( int orient ) const
     GtkRange * const sb = m_scrollBar[ScrollDirFromOrient(orient)];
     wxCHECK_MSG( sb, 0, wxT("this window is not scrollable") );
 
     GtkRange * const sb = m_scrollBar[ScrollDirFromOrient(orient)];
     wxCHECK_MSG( sb, 0, wxT("this window is not scrollable") );
 
-    return wxRound(sb->adjustment->upper);
+    return wxRound(gtk_adjustment_get_upper(gtk_range_get_adjustment(sb)));
 }
 
 // Determine if increment is the same as +/-x, allowing for some small
 }
 
 // Determine if increment is the same as +/-x, allowing for some small
@@ -4261,16 +4333,15 @@ wxEventType wxWindowGTK::GTKGetScrollEventType(GtkRange* range)
     wxASSERT(range == m_scrollBar[0] || range == m_scrollBar[1]);
 
     const int barIndex = range == m_scrollBar[1];
     wxASSERT(range == m_scrollBar[0] || range == m_scrollBar[1]);
 
     const int barIndex = range == m_scrollBar[1];
-    GtkAdjustment* adj = range->adjustment;
 
 
-    const int value = wxRound(adj->value);
+    const double value = gtk_range_get_value(range);
 
     // save previous position
     const double oldPos = m_scrollPos[barIndex];
     // update current position
 
     // save previous position
     const double oldPos = m_scrollPos[barIndex];
     // update current position
-    m_scrollPos[barIndex] = adj->value;
+    m_scrollPos[barIndex] = value;
     // If event should be ignored, or integral position has not changed
     // If event should be ignored, or integral position has not changed
-    if (!m_hasVMT || g_blockEventsOnDrag || value == wxRound(oldPos))
+    if (!m_hasVMT || g_blockEventsOnDrag || wxRound(value) == wxRound(oldPos))
     {
         return wxEVT_NULL;
     }
     {
         return wxEVT_NULL;
     }
@@ -4279,14 +4350,15 @@ wxEventType wxWindowGTK::GTKGetScrollEventType(GtkRange* range)
     if (!m_isScrolling)
     {
         // Difference from last change event
     if (!m_isScrolling)
     {
         // Difference from last change event
-        const double diff = adj->value - oldPos;
+        const double diff = value - oldPos;
         const bool isDown = diff > 0;
 
         const bool isDown = diff > 0;
 
-        if (IsScrollIncrement(adj->step_increment, diff))
+        GtkAdjustment* adj = gtk_range_get_adjustment(range);
+        if (IsScrollIncrement(gtk_adjustment_get_step_increment(adj), diff))
         {
             eventType = isDown ? wxEVT_SCROLL_LINEDOWN : wxEVT_SCROLL_LINEUP;
         }
         {
             eventType = isDown ? wxEVT_SCROLL_LINEDOWN : wxEVT_SCROLL_LINEUP;
         }
-        else if (IsScrollIncrement(adj->page_increment, diff))
+        else if (IsScrollIncrement(gtk_adjustment_get_page_increment(adj), diff))
         {
             eventType = isDown ? wxEVT_SCROLL_PAGEDOWN : wxEVT_SCROLL_PAGEUP;
         }
         {
             eventType = isDown ? wxEVT_SCROLL_PAGEDOWN : wxEVT_SCROLL_PAGEUP;
         }
@@ -4412,7 +4484,7 @@ GdkWindow* wxWindowGTK::GTKGetDrawingWindow() const
 {
     GdkWindow* window = NULL;
     if (m_wxwindow)
 {
     GdkWindow* window = NULL;
     if (m_wxwindow)
-        window = m_wxwindow->window;
+        window = gtk_widget_get_window(m_wxwindow);
     return window;
 }
 
     return window;
 }
 
@@ -4425,29 +4497,35 @@ extern "C"
 
 // this is called if we attempted to freeze unrealized widget when it finally
 // is realized (and so can be frozen):
 
 // this is called if we attempted to freeze unrealized widget when it finally
 // is realized (and so can be frozen):
-static void wx_frozen_widget_realize(GtkWidget* w, void* WXUNUSED(data))
+static void wx_frozen_widget_realize(GtkWidget* w, wxWindowGTK* win)
 {
 {
-    wxASSERT( w && !GTK_WIDGET_NO_WINDOW(w) );
-    wxASSERT( GTK_WIDGET_REALIZED(w) );
+    wxASSERT( w && gtk_widget_get_has_window(w) );
+    wxASSERT( gtk_widget_get_realized(w) );
 
     g_signal_handlers_disconnect_by_func
     (
         w,
         (void*)wx_frozen_widget_realize,
 
     g_signal_handlers_disconnect_by_func
     (
         w,
         (void*)wx_frozen_widget_realize,
-        NULL
+        win
     );
 
     );
 
-    gdk_window_freeze_updates(w->window);
+    GdkWindow* window;
+    if (w == win->m_wxwindow)
+        window = win->GTKGetDrawingWindow();
+    else
+        window = gtk_widget_get_window(w);
+    gdk_window_freeze_updates(window);
 }
 
 } // extern "C"
 
 void wxWindowGTK::GTKFreezeWidget(GtkWidget *w)
 {
 }
 
 } // extern "C"
 
 void wxWindowGTK::GTKFreezeWidget(GtkWidget *w)
 {
-    if ( !w || GTK_WIDGET_NO_WINDOW(w) )
+    if ( !w || !gtk_widget_get_has_window(w) )
         return; // window-less widget, cannot be frozen
 
         return; // window-less widget, cannot be frozen
 
-    if ( !GTK_WIDGET_REALIZED(w) )
+    GdkWindow* window = gtk_widget_get_window(w);
+    if (window == NULL)
     {
         // we can't thaw unrealized widgets because they don't have GdkWindow,
         // so set it up to be done immediately after realization:
     {
         // we can't thaw unrealized widgets because they don't have GdkWindow,
         // so set it up to be done immediately after realization:
@@ -4456,32 +4534,37 @@ void wxWindowGTK::GTKFreezeWidget(GtkWidget *w)
             w,
             "realize",
             G_CALLBACK(wx_frozen_widget_realize),
             w,
             "realize",
             G_CALLBACK(wx_frozen_widget_realize),
-            NULL
+            this
         );
         return;
     }
 
         );
         return;
     }
 
-    gdk_window_freeze_updates(w->window);
+    if (w == m_wxwindow)
+        window = GTKGetDrawingWindow();
+    gdk_window_freeze_updates(window);
 }
 
 void wxWindowGTK::GTKThawWidget(GtkWidget *w)
 {
 }
 
 void wxWindowGTK::GTKThawWidget(GtkWidget *w)
 {
-    if ( !w || GTK_WIDGET_NO_WINDOW(w) )
+    if ( !w || !gtk_widget_get_has_window(w) )
         return; // window-less widget, cannot be frozen
 
         return; // window-less widget, cannot be frozen
 
-    if ( !GTK_WIDGET_REALIZED(w) )
+    GdkWindow* window = gtk_widget_get_window(w);
+    if (window == NULL)
     {
         // the widget wasn't realized yet, no need to thaw
         g_signal_handlers_disconnect_by_func
         (
             w,
             (void*)wx_frozen_widget_realize,
     {
         // the widget wasn't realized yet, no need to thaw
         g_signal_handlers_disconnect_by_func
         (
             w,
             (void*)wx_frozen_widget_realize,
-            NULL
+            this
         );
         return;
     }
 
         );
         return;
     }
 
-    gdk_window_thaw_updates(w->window);
+    if (w == m_wxwindow)
+        window = GTKGetDrawingWindow();
+    gdk_window_thaw_updates(window);
 }
 
 void wxWindowGTK::DoFreeze()
 }
 
 void wxWindowGTK::DoFreeze()