]> git.saurik.com Git - wxWidgets.git/commitdiff
Many changes:
authorVadim Zeitlin <vadim@wxwidgets.org>
Fri, 25 Aug 2006 12:59:28 +0000 (12:59 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Fri, 25 Aug 2006 12:59:28 +0000 (12:59 +0000)
- Introduced GTKGetWindow() which returns all GdkWindows associated with the
  given wxWindow
- Renamed IsOwnGtkWindow() to GTKIsOwnWindow() to avoid confusion with the old
  virtual function (the new one is non-virtual and is implemented in terms of
  GTKGetWindow())
- Refactored/simplified event handlers code in gtk/window.cpp
- Fixed some header guards names (__GTKFOO__ -> _WX_GTK_FOO_H_)
- Added GTKUpdateCursor() which sets the current cursor for all windows
  returned by GTKGetWindow()
- Factored out code from many different classes in wxControl::OnInternalIdle()
  which now updates the cursor, checks for internal focus and sends update UI
  events

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@40815 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

32 files changed:
docs/changes.txt
include/wx/gtk/button.h
include/wx/gtk/checkbox.h
include/wx/gtk/choice.h
include/wx/gtk/combobox.h
include/wx/gtk/control.h
include/wx/gtk/listbox.h
include/wx/gtk/notebook.h
include/wx/gtk/radiobox.h
include/wx/gtk/radiobut.h
include/wx/gtk/scrolbar.h
include/wx/gtk/slider.h
include/wx/gtk/spinbutt.h
include/wx/gtk/spinctrl.h
include/wx/gtk/textctrl.h
include/wx/gtk/tglbtn.h
include/wx/gtk/window.h
src/gtk/button.cpp
src/gtk/checkbox.cpp
src/gtk/choice.cpp
src/gtk/combobox.cpp
src/gtk/control.cpp
src/gtk/notebook.cpp
src/gtk/radiobox.cpp
src/gtk/radiobut.cpp
src/gtk/scrolbar.cpp
src/gtk/slider.cpp
src/gtk/spinbutt.cpp
src/gtk/spinctrl.cpp
src/gtk/textctrl.cpp
src/gtk/tglbtn.cpp
src/gtk/window.cpp

index 9d6364fac0b2e4df456049904a59d817a68824af..e1c9b38d65975a811ef1effd5c31ab2287f9e1e3 100644 (file)
@@ -67,6 +67,7 @@ wxMac:
 wxGTK:
 
 - Automatically use stock items for the menu items with standard ids
+- Setting cursor now works for all controls
 
 
 2.7.0
index a395a617ca8e34a25264092482778af38240e64f..919c528c221ef0d67298793ba7c0fc7c97526efa 100644 (file)
@@ -61,8 +61,6 @@ public:
     // implementation
     // --------------
 
-    bool IsOwnGtkWindow( GdkWindow *window );
-
     // Since this wxButton doesn't derive from wxButtonBase (why?) we need
     // to override this here too...
     virtual bool ShouldInheritColours() const { return false; }
@@ -75,7 +73,9 @@ public:
 
 protected:
     virtual wxSize DoGetBestSize() const;
-    void DoApplyWidgetStyle(GtkRcStyle *style);
+    virtual void DoApplyWidgetStyle(GtkRcStyle *style);
+
+    virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
 
 private:
     DECLARE_DYNAMIC_CLASS(wxButton)
index a1ed20538c76ee3fd84f85f1f1c873f557f691c1..c4639026ff131e77d54d3d88a3c66b93b1271263 100644 (file)
@@ -47,9 +47,6 @@ public:
     // implementation
     // --------------
 
-    bool IsOwnGtkWindow( GdkWindow *window );
-    void OnInternalIdle();
-
     GtkWidget *m_widgetCheckbox;
     GtkWidget *m_widgetLabel;
 
@@ -57,7 +54,8 @@ public:
 
 protected:
     virtual wxSize DoGetBestSize() const;
-    void DoApplyWidgetStyle(GtkRcStyle *style);
+    virtual void DoApplyWidgetStyle(GtkRcStyle *style);
+    virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
 
     void DoSet3StateValue(wxCheckBoxState state);
     wxCheckBoxState DoGet3StateValue() const;
index 12d9a3a5fb719ac3b1b7501bd09a4819edac5192..4a3527f52c12f0efa2df033c5d75decddd4bcadb 100644 (file)
@@ -77,12 +77,13 @@ public:
     static wxVisualAttributes
     GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL);
 
-    virtual bool IsOwnGtkWindow( GdkWindow *window );
-
 protected:
     wxList m_clientList;    // contains the client data for the items
 
-    void DoApplyWidgetStyle(GtkRcStyle *style);
+    virtual wxSize DoGetBestSize() const;
+    virtual void DoApplyWidgetStyle(GtkRcStyle *style);
+    virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
+
     virtual int DoAppend(const wxString& item);
     virtual int DoInsert(const wxString& item, unsigned int pos);
 
@@ -91,8 +92,6 @@ protected:
     virtual void DoSetItemClientObject(unsigned int n, wxClientData* clientData);
     virtual wxClientData* DoGetItemClientObject(unsigned int n) const;
 
-    virtual wxSize DoGetBestSize() const;
-
 private:
     // common part of Create() and DoAppend()
     int GtkAddHelper(GtkWidget *menu, unsigned int pos, const wxString& item);
index 4d2e4195309a7985952391f471106cdb9737900c..206e72989624d4213f6c59673e1e7a868d44c744 100644 (file)
@@ -152,7 +152,6 @@ public:
     void DisableEvents();
     void EnableEvents();
     GtkWidget* GetConnectWidget();
-    bool IsOwnGtkWindow( GdkWindow *window );
 
     wxCONTROL_ITEMCONTAINER_CLIENTDATAOBJECT_RECAST
 
@@ -161,7 +160,8 @@ public:
 
 protected:
     // From wxWindowGTK:
-    void DoApplyWidgetStyle(GtkRcStyle *style);
+    virtual void DoApplyWidgetStyle(GtkRcStyle *style);
+    virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
 
     // From wxItemContainer:
     virtual int DoAppend(const wxString& item);
index f2e5c6dc045aa7b5c84e77aec6f2723f546d865d..d2cfee5cd8dec9bfeb151264d2f9ee273b8e7025 100644 (file)
@@ -59,6 +59,8 @@ public:
 
     virtual wxVisualAttributes GetDefaultAttributes() const;
 
+    virtual void OnInternalIdle();
+
 protected:
     virtual wxSize DoGetBestSize() const;
     void PostCreation(const wxSize& size);
index c5c28a4e78f5d2e323188722153abf7fe9f1e3e4..5332a01f0cf54bb2594aae63ed1b374bdb392726 100644 (file)
@@ -80,8 +80,6 @@ public:
     // implementation from now on
 
     GtkWidget *GetConnectWidget();
