Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2017-07-18 17:00:07 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2017-07-18 17:11:33 +0300
commit8b2785bda5bd077548044acb307e17b376649051 (patch)
tree43038691ad6354bb352c8851accc82a80931f252 /intern/ghost/intern/GHOST_SystemCocoa.mm
parent3cfb248bb6308b7b133956179c1422c0e433acae (diff)
Fix T49498: continuous grab issues on macOS, particularly with gaming mouses.
Change the implementation so it no longer takes over the mouse cursor motion from the OS, instead only move it when warping, similar to Windows and X11. Probably the reason it was not done this way originally is that you then get a 500ms delay after warping, but we can use a trick to avoid that and get much smoother mouse motion than before.
Diffstat (limited to 'intern/ghost/intern/GHOST_SystemCocoa.mm')
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm48
1 files changed, 23 insertions, 25 deletions
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index 173f59c9c8f..4582dfb2a49 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -366,8 +366,6 @@ GHOST_SystemCocoa::GHOST_SystemCocoa()
char *rstring = NULL;
m_modifierMask =0;
- m_cursorDelta_x=0;
- m_cursorDelta_y=0;
m_outsideLoopEventProcessed = false;
m_needDelayedApplicationBecomeActiveEventProcessing = false;
m_displayManager = new GHOST_DisplayManagerCocoa ();
@@ -644,6 +642,13 @@ GHOST_TSuccess GHOST_SystemCocoa::setMouseCursorPosition(GHOST_TInt32 x, GHOST_T
CGDisplayMoveCursorToPoint((CGDirectDisplayID)[[[windowScreen deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue], CGPointMake(xf, yf));
+ // See https://stackoverflow.com/a/17559012. By default, hardware events
+ // will be suppressed for 500ms after a synthetic mouse event. For unknown
+ // reasons CGEventSourceSetLocalEventsSuppressionInterval does not work,
+ // however calling CGAssociateMouseAndMouseCursorPosition also removes the
+ // delay, even if this is undocumented.
+ CGAssociateMouseAndMouseCursorPosition(true);
+
[pool drain];
return GHOST_kSuccess;
}
@@ -1354,9 +1359,8 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
case GHOST_kGrabWrap: //Wrap cursor at area/window boundaries
{
NSPoint mousePos = [cocoawindow mouseLocationOutsideOfEventStream];
- GHOST_TInt32 x_mouse= mousePos.x;
- GHOST_TInt32 y_mouse= mousePos.y;
- GHOST_TInt32 x_accum, y_accum, x_cur, y_cur, x, y;
+ GHOST_TInt32 x_mouse = mousePos.x;
+ GHOST_TInt32 y_mouse = mousePos.y;
GHOST_Rect bounds, windowBounds, correctedBounds;
/* fallback to window bounds */
@@ -1370,29 +1374,26 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
correctedBounds.m_b = (windowBounds.m_b - windowBounds.m_t) - correctedBounds.m_b;
correctedBounds.m_t = (windowBounds.m_b - windowBounds.m_t) - correctedBounds.m_t;
- //Update accumulation counts
+ //Get accumulation from previous mouse warps
+ GHOST_TInt32 x_accum, y_accum;
window->getCursorGrabAccum(x_accum, y_accum);
- x_accum += [event deltaX]-m_cursorDelta_x;
- y_accum += -[event deltaY]-m_cursorDelta_y; //Strange Apple implementation (inverted coordinates for the deltaY) ...
- window->setCursorGrabAccum(x_accum, y_accum);
//Warp mouse cursor if needed
- x_mouse += [event deltaX]-m_cursorDelta_x;
- y_mouse += -[event deltaY]-m_cursorDelta_y;
- correctedBounds.wrapPoint(x_mouse, y_mouse, 2);
-
- //Compensate for mouse moved event taking cursor position set into account
- m_cursorDelta_x = x_mouse-mousePos.x;
- m_cursorDelta_y = y_mouse-mousePos.y;
+ GHOST_TInt32 warped_x_mouse = x_mouse;
+ GHOST_TInt32 warped_y_mouse = y_mouse;
+ correctedBounds.wrapPoint(warped_x_mouse, warped_y_mouse, 4);
//Set new cursor position
- window->clientToScreenIntern(x_mouse, y_mouse, x_cur, y_cur);
- setMouseCursorPosition(x_cur, y_cur); /* wrap */
+ if (x_mouse != warped_x_mouse || y_mouse != warped_y_mouse) {
+ GHOST_TInt32 warped_x, warped_y;
+ window->clientToScreenIntern(warped_x_mouse, warped_y_mouse, warped_x, warped_y);
+ setMouseCursorPosition(warped_x, warped_y); /* wrap */
+ window->setCursorGrabAccum(x_accum + (x_mouse - warped_x_mouse), y_accum + (y_mouse - warped_y_mouse));
+ }
- //Post event
- window->getCursorGrabInitPos(x_cur, y_cur);
- window->screenToClientIntern(x_cur, y_cur, x_cur, y_cur);
- window->clientToScreenIntern(x_cur + x_accum, y_cur + y_accum, x, y);
+ //Generate event
+ GHOST_TInt32 x, y;
+ window->clientToScreenIntern(x_mouse + x_accum, y_mouse + y_accum, x, y);
pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y));
break;
}
@@ -1404,9 +1405,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y));
-
- m_cursorDelta_x=0;
- m_cursorDelta_y=0; //Mouse motion occurred between two cursor warps, so we can reset the delta counter
break;
}
}