]> git.saurik.com Git - wxWidgets.git/commitdiff
Applied patch, fixes #12090: wxGTK cursor handling revamp
authorRobert Roebling <robert@roebling.de>
Wed, 26 May 2010 17:37:55 +0000 (17:37 +0000)
committerRobert Roebling <robert@roebling.de>
Wed, 26 May 2010 17:37:55 +0000 (17:37 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64404 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/gtk/textctrl.h
include/wx/gtk/window.h
src/gtk/control.cpp
src/gtk/cursor.cpp
src/gtk/minifram.cpp
src/gtk/textctrl.cpp
src/gtk/toolbar.cpp
src/gtk/window.cpp

index cdecf127e888f61616b1a999f511933c631dd82a..d17eade8949ba976ca31ac616974065da8e55882 100644 (file)
@@ -217,8 +217,6 @@ private:
 
     // For wxTE_AUTO_URL
     void OnUrlMouseEvent(wxMouseEvent&);
-    GdkCursor *m_gdkHandCursor;
-    GdkCursor *m_gdkXTermCursor;
 
     DECLARE_EVENT_TABLE()
     DECLARE_DYNAMIC_CLASS(wxTextCtrl)
index 61899838853c00ef6ccfdd9ee63891ca3cb1562f..20aa4c181b0f801e64cbc3929ff92eed7b7ab81e 100644 (file)
@@ -279,6 +279,10 @@ public:
     // find the direction of the given scrollbar (must be one of ours)
     ScrollDir ScrollDirFromRange(GtkRange *range) const;
 
+    // set the current cursor for all GdkWindows making part of this widget
+    // (see GTKGetWindow)
+    void GTKUpdateCursor(bool update_self = true, bool recurse = true);
+
     // extra (wxGTK-specific) flags
     bool                 m_noExpose:1;          // wxGLCanvas has its own redrawing
     bool                 m_nativeSizeEvent:1;   // wxGLCanvas sends wxSizeEvent upon "alloc_size"
@@ -357,12 +361,6 @@ 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();
-
     // Connect the given function to the specified signal on m_widget.
     //
     // This is just a wrapper for g_signal_connect() and returns the handler id
index b79878875b33ec6d2fad082dff46b70df6655df0..0191a2f91963ab654f5c73eab6b611b06677ccbb 100644 (file)
@@ -323,11 +323,6 @@ void wxControl::OnInternalIdle()
     if ( GTKShowFromOnIdle() )
         return;
 
-    if ( GTK_WIDGET_REALIZED(m_widget) )
-    {
-        GTKUpdateCursor();
-    }
-
     if ( wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen() )
         UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
 }
index 0dedcab00bc284214fef93b866bb7d4447ef1e1a..6da4ba4d9627544192afd7de209c0ad1532fe994 100644 (file)
@@ -374,7 +374,7 @@ const wxCursor wxBusyCursor::GetBusyCursor()
     return wxCursor(wxCURSOR_WATCH);
 }
 
-static void InternalIdle(const wxWindowList& list, GdkDisplay*& display)
+static void UpdateCursors(const wxWindowList& list, GdkDisplay*& display)
 {
     wxWindowList::const_iterator i = list.begin();
     for (size_t n = list.size(); n--; ++i)
@@ -382,8 +382,8 @@ static void InternalIdle(const wxWindowList& list, GdkDisplay*& display)
         wxWindow* win = *i;
         if (display == NULL && win->m_widget && win->m_widget->window)
             display = gdk_drawable_get_display(win->m_widget->window);
-        win->OnInternalIdle();
-        InternalIdle(win->GetChildren(), display);
+        win->GTKUpdateCursor(true, false);
+        UpdateCursors(win->GetChildren(), display);
     }
 }
 
@@ -395,7 +395,7 @@ void wxEndBusyCursor()
     g_globalCursor = gs_savedCursor;
     gs_savedCursor = wxNullCursor;
     GdkDisplay* unused = NULL;
-    InternalIdle(wxTopLevelWindows, unused);
+    UpdateCursors(wxTopLevelWindows, unused);
 }
 
 void wxBeginBusyCursor(const wxCursor* cursor)
@@ -409,7 +409,7 @@ void wxBeginBusyCursor(const wxCursor* cursor)
     gs_savedCursor = g_globalCursor;
     g_globalCursor = *cursor;
     GdkDisplay* display = NULL;
-    InternalIdle(wxTopLevelWindows, display);
+    UpdateCursors(wxTopLevelWindows, display);
     if (display)
         gdk_display_flush(display);
 }
@@ -422,5 +422,6 @@ bool wxIsBusy()
 void wxSetCursor( const wxCursor& cursor )
 {
     g_globalCursor = cursor;
-    wxTheApp->WakeUpIdle();
+    GdkDisplay* unused = NULL;
+    UpdateCursors(wxTopLevelWindows, unused);
 }
index 386208c34f3a129cb9a91b5a609940551b9d05e2..1e4d289f8ad094432180f9aa6e6edec802e57c57 100644 (file)
@@ -281,6 +281,7 @@ gtk_window_motion_notify_callback( GtkWidget *widget, GdkEventMotion *gdk_event,
                gdk_window_set_cursor( widget->window, gdk_cursor_new( GDK_BOTTOM_RIGHT_CORNER ) );
             else
                gdk_window_set_cursor( widget->window, NULL );
+            win->GTKUpdateCursor(false);
         }
         return TRUE;
     }