-    bool IsOwnGtkWindow( GdkWindow *window );
-    void OnInternalIdle();
 
 #if wxUSE_TOOLTIPS
     void ApplyToolTip( GtkTooltips *tips, const wxChar *tip );
@@ -105,6 +103,9 @@ public:
 
 protected:
     virtual wxSize DoGetBestSize() const;
+    virtual void DoApplyWidgetStyle(GtkRcStyle *style);
+    virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
+
     virtual void DoSetSelection(int n, bool select);
     virtual int DoAppend(const wxString& item);
     virtual void DoInsertItems(const wxArrayString& items, unsigned int pos);
@@ -116,8 +117,6 @@ protected:
     virtual wxClientData* DoGetItemClientObject(unsigned int n) const;
     virtual int DoListHitTest(const wxPoint& point) const;
 
-    void DoApplyWidgetStyle(GtkRcStyle *style);
-
 private:
     void Init(); //common construction
 
index 9724afdb1175c19e75be8b604d4eae6ad54dbac3..8965c2d2f6f1581fb8b38327f69edc3285e51559 100644 (file)
@@ -103,8 +103,6 @@ public:
     void SetConstraintSizes(bool recurse);
     bool DoPhase(int phase);
 #endif
-    // report if window belongs to notebook
-    bool IsOwnGtkWindow( GdkWindow *window );
 
     // common part of all ctors
     void Init();
@@ -124,7 +122,8 @@ public:
 
 protected:
     // set all page's attributes
-    void DoApplyWidgetStyle(GtkRcStyle *style);
+    virtual void DoApplyWidgetStyle(GtkRcStyle *style);
+    virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
 
     // remove one page from the notebook but do not destroy it
     virtual wxNotebookPage *DoRemovePage(size_t nPage);
index bd74401b39204df1b23b210116cbb1e73d1b1d83..77bbb3a066d04e0b8daac70e9acf1d78a41a5f32 100644 (file)
@@ -131,7 +131,6 @@ public:
     void SetFocus();
     void GtkDisableEvents();
     void GtkEnableEvents();
-    bool IsOwnGtkWindow( GdkWindow *window );
 #if wxUSE_TOOLTIPS
     void ApplyToolTip( GtkTooltips *tips, const wxChar *tip );
 #endif // wxUSE_TOOLTIPS
@@ -147,7 +146,8 @@ protected:
     virtual void DoSetItemToolTip(unsigned int n, wxToolTip *tooltip);
 #endif
 
-    void DoApplyWidgetStyle(GtkRcStyle *style);
+    virtual void DoApplyWidgetStyle(GtkRcStyle *style);
+    virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
 
     virtual bool GTKWidgetNeedsMnemonic() const;
     virtual void GTKWidgetDoSetMnemonic(GtkWidget* w);
index d9eea34fdb5c228b0aa14a948f4a83cbad4e83cf..bb4f5d869cffc81d7a73392dc00fd31e7ced7a92 100644 (file)
@@ -7,8 +7,8 @@
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifndef __GTKRADIOBUTTONH__
-#define __GTKRADIOBUTTONH__
+#ifndef _WX_GTK_RADIOBUT_H_
+#define _WX_GTK_RADIOBUT_H_
 
 //-----------------------------------------------------------------------------
 // wxRadioButton
@@ -51,17 +51,15 @@ public:
 
     virtual bool IsRadioButton() const { return TRUE; }
 
-    bool IsOwnGtkWindow( GdkWindow *window );
-    void OnInternalIdle();
-
     bool m_blockEvent;
 
 protected:
-    void DoApplyWidgetStyle(GtkRcStyle *style);
     virtual wxSize DoGetBestSize() const;
+    virtual void DoApplyWidgetStyle(GtkRcStyle *style);
+    virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
 
 private:
     DECLARE_DYNAMIC_CLASS(wxRadioButton)
 };
 
-#endif // __GTKRADIOBUTTONH__
+#endif // _WX_GTK_RADIOBUT_H_
index 37d64dbae6ef1d5852e1821637b95f99fac71d97..3f94c5c0620b81c63c21c36786047744a9c0b7d7 100644 (file)
@@ -7,8 +7,8 @@
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifndef __GTKSCROLLBARH__
-#define __GTKSCROLLBARH__
+#ifndef _WX_GTK_SCROLLBAR_H_
+#define _WX_GTK_SCROLLBAR_H_
 
 #include "wx/defs.h"
 
@@ -57,14 +57,11 @@ public:
     static wxVisualAttributes
     GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL);
     
-    // implementation
-    // --------------
-
-    bool IsOwnGtkWindow( GdkWindow *window );
+protected:
+    virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
 
 private:
     DECLARE_DYNAMIC_CLASS(wxScrollBar)
 };
 
-#endif
-    // __GTKSCROLLBARH__
+#endif // _WX_GTK_SCROLLBAR_H_
index 8322bf66a9dfb0cf531ac5a44264d2917b8b724e..76f6dae280b91cd0189e6ee7a581c719cfdb3c9c 100644 (file)
@@ -60,12 +60,13 @@ public:
     GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL);
     
     // implementation
-    bool IsOwnGtkWindow( GdkWindow *window );
-
     double m_pos;
     int m_scrollEventType;
     bool m_needThumbRelease;
 
+protected:
+    virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
+
 private:
     DECLARE_DYNAMIC_CLASS(wxSlider)
 };
index f70abfcee03de3bfd61dff50b0891da10aa11226..4daf12bb375eefef7092b352c750a6aeaf602334 100644 (file)
@@ -48,12 +48,11 @@ public:
     // implementation
     void OnSize( wxSizeEvent &event );
 
-    bool IsOwnGtkWindow( GdkWindow *window );
-
     int m_pos;
 
 protected:
     virtual wxSize DoGetBestSize() const;
+    virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
 
 private:
     DECLARE_EVENT_TABLE()
index 426a01f4b07818051554c390f8a92c299b097457..77e2ae5fec22fba1bcb90adc326fc88415df7646 100644 (file)
@@ -61,7 +61,6 @@ public:
     // implementation
     void OnChar( wxKeyEvent &event );
     
-    bool IsOwnGtkWindow( GdkWindow *window );
     void GtkDisableEvents();
     void GtkEnableEvents();
 
@@ -69,6 +68,7 @@ public:
 
 protected:
     virtual wxSize DoGetBestSize() const;
+    virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
 
     // Widgets that use the style->base colour for the BG colour should
     // override this and return true.
index 19c3ca90102b3a8b8e0be7fed4058416eddb436a..9f1c6eddd2c594d4f736b5b8f63e752f49bebca1 100644 (file)
@@ -138,9 +138,7 @@ public:
     bool SetBackgroundColour(const wxColour& colour);
 
     GtkWidget* GetConnectWidget();
-    bool IsOwnGtkWindow( GdkWindow *window );
     void CalculateScrollbar();
-    void OnInternalIdle();
 
     void SetUpdateFont(bool WXUNUSED(update)) { }
 
