Fix wxSetCursorEvent handling

For compatibility with wxMSW, send event up the parent chain.
Properly handle setting the cursor for a wxSetCursorEvent, and don't overwrite the window cursor.
see #15801


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@75821 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Paul Cornett
2014-02-06 08:54:17 +00:00
parent 0dfeb74e78
commit 9d0d2b7e98
2 changed files with 36 additions and 20 deletions

View File

@@ -330,19 +330,23 @@ public:
// find the direction of the given scrollbar (must be one of ours) // find the direction of the given scrollbar (must be one of ours)
ScrollDir ScrollDirFromRange(GtkRange *range) const; ScrollDir ScrollDirFromRange(GtkRange *range) const;
void GTKUpdateCursor(bool isBusyOrGlobalCursor = false, bool isRealize = false); void GTKUpdateCursor(
bool isBusyOrGlobalCursor = false,
bool isRealize = false,
const wxCursor* overrideCursor = NULL);
// extra (wxGTK-specific) flags // extra (wxGTK-specific) flags
bool m_noExpose:1; // wxGLCanvas has its own redrawing bool m_noExpose:1; // wxGLCanvas has its own redrawing
bool m_nativeSizeEvent:1; // wxGLCanvas sends wxSizeEvent upon "alloc_size" bool m_nativeSizeEvent:1; // wxGLCanvas sends wxSizeEvent upon "alloc_size"
bool m_isScrolling:1; // dragging scrollbar thumb? bool m_isScrolling:1; // dragging scrollbar thumb?
bool m_clipPaintRegion:1; // true after ScrollWindow() bool m_clipPaintRegion:1; // true after ScrollWindow()
wxRegion m_nativeUpdateRegion; // not transformed for RTL
bool m_dirtyTabOrder:1; // tab order changed, GTK focus bool m_dirtyTabOrder:1; // tab order changed, GTK focus
// chain needs update // chain needs update
bool m_mouseButtonDown:1; bool m_mouseButtonDown:1;
bool m_showOnIdle:1; // postpone showing the window until idle bool m_showOnIdle:1; // postpone showing the window until idle
bool m_needCursorReset:1;
wxRegion m_nativeUpdateRegion; // not transformed for RTL
protected: protected:
// implement the base class pure virtuals // implement the base class pure virtuals

View File

@@ -1528,6 +1528,25 @@ gtk_window_button_release_callback( GtkWidget *WXUNUSED(widget),
return ret; return ret;
} }
//-----------------------------------------------------------------------------
static void SendSetCursorEvent(wxWindow* win, int x, int y)
{
wxSetCursorEvent event(x, y);
wxWindow* w = win;
do {
if (w->GTKProcessEvent(event))
{
win->GTKUpdateCursor(false, false, &event.GetCursor());
win->m_needCursorReset = true;
return;
}
w = w->GetParent();
} while (w);
if (win->m_needCursorReset)
win->GTKUpdateCursor();
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// "motion_notify_event" // "motion_notify_event"
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -1595,13 +1614,7 @@ gtk_window_motion_notify_callback( GtkWidget * WXUNUSED(widget),
} }
if ( !g_captureWindow ) if ( !g_captureWindow )
{ SendSetCursorEvent(win, event.m_x, event.m_y);
wxSetCursorEvent cevent( event.m_x, event.m_y );
if (win->GTKProcessEvent( cevent ))
{
win->SetCursor( cevent.GetCursor() );
}
}
bool ret = win->GTKProcessEvent(event); bool ret = win->GTKProcessEvent(event);
@@ -1809,13 +1822,7 @@ gtk_window_enter_callback( GtkWidget*,
InitMouseEvent(win, event, gdk_event); InitMouseEvent(win, event, gdk_event);
if ( !g_captureWindow ) if ( !g_captureWindow )
{ SendSetCursorEvent(win, event.m_x, event.m_y);
wxSetCursorEvent cevent( event.m_x, event.m_y );
if (win->GTKProcessEvent( cevent ))
{
win->SetCursor( cevent.GetCursor() );
}
}
return win->GTKProcessEvent(event); return win->GTKProcessEvent(event);
} }
@@ -1831,6 +1838,9 @@ gtk_window_leave_callback( GtkWidget*,
{ {
wxCOMMON_CALLBACK_PROLOGUE(gdk_event, win); wxCOMMON_CALLBACK_PROLOGUE(gdk_event, win);
if (win->m_needCursorReset)
win->GTKUpdateCursor();
// Event was emitted after an ungrab // Event was emitted after an ungrab
if (gdk_event->mode != GDK_CROSSING_NORMAL) return FALSE; if (gdk_event->mode != GDK_CROSSING_NORMAL) return FALSE;
@@ -2235,7 +2245,7 @@ void wxWindowGTK::Init()
m_height = 0; m_height = 0;
m_showOnIdle = false; m_showOnIdle = false;
m_needCursorReset = false;
m_noExpose = false; m_noExpose = false;
m_nativeSizeEvent = false; m_nativeSizeEvent = false;
#ifdef __WXGTK3__ #ifdef __WXGTK3__
@@ -3669,8 +3679,10 @@ bool wxWindowGTK::SetCursor( const wxCursor &cursor )
return true; return true;
} }
void wxWindowGTK::GTKUpdateCursor(bool isBusyOrGlobalCursor, bool isRealize) void wxWindowGTK::GTKUpdateCursor(bool isBusyOrGlobalCursor, bool isRealize, const wxCursor* overrideCursor)
{ {
m_needCursorReset = false;
if (m_widget == NULL || !gtk_widget_get_realized(m_widget)) if (m_widget == NULL || !gtk_widget_get_realized(m_widget))
return; return;
@@ -3688,7 +3700,7 @@ void wxWindowGTK::GTKUpdateCursor(bool isBusyOrGlobalCursor, bool isRealize)
} }
GdkCursor* cursor = NULL; GdkCursor* cursor = NULL;
if (!isBusyOrGlobalCursor) if (!isBusyOrGlobalCursor)
cursor = m_cursor.GetCursor(); cursor = (overrideCursor ? *overrideCursor : m_cursor).GetCursor();
GdkWindow* window = NULL; GdkWindow* window = NULL;
if (cursor || isBusyOrGlobalCursor || !isRealize) if (cursor || isBusyOrGlobalCursor || !isRealize)