]> 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&);
 
     // For wxTE_AUTO_URL
     void OnUrlMouseEvent(wxMouseEvent&);
-    GdkCursor *m_gdkHandCursor;
-    GdkCursor *m_gdkXTermCursor;
 
     DECLARE_EVENT_TABLE()
     DECLARE_DYNAMIC_CLASS(wxTextCtrl)
 
     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;
 
     // 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"
     // 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);
 
     // 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
     // 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 ( GTKShowFromOnIdle() )
         return;
 
-    if ( GTK_WIDGET_REALIZED(m_widget) )
-    {
-        GTKUpdateCursor();
-    }
-
     if ( wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen() )
         UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
 }
     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);
 }
 
     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)
 {
     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);
         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;
     g_globalCursor = gs_savedCursor;
     gs_savedCursor = wxNullCursor;
     GdkDisplay* unused = NULL;
-    InternalIdle(wxTopLevelWindows, unused);
+    UpdateCursors(wxTopLevelWindows, unused);
 }
 
 void wxBeginBusyCursor(const wxCursor* cursor)
 }
 
 void wxBeginBusyCursor(const wxCursor* cursor)
@@ -409,7 +409,7 @@ void wxBeginBusyCursor(const wxCursor* cursor)
     gs_savedCursor = g_globalCursor;
     g_globalCursor = *cursor;
     GdkDisplay* display = NULL;
     gs_savedCursor = g_globalCursor;
     g_globalCursor = *cursor;
     GdkDisplay* display = NULL;
-    InternalIdle(wxTopLevelWindows, display);
+    UpdateCursors(wxTopLevelWindows, display);
     if (display)
         gdk_display_flush(display);
 }
     if (display)
         gdk_display_flush(display);
 }
@@ -422,5 +422,6 @@ bool wxIsBusy()
 void wxSetCursor( const wxCursor& cursor )
 {
     g_globalCursor = cursor;
 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 );
                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;
     }
         }
         return TRUE;
     }
index 6a8d22424a41b5dac8af4015337c82f6774befbf..f5a78bdf8d1ac02f480c5259ba70d55574eab6ca 100644 (file)
@@ -622,16 +622,10 @@ void wxTextCtrl::Init()
 
     m_text = NULL;
     m_showPositionOnThaw = NULL;
 
     m_text = NULL;
     m_showPositionOnThaw = NULL;
-    m_gdkHandCursor = NULL;
-    m_gdkXTermCursor = NULL;
 }
 
 wxTextCtrl::~wxTextCtrl()
 {
 }
 
 wxTextCtrl::~wxTextCtrl()
 {
-    if(m_gdkHandCursor)
-        gdk_cursor_unref(m_gdkHandCursor);
-    if(m_gdkXTermCursor)
-        gdk_cursor_unref(m_gdkXTermCursor);
 }
 
 wxTextCtrl::wxTextCtrl( wxWindow *parent,
 }
 
 wxTextCtrl::wxTextCtrl( wxWindow *parent,
@@ -763,8 +757,6 @@ bool wxTextCtrl::Create( wxWindow *parent,
         if (style & wxTE_AUTO_URL)
         {
             GtkTextIter start, end;
         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,
 
             // 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))
     {
     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;
     }
 
         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))
 
     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;
 
     // 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);
 }
     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
 
    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.
-
 */
 
 //-----------------------------------------------------------------------------
 */
 
 //-----------------------------------------------------------------------------
@@ -2565,38 +2563,6 @@ 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 = 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);
 }
     if (wxUpdateUIEvent::CanUpdate(this) && IsShownOnScreen())
         UpdateWindowUI(wxUPDATE_UI_FROMIDLE);
 }
@@ -3429,33 +3395,55 @@ 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.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 )
 }
 
 void wxWindowGTK::WarpPointer( int x, int y )