@@ -175,7 +173,8 @@ public:
 
 protected:
     virtual wxSize DoGetBestSize() const;
-    void DoApplyWidgetStyle(GtkRcStyle *style);
+    virtual void DoApplyWidgetStyle(GtkRcStyle *style);
+    virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
 
     // common part of all ctors
     void Init();
index 0c542ac0c9f29d1dcba198e43e328fa7a104e129..4964591aa10a3dbd9d7d4866fe6a76b538ba05dc 100644 (file)
@@ -75,13 +75,11 @@ public:
     wxBitmap  m_bitmap;
 
     void OnSetBitmap();
-    bool IsOwnGtkWindow(GdkWindow *window);
-
-    virtual void OnInternalIdle();
 
 protected:
-    void DoApplyWidgetStyle(GtkRcStyle *style);
     virtual wxSize DoGetBestSize() const;
+    virtual void DoApplyWidgetStyle(GtkRcStyle *style);
+    virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
 
 private:
     DECLARE_DYNAMIC_CLASS(wxToggleBitmapButton)
@@ -131,13 +129,10 @@ public:
     // implementation
     bool m_blockEvent;
 
-    bool IsOwnGtkWindow(GdkWindow *window);
-
-    virtual void OnInternalIdle();
-
 protected:
-    void DoApplyWidgetStyle(GtkRcStyle *style);
     virtual wxSize DoGetBestSize() const;
+    virtual void DoApplyWidgetStyle(GtkRcStyle *style);
+    virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
 
 private:
     DECLARE_DYNAMIC_CLASS(wxToggleButton)
index fb02d8304f1993c8346a5a8afc4a166ff487ad79..8106f545cded1703f8864db24af4697e0c6d9926 100644 (file)
@@ -7,13 +7,17 @@
 // Licence:     wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
-#ifndef __GTKWINDOWH__
-#define __GTKWINDOWH__
+#ifndef _WX_GTK_WINDOW_H_
+#define _WX_GTK_WINDOW_H_
+
+#include "wx/dynarray.h"
 
 // helper structure that holds class that holds GtkIMContext object and
 // some additional data needed for key events processing
 struct wxGtkIMData;
 
+WX_DEFINE_EXPORTED_ARRAY_PTR(GdkWindow *, wxArrayGdkWindows);
+
 //-----------------------------------------------------------------------------
 // callback definition for inserting a window (internal)
 //-----------------------------------------------------------------------------
@@ -117,6 +121,8 @@ public:
 
     virtual WXWidget GetHandle() const { return m_widget; }
 
+    // many important things are done here, this function must be called
+    // regularly
     virtual void OnInternalIdle();
 
     // Internal represention of Update()
@@ -153,9 +159,11 @@ public:
     // widget where (most of) the input goes. even tooltips have
     // to be applied to all subwidgets.
     virtual GtkWidget* GetConnectWidget();
-    virtual bool IsOwnGtkWindow( GdkWindow *window );
     void ConnectWidget( GtkWidget *widget );
 
+    // Called from several event handlers
+    bool GTKCallbackCommonPrologue(struct _GdkEventAny *event) const;
+
 protected:
     // Override GTKWidgetNeedsMnemonic and return true if your
     // needs to set its mnemonic widget, such as for a 
@@ -164,6 +172,24 @@ protected:
     virtual bool GTKWidgetNeedsMnemonic() const;
     virtual void GTKWidgetDoSetMnemonic(GtkWidget* w);
 
+    // Get the GdkWindows making part of this window: usually there will be
+    // only one of them in which case it should be returned directly by this
+    // function. If there is more than one GdkWindow (can be the case for
+    // composite widgets), return NULL and fill in the provided array
+    //
+    // This is not pure virtual for backwards compatibility but almost
+    // certainly must be overridden in any wxControl-derived class!
+    virtual GdkWindow *GTKGetWindow(wxArrayGdkWindows& windows) const;
+
+    // Check if the given window makes part of this widget
+    bool GTKIsOwnWindow(GdkWindow *window) const;
+
+    // Set the focus to this window if its setting was delayed because the
+    // widget hadn't been realized when SetFocus() was called
+    //
+    // Return true if focus was set to us, false if nothing was done
+    bool GTKSetDelayedFocusIfNeeded();
+
 public:
     // Returns the default context which usually is anti-aliased
     PangoContext   *GtkGetPangoDefaultContext();
@@ -323,6 +349,12 @@ protected:
     // sets the border of a given GtkScrolledWindow from a wx style
     static void GtkScrolledWindowSetBorder(GtkWidget* w, int style);
 
+    // set the current cursor for all GdkWindows making part of this widget
+    // (see GTKGetWindow)
+    //
+    // should be called from OnInternalIdle() if it's overridden
+    void GTKUpdateCursor();
+
 private:
     enum ScrollUnit { ScrollUnit_Line, ScrollUnit_Page, ScrollUnit_Max };
 
@@ -340,4 +372,4 @@ private:
 
 extern WXDLLIMPEXP_CORE wxWindow *wxFindFocusedChild(wxWindowGTK *win);
 
-#endif // __GTKWINDOWH__
+#endif // _WX_GTK_WINDOW_H_
index efcfb9626fd11a816c2f9c0fdcd93d2363dbb01d..35e0b4f53712a2e9aec2134106ba835bbff4f4d7 100644 (file)
@@ -257,7 +257,7 @@ bool wxButton::Enable( bool enable )
     return true;
 }
 
-bool wxButton::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
 {
     return GTK_BUTTON(m_widget)->event_window;
 }
index c03eefa9c3f5cd266b191377e2a151585930c00a..7dcc25d78f9527f07063671d146efd7a9e6b299a 100644 (file)
@@ -21,8 +21,6 @@
 //-----------------------------------------------------------------------------
 
 extern bool           g_blockEventsOnDrag;
-extern wxCursor       g_globalCursor;
-extern wxWindowGTK   *g_delayedFocus;
 
 //-----------------------------------------------------------------------------
 // "clicked"
@@ -225,41 +223,9 @@ void wxCheckBox::DoApplyWidgetStyle(GtkRcStyle *style)
     gtk_widget_modify_style(m_widgetLabel, style);
 }
 
-bool wxCheckBox::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxCheckBox::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
 {
-    return window == GTK_BUTTON(m_widget)->event_window;
-}
-
-void wxCheckBox::OnInternalIdle()
-{
-    // Check if we have to show window now
-    if (GtkShowFromOnIdle()) return;
-    
-    wxCursor cursor = m_cursor;
-    if (g_globalCursor.Ok()) cursor = g_globalCursor;
-
-    GdkWindow *event_window = GTK_BUTTON(m_widgetCheckbox)->event_window;
-    if ( event_window && cursor.Ok() )
-    {
-        /* I now set the cursor the 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. */
-
-       gdk_window_set_cursor( event_window, cursor.GetCursor() );
-    }
-
-    if (g_delayedFocus == this)
-    {
-        if (GTK_WIDGET_REALIZED(m_widget))
-        {
-            gtk_widget_grab_focus( m_widget );
-            g_delayedFocus = NULL;
-        }
-    }
-
-    if (wxUpdateUIEvent::CanUpdate(this))
-        UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
+    return GTK_BUTTON(m_widgetCheckbox)->event_window;
 }
 
 wxSize wxCheckBox::DoGetBestSize() const