index 6a8d22424a41b5dac8af4015337c82f6774befbf..f5a78bdf8d1ac02f480c5259ba70d55574eab6ca 100644 (file)
@@ -622,16 +622,10 @@ void wxTextCtrl::Init()
 
     m_text = NULL;
     m_showPositionOnThaw = NULL;
-    m_gdkHandCursor = NULL;
-    m_gdkXTermCursor = NULL;
 }
 
 wxTextCtrl::~wxTextCtrl()
 {
-    if(m_gdkHandCursor)
-        gdk_cursor_unref(m_gdkHandCursor);
-    if(m_gdkXTermCursor)
-        gdk_cursor_unref(m_gdkXTermCursor);
 }
 
 wxTextCtrl::wxTextCtrl( wxWindow *parent,
@@ -763,8 +757,6 @@ bool wxTextCtrl::Create( wxWindow *parent,
         if (style & wxTE_AUTO_URL)
         {
             GtkTextIter start, end;
-            m_gdkHandCursor = gdk_cursor_new(GDK_HAND2);
-            m_gdkXTermCursor = gdk_cursor_new(GDK_XTERM);
 
             // We create our wxUrl tag here for slight efficiency gain - we
             // don't have to check for the tag existance in callbacks,
@@ -1873,13 +1865,11 @@ void wxTextCtrl::OnUrlMouseEvent(wxMouseEvent& event)
     gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(m_text), &end, x, y);
     if (!gtk_text_iter_has_tag(&end, tag))
     {
-        gdk_window_set_cursor(gtk_text_view_get_window(GTK_TEXT_VIEW(m_text),
-                              GTK_TEXT_WINDOW_TEXT), m_gdkXTermCursor);
+        SetCursor(wxCursor(wxCURSOR_IBEAM));
         return;
     }
 
-    gdk_window_set_cursor(gtk_text_view_get_window(GTK_TEXT_VIEW(m_text),
-                          GTK_TEXT_WINDOW_TEXT), m_gdkHandCursor);
+    SetCursor(wxCursor(wxCURSOR_HAND));
 
     start = end;
     if(!gtk_text_iter_begins_tag(&start, tag))
index df4530d636c1d8134dc1f126a30e0b0164824f16..f8a8cade54e060286e8b70fb5d8d4c82556e379b 100644 (file)
@@ -733,45 +733,6 @@ void wxToolBar::OnInternalIdle()
     // Check if we have to show window now
     if (GTKShowFromOnIdle()) return;
 
-    wxCursor cursor = m_cursor;
-    if (g_globalCursor.Ok()) cursor = g_globalCursor;
-
-    if (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. */
-
-        if (HasFlag(wxTB_DOCKABLE) && (m_widget->window))
-        {
-            /* if the toolbar is dockable, then m_widget stands for the
-               GtkHandleBox widget, which uses its own window so that we
-               can set the cursor for it. if the toolbar is not dockable,
-               m_widget comes from m_toolbar which uses its parent's
-               window ("windowless windows") and thus we cannot set the
-               cursor. */
-            gdk_window_set_cursor( m_widget->window, cursor.GetCursor() );
-        }
-
-        wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
-        while ( node )
-        {
-            wxToolBarTool *tool = (wxToolBarTool *)node->GetData();
-            node = node->GetNext();
-
-            if (tool->m_item)
-            {
-                GdkWindow* window = GTK_WIDGET(tool->m_item)->window;
-
-                if ( window )
-                {
-                    gdk_window_set_cursor( window, cursor.GetCursor() );
-                }
-            }
-        }
-    }
-
     if (wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen())
         UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
 }
index e1b0b87036044c3564ed361f621a55d40f635493..a8b4ad1e46b484788e6d393035f8e87591495c9a 100644 (file)
 
    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.
-
 */
 
 //-----------------------------------------------------------------------------
@@ -2565,38 +2563,6 @@ void wxWindowGTK::OnInternalIdle()
         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 = GTKGetDrawingWindow();
-            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);
 }
@@ -3429,33 +3395,55 @@ bool wxWindowGTK::SetCursor( const wxCursor &cursor )
     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.Ok() ? g_globalCursor : GetCursor());
+        if ( cursor.Ok() )
         {
-            const size_t count = windowsThis.size();
-            for ( size_t n = 0; n < count; n++ )
+            if (m_wxwindow && (m_wxwindow != m_widget))
             {
-                GdkWindow *win = windowsThis[n];
-                if ( !win )
+                wxArrayGdkWindows windowsThis;
+                GdkWindow* window = GTKGetDrawingWindow();
+                if (window)
+                    gdk_window_set_cursor( window, cursor.GetCursor() );
+                else
                 {
-                    wxFAIL_MSG(wxT("NULL window returned by GTKGetWindow()?"));
-                    continue;
+                    const size_t count = windowsThis.size();
+                    for ( size_t n = 0; n < count; n++ )
+                    {
+                        GdkWindow *win = windowsThis[n];
+                        if ( !win )
+                        {
+                            wxFAIL_MSG(wxT("NULL window returned by GTKGetWindow()?"));
+                            continue;
+                        }
+                        gdk_window_set_cursor(win, cursor.GetCursor());
+                    }
                 }
 
-                gdk_window_set_cursor(win, cursor.GetCursor());
+                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 (recurse)
+    {
+        for (wxWindowList::iterator it = GetChildren().begin(); it != GetChildren().end(); ++it)
+        {
+            (*it)->GTKUpdateCursor( true );
+        }
+    }
 }
 
 void wxWindowGTK::WarpPointer( int x, int y )