forked from bartvdbraak/blender
Cocoa : Bug fix for continuous grab feature implementation
This commit is contained in:
parent
638ed7d0a8
commit
1234f4709b
@ -812,9 +812,9 @@ GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32
|
|||||||
//Quartz Display Services uses the old coordinates (top left origin)
|
//Quartz Display Services uses the old coordinates (top left origin)
|
||||||
yf = [[NSScreen mainScreen] frame].size.height -yf;
|
yf = [[NSScreen mainScreen] frame].size.height -yf;
|
||||||
|
|
||||||
CGAssociateMouseAndMouseCursorPosition(false);
|
//CGAssociateMouseAndMouseCursorPosition(false);
|
||||||
CGWarpMouseCursorPosition(CGPointMake(xf, yf));
|
CGWarpMouseCursorPosition(CGPointMake(xf, yf));
|
||||||
CGAssociateMouseAndMouseCursorPosition(true);
|
//CGAssociateMouseAndMouseCursorPosition(true);
|
||||||
|
|
||||||
return GHOST_kSuccess;
|
return GHOST_kSuccess;
|
||||||
}
|
}
|
||||||
@ -1151,7 +1151,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
|
|||||||
|
|
||||||
window->getCursorWarpAccum(x_accum, y_accum);
|
window->getCursorWarpAccum(x_accum, y_accum);
|
||||||
x_accum += [event deltaX];
|
x_accum += [event deltaX];
|
||||||
y_accum += [event deltaY];
|
y_accum += -[event deltaY]; //Strange Apple implementation (inverted coordinates for the deltaY) ...
|
||||||
window->setCursorWarpAccum(x_accum, y_accum);
|
window->setCursorWarpAccum(x_accum, y_accum);
|
||||||
|
|
||||||
pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, x_warp+x_accum, y_warp+y_accum));
|
pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, x_warp+x_accum, y_warp+y_accum));
|
||||||
@ -1159,6 +1159,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
|
|||||||
else { //Normal cursor operation: send mouse position in window
|
else { //Normal cursor operation: send mouse position in window
|
||||||
NSPoint mousePos = [event locationInWindow];
|
NSPoint mousePos = [event locationInWindow];
|
||||||
pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, mousePos.x, mousePos.y));
|
pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, mousePos.x, mousePos.y));
|
||||||
|
window->setCursorWarpAccum(0, 0); //Mouse motion occured between two cursor warps, so we can reset the delta counter
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -236,6 +236,11 @@ protected:
|
|||||||
*/
|
*/
|
||||||
virtual GHOST_TSuccess setWindowCursorVisibility(bool visible);
|
virtual GHOST_TSuccess setWindowCursorVisibility(bool visible);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the cursor warp accumulator. Overriden for workaround due to Cocoa next event after cursor set giving delta values non zero
|
||||||
|
*/
|
||||||
|
inline virtual bool setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the cursor grab on the window using
|
* Sets the cursor grab on the window using
|
||||||
* native window system calls.
|
* native window system calls.
|
||||||
|
@ -712,18 +712,33 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible)
|
|||||||
return GHOST_kSuccess;
|
return GHOST_kSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Override this method to provide set feature even if not in warp
|
||||||
|
inline bool GHOST_WindowCocoa::setCursorWarpAccum(GHOST_TInt32 x, GHOST_TInt32 y)
|
||||||
|
{
|
||||||
|
m_cursorWarpAccumPos[0]= x;
|
||||||
|
m_cursorWarpAccumPos[1]= y;
|
||||||
|
|
||||||
|
return GHOST_kSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(bool grab, bool warp, bool restore)
|
GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(bool grab, bool warp, bool restore)
|
||||||
{
|
{
|
||||||
|
printf("\ncursor grab %i",grab);
|
||||||
if (grab)
|
if (grab)
|
||||||
{
|
{
|
||||||
|
//No need to perform grab without warp as it is always on in OS X
|
||||||
if(warp) {
|
if(warp) {
|
||||||
m_systemCocoa->getCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]);
|
GHOST_TInt32 x_old,y_old;
|
||||||
|
|
||||||
setCursorWarpAccum(0, 0);
|
|
||||||
setWindowCursorVisibility(false);
|
|
||||||
m_cursorWarp= true;
|
m_cursorWarp= true;
|
||||||
|
m_systemCocoa->getCursorPosition(x_old,y_old);
|
||||||
|
screenToClient(x_old, y_old, m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]);
|
||||||
|
//Warp position is stored in client (window base) coordinates
|
||||||
|
setWindowCursorVisibility(false);
|
||||||
|
return CGAssociateMouseAndMouseCursorPosition(false) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure;
|
||||||
}
|
}
|
||||||
return CGAssociateMouseAndMouseCursorPosition(false) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(m_cursorWarp)
|
if(m_cursorWarp)
|
||||||
@ -732,34 +747,37 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(bool grab, bool warp, bool
|
|||||||
/* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
|
/* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
|
||||||
if(restore) {
|
if(restore) {
|
||||||
GHOST_Rect bounds;
|
GHOST_Rect bounds;
|
||||||
GHOST_TInt32 x_new, y_new, x_rel, y_rel;
|
GHOST_TInt32 x_new, y_new, x_cur, y_cur;
|
||||||
|
|
||||||
getClientBounds(bounds);
|
getClientBounds(bounds);
|
||||||
printf("\ncursor ungrab with restore");
|
|
||||||
x_new= m_cursorWarpInitPos[0]+m_cursorWarpAccumPos[0];
|
x_new= m_cursorWarpInitPos[0]+m_cursorWarpAccumPos[0];
|
||||||
y_new= m_cursorWarpInitPos[1]+m_cursorWarpAccumPos[1];
|
y_new= m_cursorWarpInitPos[1]+m_cursorWarpAccumPos[1];
|
||||||
|
|
||||||
screenToClient(x_new, y_new, x_rel, y_rel);
|
if(x_new < 0) x_new = 0;
|
||||||
|
if(y_new < 0) y_new = 0;
|
||||||
|
if(x_new > bounds.getWidth()) x_new = bounds.getWidth();
|
||||||
|
if(y_new > bounds.getHeight()) y_new = bounds.getHeight();
|
||||||
|
|
||||||
if(x_rel < 0) x_new = (x_new-x_rel) + 2;
|
//get/set cursor position works in screen coordinates
|
||||||
if(y_rel < 0) y_new = (y_new-y_rel) + 2;
|
clientToScreen(x_new, y_new, x_cur, y_cur);
|
||||||
if(x_rel > bounds.getWidth()) x_new -= (x_rel-bounds.getWidth()) + 2;
|
m_systemCocoa->setCursorPosition(x_cur, y_cur);
|
||||||
if(y_rel > bounds.getHeight()) y_new -= (y_rel-bounds.getHeight()) + 2;
|
|
||||||
|
|
||||||
clientToScreen(x_new, y_new, x_rel, y_rel);
|
|
||||||
m_systemCocoa->setCursorPosition(x_rel, y_rel);
|
|
||||||
|
|
||||||
|
//As Cocoa will give as first deltaX,deltaY this change in cursor position, we need to compensate for it
|
||||||
|
//Issue appearing in case of two transform operations conducted w/o mouse motion in between
|
||||||
|
x_new=m_cursorWarpAccumPos[0];
|
||||||
|
y_new=m_cursorWarpAccumPos[1];
|
||||||
|
setCursorWarpAccum(-x_new, -y_new);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_systemCocoa->setCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]);
|
m_systemCocoa->setCursorPosition(m_cursorWarpInitPos[0], m_cursorWarpInitPos[1]);
|
||||||
|
setCursorWarpAccum(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
setCursorWarpAccum(0, 0);
|
|
||||||
m_cursorWarp= false;
|
m_cursorWarp= false;
|
||||||
|
return CGAssociateMouseAndMouseCursorPosition(true) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure;
|
||||||
}
|
}
|
||||||
return CGAssociateMouseAndMouseCursorPosition(true) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure;
|
|
||||||
}
|
}
|
||||||
|
return GHOST_kSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor shape)
|
GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor shape)
|
||||||
|
Loading…
Reference in New Issue
Block a user