index a7f05f679afed006baec1e027f89a933723f5465..737522f7ada89e092399945b7e55b1d5aa8c5a39 100644 (file)
@@ -599,7 +599,7 @@ wxSize wxChoice::DoGetBestSize() const
     return ret;
 }
 
-bool wxChoice::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxChoice::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
 {
     return GTK_BUTTON(m_widget)->event_window;
 }
index 6549733c33c8af19a978ff13aa89c5f4a4eb3aef..32123f67cc985df473d1772921aa980cb3d97cfa 100644 (file)
@@ -1325,21 +1325,23 @@ GtkWidget* wxComboBox::GetConnectWidget()
     return GTK_WIDGET( entry );
 }
 
-bool wxComboBox::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxComboBox::GTKGetWindow(wxArrayGdkWindows& windows) const
 {
-    GtkEntry *entry = NULL;
 #ifdef __WXGTK24__
     if (!gtk_check_version(2,4,0))
     {
-        entry = GTK_ENTRY( GTK_BIN(m_widget)->child );
-        return (window == entry->text_area);
+        wxUnusedVar(windows);
+
+        return GTK_ENTRY(GTK_BIN(m_widget)->child)->text_area;
     }
     else
-#endif
+#endif // GTK+ 2.4
     {
-        entry = GTK_ENTRY( GTK_COMBO(m_widget)->entry );
-        return ( (window == entry->text_area) ||
-                 (window == GTK_COMBO(m_widget)->button->window ) );
+        windows.push_back(GTK_ENTRY(GTK_COMBO(m_widget)->entry)->text_area);
+        windows.push_back(GTK_COMBO(m_widget)->button->window);
+
+        // indicate that we return multiple windows in the windows array
+        return NULL;
     }
 }
 
index 613ed139fa1c74732b1d4eac2d6cf122cf6dcc15..21e35fd0d214217b98c333190df0647a76b9148a 100644 (file)
@@ -366,4 +366,19 @@ wxControl::GetDefaultAttributesFromGTKWidget(wxGtkWidgetNewFromAdj_t widget_new,
     return attr;
 }
 
+// ----------------------------------------------------------------------------
+// idle handling
+// ----------------------------------------------------------------------------
+
+void wxControl::OnInternalIdle()
+{
+    if ( GtkShowFromOnIdle() )
+        return;
+    
+    GTKUpdateCursor();
+
+    if ( wxUpdateUIEvent::CanUpdate(this) )
+        UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
+}
+
 #endif // wxUSE_CONTROLS
index b8dfb49c813dd01d987b9d490fb6abce11c08a5c..756cd7f21b73e52e1d612e7aafb4bade2fde150c 100644 (file)
@@ -847,10 +847,12 @@ void wxNotebook::DoApplyWidgetStyle(GtkRcStyle *style)
         gtk_widget_modify_style(GTK_WIDGET(GetNotebookPage(i)->m_label), style);
 }
 
-bool wxNotebook::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxNotebook::GTKGetWindow(wxArrayGdkWindows& windows) const
 {
-    return ((m_widget->window == window) ||
-            GTK_NOTEBOOK(m_widget)->event_window == window);
+    windows.push_back(m_widget->window);
+    windows.push_back(GTK_NOTEBOOK(m_widget)->event_window);
+
+    return NULL;
 }
 
 // static
index 7af0bde3dd342e39f495fef2c3a1f42573b1f2eb..9117e587aca3ab6541b156d8e2e353ab75eac4a9 100644 (file)
@@ -52,7 +52,6 @@ public:
 WX_DEFINE_LIST( wxRadioBoxButtonsInfoList );
 
 extern bool          g_blockEventsOnDrag;
-extern wxWindowGTK  *g_delayedFocus;
 
 //-----------------------------------------------------------------------------
 // "clicked"
@@ -638,30 +637,27 @@ void wxRadioBox::DoSetItemToolTip(unsigned int n, wxToolTip *tooltip)
 
 #endif // wxUSE_TOOLTIPS
 
-bool wxRadioBox::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxRadioBox::GTKGetWindow(wxArrayGdkWindows& windows) const
 {
-    if (window == m_widget->window)
-        return true;
+    windows.push_back(m_widget->window);
 
     wxRadioBoxButtonsInfoList::compatibility_iterator node = m_buttonsInfo.GetFirst();
     while (node)
     {
         GtkWidget *button = GTK_WIDGET( node->GetData()->button );
 
-        if (window == button->window)
-            return true;
+        windows.push_back(button->window);
 
         node = node->GetNext();
     }
 
-    return false;
+    return NULL;
 }
 
 void wxRadioBox::OnInternalIdle()
 {
-    // Check if we have to show window now
-    if (GtkShowFromOnIdle()) return;
-    
+    wxControl::OnInternalIdle();
+
     if ( m_lostFocus )
     {
         m_hasFocus = false;
@@ -672,18 +668,6 @@ void wxRadioBox::OnInternalIdle()
 
         (void)GetEventHandler()->ProcessEvent( event );
     }
-
-    if (g_delayedFocus == this)
-    {
-        if (GTK_WIDGET_REALIZED(m_widget))
-        {
-            g_delayedFocus = NULL;
-            SetFocus();
-        }
-    }
-
-    if (wxUpdateUIEvent::CanUpdate(this))
-        UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
 }
 
 // static
index cf56a75187a830d7dbffc1cd856a93713084b945..400b101454b5fe77b956e10cca84cdf66f92614d 100644 (file)
@@ -21,8 +21,6 @@
 //-----------------------------------------------------------------------------
 
 extern bool           g_blockEventsOnDrag;
-extern wxCursor       g_globalCursor;
-extern wxWindowGTK   *g_delayedFocus;
 
 //-----------------------------------------------------------------------------
 // "clicked"
@@ -167,38 +165,10 @@ void wxRadioButton::DoApplyWidgetStyle(GtkRcStyle *style)
     gtk_widget_modify_style(GTK_BIN(m_widget)->child, style);
 }
 
