Applied patch, fixes #12090: wxGTK cursor handling revamp

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@64404 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
2010-05-26 17:37:55 +00:00
parent 443fbbf7ae
commit c2246a3881
8 changed files with 55 additions and 123 deletions

View File

@@ -183,14 +183,12 @@
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,31 +3395,53 @@ 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 )
wxCursor cursor(g_globalCursor.Ok() ? g_globalCursor : GetCursor());
if ( cursor.Ok() )
{
gdk_window_set_cursor(winThis, cursor.GetCursor());
}
else
{
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 );
}
}
}