Fix mouse moved event on OS X when dragging the cursor (close #277)

This commit is contained in:
Marco Antognini 2013-06-28 13:58:54 +02:00
parent f92c0cbe7e
commit 365f7999eb

View File

@ -63,6 +63,13 @@ BOOL isValidTextUnicode(NSEvent* event);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
-(BOOL)isMouseInside; -(BOOL)isMouseInside;
////////////////////////////////////////////////////////////
/// Update the mouse state (in or out) and fire an event
/// if its state has changed.
///
////////////////////////////////////////////////////////////
-(void)updateMouseState;
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Convert the NSEvent mouse button type to SFML type. /// Convert the NSEvent mouse button type to SFML type.
/// ///
@ -204,15 +211,7 @@ BOOL isValidTextUnicode(NSEvent* event);
-(void)frameDidChange:(NSNotification *)notification -(void)frameDidChange:(NSNotification *)notification
{ {
// Update mouse internal state. // Update mouse internal state.
BOOL mouseWasIn = m_mouseIsIn; [self updateMouseState];
m_mouseIsIn = [self isMouseInside];
// Send event if needed.
if (mouseWasIn && !m_mouseIsIn) {
[self mouseExited:nil];
} else if (!mouseWasIn && m_mouseIsIn) {
[self mouseEntered:nil];
}
// Adapt tracking area for mouse mouse event. // Adapt tracking area for mouse mouse event.
[self removeTrackingRect:m_trackingTag]; [self removeTrackingRect:m_trackingTag];
@ -247,6 +246,21 @@ BOOL isValidTextUnicode(NSEvent* event);
} }
////////////////////////////////////////////////////////
-(void)updateMouseState
{
BOOL mouseWasIn = m_mouseIsIn;
m_mouseIsIn = [self isMouseInside];
// Send event if needed.
if (mouseWasIn && !m_mouseIsIn) {
[self mouseExited:nil];
} else if (!mouseWasIn && m_mouseIsIn) {
[self mouseEntered:nil];
}
}
#pragma mark #pragma mark
#pragma mark Subclassing methods #pragma mark Subclassing methods
@ -336,23 +350,40 @@ BOOL isValidTextUnicode(NSEvent* event);
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
-(void)mouseEntered:(NSEvent *)theEvent -(void)mouseEntered:(NSEvent *)theEvent
{ {
// There are two cases when we need to fire an event:
// a) the event is nil, meaning that the method was
// called from our code (e.g. updateMouseState)
// b) the mouse was outside the view.
BOOL shouldFire = (theEvent == nil || m_mouseIsIn == NO);
// Update status
m_mouseIsIn = YES; m_mouseIsIn = YES;
if (m_requester == 0) return; if (m_requester == 0) return;
// Fire (or not) an event
if (shouldFire) {
m_requester->mouseMovedIn(); m_requester->mouseMovedIn();
} }
}
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
-(void)mouseExited:(NSEvent *)theEvent -(void)mouseExited:(NSEvent *)theEvent
{ {
// Similarly to mouseEntered:
BOOL shouldFire = (theEvent == nil || m_mouseIsIn == YES);
// Update status
m_mouseIsIn = NO; m_mouseIsIn = NO;
if (m_requester == 0) return; if (m_requester == 0) return;
// Fire (or not) an event
if (shouldFire) {
m_requester->mouseMovedOut(); m_requester->mouseMovedOut();
} }
}
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
@ -445,13 +476,16 @@ BOOL isValidTextUnicode(NSEvent* event);
-(void)otherMouseDragged:(NSEvent *)theEvent -(void)otherMouseDragged:(NSEvent *)theEvent
{ {
if (m_requester != 0) { if (m_requester != 0) {
// If the event is not useful.
if (!m_mouseIsIn) return;
NSPoint loc = [self cursorPositionFromEvent:theEvent]; NSPoint loc = [self cursorPositionFromEvent:theEvent];
// Make sure the point is inside the view.
// (mouseEntered: and mouseExited: are not immediately called
// when the mouse is dragged. That would be too easy!)
[self updateMouseState];
if (m_mouseIsIn) {
m_requester->mouseMovedAt(loc.x, loc.y); m_requester->mouseMovedAt(loc.x, loc.y);
} }
}
// If the event is not forwarded by mouseDragged or rightMouseDragged... // If the event is not forwarded by mouseDragged or rightMouseDragged...
sf::Mouse::Button button = [self mouseButtonFromEvent:theEvent]; sf::Mouse::Button button = [self mouseButtonFromEvent:theEvent];