-bool wxRadioButton::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *
+wxRadioButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
 {
-    return window == GTK_BUTTON(m_widget)->event_window;
-}
-
-void wxRadioButton::OnInternalIdle()
-{
-    wxCursor cursor = m_cursor;
-    if (g_globalCursor.Ok()) cursor = g_globalCursor;
-
-    GdkWindow *win = GTK_BUTTON(m_widget)->event_window;
-    if ( win && cursor.Ok())
-    {
-        /* I now set the cursor the 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. */
-
-       gdk_window_set_cursor( win, cursor.GetCursor() );
-    }
-
-    if (g_delayedFocus == this)
-    {
-        if (GTK_WIDGET_REALIZED(m_widget))
-        {
-            gtk_widget_grab_focus( m_widget );
-            g_delayedFocus = NULL;
-        }
-    }
-
-    if (wxUpdateUIEvent::CanUpdate(this))
-        UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
+    return GTK_BUTTON(m_widget)->event_window;
 }
 
 wxSize wxRadioButton::DoGetBestSize() const
index d0a691baea0d1db8e6f8ba43b97b3a178410f270..f1d1efc384dd28e1aac76e68a132a227f4545280 100644 (file)
@@ -248,10 +248,9 @@ void wxScrollBar::SetRange(int range)
     SetScrollbar(GetThumbPosition(), GetThumbSize(), range, GetPageSize());
 }
 
-bool wxScrollBar::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxScrollBar::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
 {
-    GtkRange *range = GTK_RANGE(m_widget);
-    return ( (window == GTK_WIDGET(range)->window) );
+    return GTK_WIDGET(GTK_RANGE(m_widget))->window;
 }
 
 // static
index 5e8098e47c84ee77c901b60749e153ceb3c6c49d..5cde6b19f657a5f6289e381b427b04937c5e9346 100644 (file)
@@ -401,10 +401,9 @@ int wxSlider::GetLineSize() const
     return int(gtk_range_get_adjustment (GTK_RANGE (m_widget))->step_increment);
 }
 
-bool wxSlider::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxSlider::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
 {
-    GtkRange *range = GTK_RANGE(m_widget);
-    return (range->event_window == window);
+    return GTK_RANGE(m_widget)->event_window;
 }
 
 // static
index 6dbfe5b1072db1efe7e228790889b77bfce6c0c2..25c26b63a02d52409341419ab43c283f0b8221ec 100644 (file)
@@ -176,9 +176,9 @@ void wxSpinButton::OnSize( wxSizeEvent &WXUNUSED(event) )
     gtk_widget_set_size_request( m_widget, m_width, m_height );
 }
 
-bool wxSpinButton::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxSpinButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
 {
-    return GTK_SPIN_BUTTON(m_widget)->panel == window;
+    return GTK_SPIN_BUTTON(m_widget)->panel;
 }
 
 wxSize wxSpinButton::DoGetBestSize() const
index 0e91452d8c05d58555b62c2d121c0c25d9bea81e..2cea9634f589c038764cb583adcd1d9fd106dd1d 100644 (file)
@@ -249,16 +249,20 @@ void wxSpinCtrl::OnChar( wxKeyEvent &event )
     event.Skip();
 }
 
-bool wxSpinCtrl::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxSpinCtrl::GTKGetWindow(wxArrayGdkWindows& windows) const
 {
     GtkSpinButton* spinbutton = GTK_SPIN_BUTTON(m_widget);
-    return window == spinbutton->entry.text_area || window == spinbutton->panel;
+
+    windows.push_back(spinbutton->entry.text_area);
+    windows.push_back(spinbutton->panel);
+
+    return NULL;
 }
 
 wxSize wxSpinCtrl::DoGetBestSize() const
 {
     wxSize ret( wxControl::DoGetBestSize() );
-    wxSize best(95, ret.y);
+    wxSize best(95, ret.y); // FIXME: 95?
     CacheBestSize(best);
     return best;
 }
index 64a6796cb5b683af54f79ba0c9d09f6410610858..59ff4e0486f3efddd0dceec870f9e1b0f10894b0 100644 (file)
 #include "wx/gtk/private.h"
 #include <gdk/gdkkeysyms.h>
 
-//-----------------------------------------------------------------------------
-// data
-//-----------------------------------------------------------------------------
-
-extern wxWindowGTK *g_delayedFocus;
-
 // ----------------------------------------------------------------------------
 // helpers
 // ----------------------------------------------------------------------------
@@ -1547,15 +1541,16 @@ GtkWidget* wxTextCtrl::GetConnectWidget()
     return GTK_WIDGET(m_text);
 }
 
-bool wxTextCtrl::IsOwnGtkWindow( GdkWindow *window )
+GdkWindow *wxTextCtrl::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
 {
     if ( IsMultiLine() )
     {
-        return window == gtk_text_view_get_window( GTK_TEXT_VIEW( m_text ), GTK_TEXT_WINDOW_TEXT );  // pure guesswork
+        return gtk_text_view_get_window(GTK_TEXT_VIEW(m_text),
+                                        GTK_TEXT_WINDOW_TEXT );
     }
     else
     {
-        return (window == GTK_ENTRY(m_text)->text_area);
+        return GTK_ENTRY(m_text)->text_area;
     }
 }
 
@@ -1717,24 +1712,6 @@ void wxTextCtrl::OnUpdateRedo(wxUpdateUIEvent& event)
     event.Enable( CanRedo() );
 }
 
-void wxTextCtrl::OnInternalIdle()
-{
-    // Check if we have to show window now
-    if (GtkShowFromOnIdle()) return;
-
-    if (g_delayedFocus == this)
-    {
-        if (GTK_WIDGET_REALIZED(m_widget))
-        {
-            gtk_widget_grab_focus( m_widget );
-            g_delayedFocus = NULL;
-        }
-    }
-    
-    if (wxUpdateUIEvent::CanUpdate(this))
-        UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
-}
-
 wxSize wxTextCtrl::DoGetBestSize() const
 {
     // FIXME should be different for multi-line controls...
index a7a7b479261dbb0d860a950def367290369f68af..cc2f7db78dd19a801d2604718df237a0954b487e 100644 (file)
@@ -30,7 +30,6 @@
 #include "wx/gtk/private.h"
 
 extern bool      g_blockEventsOnDrag;
-extern wxCursor   g_globalCursor;
 
 extern "C" {
 static void gtk_togglebutton_clicked_callback(GtkWidget *WXUNUSED(widget), wxToggleButton *cb)
@@ -174,37 +173,12 @@ void wxToggleBitmapButton::DoApplyWidgetStyle(GtkRcStyle *style)
     gtk_widget_modify_style(GTK_BIN(m_widget)->child, style);
 }
 
-bool wxToggleBitmapButton::IsOwnGtkWindow(GdkWindow *window)
+GdkWindow *
+wxToggleBitmapButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
 {
-    return window == GTK_BUTTON(m_widget)->event_window;
+    return GTK_BUTTON(m_widget)->event_window;
 }
 
-void wxToggleBitmapButton::OnInternalIdle()
-{
-    // Check if we have to show window now
-    if (GtkShowFromOnIdle()) return;
-    
-    wxCursor cursor = m_cursor;
-
-    if (g_globalCursor.Ok())
-        cursor = g_globalCursor;
-
-    GdkWindow *win = GTK_BUTTON(m_widget)->event_window;
-    if ( win && cursor.Ok() )
-    {
-      /* I now set the cursor the 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. */
-
-        gdk_window_set_cursor(win, cursor.GetCursor());
-    }
-
-    if (wxUpdateUIEvent::CanUpdate(this))
-        UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
-}
-
-
 // Get the "best" size for this control.
 wxSize wxToggleBitmapButton::DoGetBestSize() const
 {
@@ -318,34 +292,12 @@ void wxToggleButton::DoApplyWidgetStyle(GtkRcStyle *style)
     gtk_widget_modify_style(GTK_BIN(m_widget)->child, style);
 }
 
-bool wxToggleButton::IsOwnGtkWindow(GdkWindow *window)
+GdkWindow *
+wxToggleButton::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
 {
-    return window == GTK_BUTTON(m_widget)->event_window;
+    return GTK_BUTTON(m_widget)->event_window;
 }
 
-void wxToggleButton::OnInternalIdle()
-{
-    wxCursor cursor = m_cursor;
-
-    if (g_globalCursor.Ok())
-        cursor = g_globalCursor;
-
-    GdkWindow *win = GTK_BUTTON(m_widget)->event_window;
-    if ( win && cursor.Ok() )
-    {
-      /* I now set the cursor the 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. */
-
-        gdk_window_set_cursor(win, cursor.GetCursor());
-    }
-
-    if (wxUpdateUIEvent::CanUpdate(this))
-        UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
-}
-
-
 // Get the "best" size for this control.
 wxSize wxToggleButton::DoGetBestSize() const
 {
index d94f9f2b0a837231003843c6e9178906a44c4a6d..b5ebaaea800a0633dc38a74dfb50aa0da092edff 100644 (file)
@@ -1406,42 +1406,79 @@ wxWindowGTK *FindWindowForMouseEvent(wxWindowGTK *win, wxCoord& x, wxCoord& y)
     return win;
 }
 
+// ----------------------------------------------------------------------------
+// common event handlers helpers
+// ----------------------------------------------------------------------------
+
+bool wxWindowGTK::GTKCallbackCommonPrologue(GdkEventAny *event) const
+{
+    DEBUG_MAIN_THREAD
+
+    if (g_isIdle)
+        wxapp_install_idle_handler();
+
+    if (!m_hasVMT)
+        return false;
+    if (g_blockEventsOnDrag)
+        return true;
+    if (g_blockEventsOnScroll)
+        return true;
+
+    if (!GTKIsOwnWindow(event->window))
+        return false;
+
+    return true;
+}
+
+// overloads for all GDK event types we use here: we need to have this as
+// GdkEventXXX can't be implicitly cast to GdkEventAny even if it, in fact,
+// derives from it in the sense that the structs have the same layout
+#define wxDEFINE_COMMON_PROLOGUE_OVERLOAD(T)                                  \
+    static bool wxGtkCallbackCommonPrologue(T *event, wxWindowGTK *win)       \
+    {                                                                         \
+        return win->GTKCallbackCommonPrologue((GdkEventAny *)event);          \
+    }
+
+wxDEFINE_COMMON_PROLOGUE_OVERLOAD(GdkEventButton)
+wxDEFINE_COMMON_PROLOGUE_OVERLOAD(GdkEventMotion)
+wxDEFINE_COMMON_PROLOGUE_OVERLOAD(GdkEventCrossing)
+
+#undef wxDEFINE_COMMON_PROLOGUE_OVERLOAD
+
+// send the wxChildFocusEvent and wxFocusEvent, common code of
+// gtk_window_focus_in_callback() and SetFocus()
+static bool DoSendFocusEvents(wxWindow *win)
+{
+    // Notify the parent keeping track of focus for the kbd navigation
+    // purposes that we got it.
+    wxChildFocusEvent eventChildFocus(win);
+    (void)win->GetEventHandler()->ProcessEvent(eventChildFocus);
+
+    wxFocusEvent eventFocus(wxEVT_SET_FOCUS, win->GetId());
+    eventFocus.SetEventObject(win);
+
+    return win->GetEventHandler()->ProcessEvent(eventFocus);
+}
+
+// all event handlers must have C linkage as they're called from GTK+ C code
+extern "C"
+{
+
 //-----------------------------------------------------------------------------
 // "button_press_event"
 //-----------------------------------------------------------------------------
 
-extern "C" {
 static gboolean
 gtk_window_button_press_callback( GtkWidget *widget,
                                   GdkEventButton *gdk_event,
                                   wxWindowGTK *win )
 {
-    DEBUG_MAIN_THREAD
-
-    if (g_isIdle)
-        wxapp_install_idle_handler();
-
-/*
-    wxPrintf( wxT("1) OnButtonPress from ") );
-    if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
-        wxPrintf( win->GetClassInfo()->GetClassName() );
-    wxPrintf( wxT(".\n") );
-*/
-    if (!win->m_hasVMT) return FALSE;
-    if (g_blockEventsOnDrag) return TRUE;
-    if (g_blockEventsOnScroll) return TRUE;
-
-    if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
+    if ( !wxGtkCallbackCommonPrologue(gdk_event, win) )
+        return FALSE;
 
     if (win->m_wxwindow && (g_focusWindow != win) && win->AcceptsFocus())
     {
         gtk_widget_grab_focus( win->m_wxwindow );
-/*
-        wxPrintf( wxT("GrabFocus from ") );
-        if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
-            wxPrintf( win->GetClassInfo()->GetClassName() );
-        wxPrintf( wxT(".\n") );
-*/
     }
 
     // GDK sends surplus button down events
@@ -1599,28 +1636,18 @@ gtk_window_button_press_callback( GtkWidget *widget,
 
     return FALSE;
 }
-}
 
 //-----------------------------------------------------------------------------
 // "button_release_event"
 //-----------------------------------------------------------------------------
 
-extern "C" {
 static gboolean
 gtk_window_button_release_callback( GtkWidget *widget,
                                     GdkEventButton *gdk_event,
                                     wxWindowGTK *win )
 {
-    DEBUG_MAIN_THREAD
-
-    if (g_isIdle)
-        wxapp_install_idle_handler();
-
-    if (!win->m_hasVMT) return FALSE;
-    if (g_blockEventsOnDrag) return FALSE;
-    if (g_blockEventsOnScroll) return FALSE;
-
-    if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
+    if ( !wxGtkCallbackCommonPrologue(gdk_event, win) )
+        return FALSE;
 
     wxEventType event_type = wxEVT_NULL;
 
@@ -1666,28 +1693,18 @@ gtk_window_button_release_callback( GtkWidget *widget,
 
     return FALSE;
 }
-}
 
 //-----------------------------------------------------------------------------
 // "motion_notify_event"
 //-----------------------------------------------------------------------------
 
-extern "C" {
 static gboolean
 gtk_window_motion_notify_callback( GtkWidget *widget,
                                    GdkEventMotion *gdk_event,
                                    wxWindowGTK *win )
 {
-    DEBUG_MAIN_THREAD
-
-    if (g_isIdle)
-        wxapp_install_idle_handler();
-
-    if (!win->m_hasVMT) return FALSE;
-    if (g_blockEventsOnDrag) return FALSE;
-    if (g_blockEventsOnScroll) return FALSE;
-
-    if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
+    if ( !wxGtkCallbackCommonPrologue(gdk_event, win) )
+        return FALSE;
 
     if (gdk_event->is_hint)
     {
@@ -1699,13 +1716,6 @@ gtk_window_motion_notify_callback( GtkWidget *widget,
         gdk_event->y = y;
     }
 
-/*
-    printf( "OnMotion from " );
-    if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
-      printf( win->GetClassInfo()->GetClassName() );
-    printf( ".\n" );
-*/
-
     wxMouseEvent event( wxEVT_MOTION );
     InitMouseEvent(win, event, gdk_event);
 
@@ -1756,13 +1766,11 @@ gtk_window_motion_notify_callback( GtkWidget *widget,
 
     return FALSE;
 }
-}
 
 //-----------------------------------------------------------------------------
 // "scroll_event", (mouse wheel event)
 //-----------------------------------------------------------------------------
 
-extern "C" {
 static gboolean
 window_scroll_event(GtkWidget*, GdkEventScroll* gdk_event, wxWindow* win)
 {
@@ -1804,43 +1812,22 @@ window_scroll_event(GtkWidget*, GdkEventScroll* gdk_event, wxWindow* win)
 
     return win->GetEventHandler()->ProcessEvent(event);
 }
-}
 
 //-----------------------------------------------------------------------------
 // "popup-menu"
 //-----------------------------------------------------------------------------
-extern "C" {
+
 static gboolean wxgtk_window_popup_menu_callback(GtkWidget*, wxWindowGTK* win)
 {
-    wxContextMenuEvent event(
-        wxEVT_CONTEXT_MENU,
-        win->GetId(),
-        wxPoint(-1, -1));
+    wxContextMenuEvent event(wxEVT_CONTEXT_MENU, win->GetId(), wxPoint(-1, -1));
     event.SetEventObject(win);
     return win->GetEventHandler()->ProcessEvent(event);
 }
-}
 
 //-----------------------------------------------------------------------------
 // "focus_in_event"
 //-----------------------------------------------------------------------------
 
-// send the wxChildFocusEvent and wxFocusEvent, common code of
-// gtk_window_focus_in_callback() and SetFocus()
-static bool DoSendFocusEvents(wxWindow *win)
-{
-    // Notify the parent keeping track of focus for the kbd navigation
-    // purposes that we got it.
-    wxChildFocusEvent eventChildFocus(win);
-    (void)win->GetEventHandler()->ProcessEvent(eventChildFocus);
-
-    wxFocusEvent eventFocus(wxEVT_SET_FOCUS, win->GetId());
-    eventFocus.SetEventObject(win);
-
-    return win->GetEventHandler()->ProcessEvent(eventFocus);
-}
-
-extern "C" {
 static gboolean
 gtk_window_focus_in_callback( GtkWidget *widget,
                               GdkEventFocus *WXUNUSED(event),
@@ -1894,13 +1881,11 @@ gtk_window_focus_in_callback( GtkWidget *widget,
 
     return FALSE;
 }
-}
 
 //-----------------------------------------------------------------------------
 // "focus_out_event"
 //-----------------------------------------------------------------------------
 
-extern "C" {
 static gboolean
 gtk_window_focus_out_callback( GtkWidget *widget,
                                GdkEventFocus *gdk_event,
@@ -1961,31 +1946,22 @@ gtk_window_focus_out_callback( GtkWidget *widget,
 
     return FALSE;
 }
-}
 
 //-----------------------------------------------------------------------------
 // "enter_notify_event"
 //-----------------------------------------------------------------------------
 
-extern "C" {
 static gboolean
 gtk_window_enter_callback( GtkWidget *widget,
                            GdkEventCrossing *gdk_event,
                            wxWindowGTK *win )
 {
-    DEBUG_MAIN_THREAD
-
-    if (g_isIdle)
-        wxapp_install_idle_handler();
-
-    if (!win->m_hasVMT) return FALSE;
-    if (g_blockEventsOnDrag) return FALSE;
+    if ( !wxGtkCallbackCommonPrologue(gdk_event, win) )
+        return FALSE;
 
     // Event was emitted after a grab
     if (gdk_event->mode != GDK_CROSSING_NORMAL) return FALSE;
 
-    if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
-
     int x = 0;
     int y = 0;
     GdkModifierType state = (GdkModifierType)0;
@@ -2015,31 +1991,22 @@ gtk_window_enter_callback( GtkWidget *widget,
 
     return FALSE;
 }
-}
 
 //-----------------------------------------------------------------------------
 // "leave_notify_event"
 //-----------------------------------------------------------------------------
 
-extern "C" {
 static gboolean
 gtk_window_leave_callback( GtkWidget *widget,
                            GdkEventCrossing *gdk_event,
                            wxWindowGTK *win )
 {
-    DEBUG_MAIN_THREAD
-
-    if (g_isIdle)
-        wxapp_install_idle_handler();
-
-    if (!win->m_hasVMT) return FALSE;
-    if (g_blockEventsOnDrag) return FALSE;
+    if ( !wxGtkCallbackCommonPrologue(gdk_event, win) )
+        return FALSE;
 
     // Event was emitted after an ungrab
     if (gdk_event->mode != GDK_CROSSING_NORMAL) return FALSE;
 
-    if (!win->IsOwnGtkWindow( gdk_event->window )) return FALSE;
-
     wxMouseEvent event( wxEVT_LEAVE_WINDOW );
     event.SetTimestamp( gdk_event->time );
     event.SetEventObject( win );
@@ -2070,13 +2037,11 @@ gtk_window_leave_callback( GtkWidget *widget,
 
     return FALSE;
 }
-}
 
 //-----------------------------------------------------------------------------
 // "value_changed" from scrollbar
 //-----------------------------------------------------------------------------
 
-extern "C" {
 static void
 gtk_scrollbar_value_changed(GtkRange* range, wxWindow* win)
 {
@@ -2099,13 +2064,11 @@ gtk_scrollbar_value_changed(GtkRange* range, wxWindow* win)
         win->m_blockValueChanged[dir] = false;
     }
 }
-}
 
 //-----------------------------------------------------------------------------
 // "button_press_event" from scrollbar
 //-----------------------------------------------------------------------------
 
-extern "C" {
 static gboolean
 gtk_scrollbar_button_press_event(GtkRange*, GdkEventButton*, wxWindow* win)
 {
@@ -2119,13 +2082,11 @@ gtk_scrollbar_button_press_event(GtkRange*, GdkEventButton*, wxWindow* win)
 
     return false;
 }
-}
 
 //-----------------------------------------------------------------------------
 // "event_after" from scrollbar
 //-----------------------------------------------------------------------------
 
-extern "C" {
 static void
 gtk_scrollbar_event_after(GtkRange* range, GdkEvent* event, wxWindow* win)
 {
@@ -2140,13 +2101,11 @@ gtk_scrollbar_event_after(GtkRange* range, GdkEvent* event, wxWindow* win)
         win->GetEventHandler()->ProcessEvent(event);
     }
 }
-}
 
 //-----------------------------------------------------------------------------
 // "button_release_event" from scrollbar
 //-----------------------------------------------------------------------------
 
-extern "C" {
 static gboolean
 gtk_scrollbar_button_release_event(GtkRange* range, GdkEventButton*, wxWindow* win)
 {
@@ -2166,18 +2125,6 @@ gtk_scrollbar_button_release_event(GtkRange* range, GdkEventButton*, wxWindow* w
 
     return false;
 }
-}
-
-// ----------------------------------------------------------------------------
-// this wxWindowBase function is implemented here (in platform-specific file)
-// because it is static and so couldn't be made virtual
-// ----------------------------------------------------------------------------
-
-wxWindow *wxWindowBase::DoFindFocus()
-{
-    // the cast is necessary when we compile in wxUniversal mode
-    return (wxWindow *)g_focusWindow;
-}
 
 //-----------------------------------------------------------------------------
 // "realize" from m_widget
@@ -2186,7 +2133,6 @@ wxWindow *wxWindowBase::DoFindFocus()
 /* We cannot set colours and fonts before the widget has
    been realized, so we do this directly after realization. */
 
-extern "C" {
 static void
 gtk_window_realized_callback( GtkWidget *m_widget, wxWindow *win )
 {
@@ -2206,13 +2152,11 @@ gtk_window_realized_callback( GtkWidget *m_widget, wxWindow *win )
     event.SetEventObject( win );
     win->GetEventHandler()->ProcessEvent( event );
 }
-}
 
 //-----------------------------------------------------------------------------
 // "size_allocate"
 //-----------------------------------------------------------------------------
 
-extern "C" {
 static
 void gtk_window_size_callback( GtkWidget *WXUNUSED(widget),
                                GtkAllocation *WXUNUSED(alloc),
@@ -2237,7 +2181,6 @@ void gtk_window_size_callback( GtkWidget *WXUNUSED(widget),
         win->GetEventHandler()->ProcessEvent( event );
     }
 }
-}
 
 
 #ifdef HAVE_XIM
@@ -2247,8 +2190,6 @@ void gtk_window_size_callback( GtkWidget *WXUNUSED(widget),
 #endif
 
 /* Resize XIM window */
-
-extern "C" {
 static
 void gtk_wxwindow_size_callback( GtkWidget* WXUNUSED_UNLESS_XIM(widget),
                                  GtkAllocation* WXUNUSED_UNLESS_XIM(alloc),
@@ -2272,7 +2213,6 @@ void gtk_wxwindow_size_callback( GtkWidget* WXUNUSED_UNLESS_XIM(widget),
     }
 #endif // HAVE_XIM
 }
-}
 
 //-----------------------------------------------------------------------------
 // "realize" from m_wxwindow
@@ -2280,7 +2220,6 @@ void gtk_wxwindow_size_callback( GtkWidget* WXUNUSED_UNLESS_XIM(widget),
 
 /* Initialize XIM support */
 
-extern "C" {
 static void
 gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget),
                                 wxWindowGTK * WXUNUSED_UNLESS_XIM(win) )
@@ -2365,6 +2304,18 @@ gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget),
       }
 #endif // HAVE_XIM
 }
+
+} // extern "C"
+
+// ----------------------------------------------------------------------------
+// this wxWindowBase function is implemented here (in platform-specific file)
+// because it is static and so couldn't be made virtual
+// ----------------------------------------------------------------------------
+
+wxWindow *wxWindowBase::DoFindFocus()
+{
+    // the cast is necessary when we compile in wxUniversal mode
+    return (wxWindow *)g_focusWindow;
 }
 
 //-----------------------------------------------------------------------------
@@ -3375,6 +3326,22 @@ void wxWindowGTK::GetTextExtent( const wxString& string,
     g_object_unref (layout);
 }
 
+bool wxWindowGTK::GTKSetDelayedFocusIfNeeded()
+{
+    if ( g_delayedFocus == this )
+    {
+        if ( GTK_WIDGET_REALIZED(m_widget) )
+        {
+            gtk_widget_grab_focus(m_widget);
+            g_delayedFocus = NULL;
+
+            return true;
+        }
+    }
+
+    return false;
+}
+
 void wxWindowGTK::SetFocus()
 {
     wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
@@ -3626,10 +3593,29 @@ bool wxWindowGTK::SetCursor( const wxCursor &cursor )
     if (g_isIdle)
         wxapp_install_idle_handler();
 
-    if (cursor == wxNullCursor)
-       return wxWindowBase::SetCursor( *wxSTANDARD_CURSOR );
-    else
-       return wxWindowBase::SetCursor( cursor );
+    return wxWindowBase::SetCursor( cursor.Ok() ? cursor : *wxSTANDARD_CURSOR );
+}
+
+void wxWindowGTK::GTKUpdateCursor()
+{
+    wxCursor cursor(g_globalCursor.Ok() ? g_globalCursor : GetCursor());
+    if ( cursor.Ok() )
+    {
+        wxArrayGdkWindows windowsThis;
+        GdkWindow * const winThis = GTKGetWindow(windowsThis);
+        if ( winThis )
+        {
+            gdk_window_set_cursor(winThis, cursor.GetCursor());
+        }
+        else
+        {
+            const size_t count = windowsThis.size();
+            for ( size_t n = 0; n < count; n++ )
+            {
+                gdk_window_set_cursor(windowsThis[n], cursor.GetCursor());
+            }
+        }
+    }
 }
 
 void wxWindowGTK::WarpPointer( int x, int y )
@@ -4043,12 +4029,18 @@ GtkWidget* wxWindowGTK::GetConnectWidget()
     return connect_widget;
 }
 
-bool wxWindowGTK::IsOwnGtkWindow( GdkWindow *window )
+bool wxWindowGTK::GTKIsOwnWindow(GdkWindow *window) const
 {
-    if (m_wxwindow)
-        return (window == GTK_PIZZA(m_wxwindow)->bin_window);
+    wxArrayGdkWindows windowsThis;
+    GdkWindow * const winThis = GTKGetWindow(windowsThis);
 
-    return (window == m_widget->window);
+    return winThis ? window == winThis
+                   : windowsThis.Index(window) != wxNOT_FOUND;
+}
+
+GdkWindow *wxWindowGTK::GTKGetWindow(wxArrayGdkWindows& WXUNUSED(windows)) const
+{
+    return m_wxwindow ? GTK_PIZZA(m_wxwindow)->bin_window : m_widget->window;
 }
 
 bool wxWindowGTK::SetFont( const wxFont &font )