GHOST Cocoa: some changes to Y coordinate conversion in previous commit,
to fix continuous grab being broken (bug report #27760).
This commit is contained in:
@@ -272,17 +272,6 @@ protected:
|
|||||||
*/
|
*/
|
||||||
GHOST_TSuccess setMouseCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y);
|
GHOST_TSuccess setMouseCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y);
|
||||||
|
|
||||||
/**
|
|
||||||
* Push cursor event, with coordinate conversion to follow GHOST convention.
|
|
||||||
*/
|
|
||||||
void pushEventCursor(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window, GHOST_TInt32 x, GHOST_TInt32 y);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Push trackpad event, with coordinate conversion to follow GHOST convention.
|
|
||||||
*/
|
|
||||||
void pushEventTrackpad(GHOST_TUns64 msec, GHOST_IWindow* window, GHOST_TTrackpadEventSubTypes subtype,
|
|
||||||
GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 deltaX, GHOST_TInt32 deltaY);
|
|
||||||
|
|
||||||
/** Start time at initialization. */
|
/** Start time at initialization. */
|
||||||
GHOST_TUns64 m_start_time;
|
GHOST_TUns64 m_start_time;
|
||||||
|
|
||||||
|
@@ -806,37 +806,11 @@ GHOST_TSuccess GHOST_SystemCocoa::getCursorPosition(GHOST_TInt32& x, GHOST_TInt3
|
|||||||
return GHOST_kSuccess;
|
return GHOST_kSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GHOST_SystemCocoa::pushEventCursor(GHOST_TUns64 msec, GHOST_TEventType type, GHOST_IWindow* window, GHOST_TInt32 x, GHOST_TInt32 y)
|
|
||||||
{
|
|
||||||
GHOST_Rect cBnds;
|
|
||||||
window->getClientBounds(cBnds);
|
|
||||||
y = (cBnds.getHeight() - 1) - y;
|
|
||||||
|
|
||||||
GHOST_TInt32 screen_x, screen_y;
|
|
||||||
window->clientToScreen(x, y, screen_x, screen_y);
|
|
||||||
|
|
||||||
pushEvent(new GHOST_EventCursor(msec, type, window, screen_x, screen_y));
|
|
||||||
}
|
|
||||||
|
|
||||||
void GHOST_SystemCocoa::pushEventTrackpad(GHOST_TUns64 msec, GHOST_IWindow* window, GHOST_TTrackpadEventSubTypes subtype, GHOST_TInt32 x, GHOST_TInt32 y, GHOST_TInt32 deltaX, GHOST_TInt32 deltaY)
|
|
||||||
{
|
|
||||||
GHOST_Rect cBnds;
|
|
||||||
window->getClientBounds(cBnds);
|
|
||||||
y = (cBnds.getHeight() - 1) - y;
|
|
||||||
deltaY = -deltaY;
|
|
||||||
|
|
||||||
GHOST_TInt32 screen_x, screen_y;
|
|
||||||
window->clientToScreen(x, y, screen_x, screen_y);
|
|
||||||
|
|
||||||
pushEvent(new GHOST_EventTrackpad(msec, window, subtype, screen_x, screen_y, deltaX, deltaY));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @note : expect Cocoa screen coordinates
|
* @note : expect Cocoa screen coordinates
|
||||||
*/
|
*/
|
||||||
GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y)
|
GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y)
|
||||||
{
|
{
|
||||||
GHOST_TInt32 wx,wy;
|
|
||||||
GHOST_WindowCocoa* window = (GHOST_WindowCocoa*)m_windowManager->getActiveWindow();
|
GHOST_WindowCocoa* window = (GHOST_WindowCocoa*)m_windowManager->getActiveWindow();
|
||||||
if (!window) return GHOST_kFailure;
|
if (!window) return GHOST_kFailure;
|
||||||
|
|
||||||
@@ -847,8 +821,7 @@ GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32
|
|||||||
CGAssociateMouseAndMouseCursorPosition(true);
|
CGAssociateMouseAndMouseCursorPosition(true);
|
||||||
|
|
||||||
//Force mouse move event (not pushed by Cocoa)
|
//Force mouse move event (not pushed by Cocoa)
|
||||||
window->screenToClient(x, y, wx, wy);
|
pushEvent(new GHOST_EventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, x, y));
|
||||||
pushEventCursor(getMilliSeconds(), GHOST_kEventCursorMove, window, wx,wy);
|
|
||||||
m_outsideLoopEventProcessed = true;
|
m_outsideLoopEventProcessed = true;
|
||||||
|
|
||||||
return GHOST_kSuccess;
|
return GHOST_kSuccess;
|
||||||
@@ -1460,9 +1433,9 @@ GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr, short eventT
|
|||||||
GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
|
GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
|
||||||
{
|
{
|
||||||
NSEvent *event = (NSEvent *)eventPtr;
|
NSEvent *event = (NSEvent *)eventPtr;
|
||||||
GHOST_Window* window;
|
GHOST_WindowCocoa* window;
|
||||||
|
|
||||||
window = (GHOST_Window*)m_windowManager->getWindowAssociatedWithOSWindow((void*)[event window]);
|
window = (GHOST_WindowCocoa*)m_windowManager->getWindowAssociatedWithOSWindow((void*)[event window]);
|
||||||
if (!window) {
|
if (!window) {
|
||||||
//printf("\nW failure for event 0x%x",[event type]);
|
//printf("\nW failure for event 0x%x",[event type]);
|
||||||
return GHOST_kFailure;
|
return GHOST_kFailure;
|
||||||
@@ -1526,7 +1499,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
|
|||||||
switch (window->getCursorGrabMode()) {
|
switch (window->getCursorGrabMode()) {
|
||||||
case GHOST_kGrabHide: //Cursor hidden grab operation : no cursor move
|
case GHOST_kGrabHide: //Cursor hidden grab operation : no cursor move
|
||||||
{
|
{
|
||||||
GHOST_TInt32 x_warp, y_warp, x_accum, y_accum;
|
GHOST_TInt32 x_warp, y_warp, x_accum, y_accum, x, y;
|
||||||
|
|
||||||
window->getCursorGrabInitPos(x_warp, y_warp);
|
window->getCursorGrabInitPos(x_warp, y_warp);
|
||||||
|
|
||||||
@@ -1535,7 +1508,8 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
|
|||||||
y_accum += -[event deltaY]; //Strange Apple implementation (inverted coordinates for the deltaY) ...
|
y_accum += -[event deltaY]; //Strange Apple implementation (inverted coordinates for the deltaY) ...
|
||||||
window->setCursorGrabAccum(x_accum, y_accum);
|
window->setCursorGrabAccum(x_accum, y_accum);
|
||||||
|
|
||||||
pushEventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, x_warp+x_accum, y_warp+y_accum);
|
window->clientToScreenIntern(x_warp+x_accum, y_warp+y_accum, x, y);
|
||||||
|
pushEvent(new GHOST_EventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, x, y));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GHOST_kGrabWrap: //Wrap cursor at area/window boundaries
|
case GHOST_kGrabWrap: //Wrap cursor at area/window boundaries
|
||||||
@@ -1543,19 +1517,16 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
|
|||||||
NSPoint mousePos = [event locationInWindow];
|
NSPoint mousePos = [event locationInWindow];
|
||||||
GHOST_TInt32 x_mouse= mousePos.x;
|
GHOST_TInt32 x_mouse= mousePos.x;
|
||||||
GHOST_TInt32 y_mouse= mousePos.y;
|
GHOST_TInt32 y_mouse= mousePos.y;
|
||||||
GHOST_TInt32 x_accum, y_accum, x_cur, y_cur;
|
GHOST_TInt32 x_accum, y_accum, x_cur, y_cur, x, y;
|
||||||
GHOST_Rect bounds, windowBounds, correctedBounds;
|
GHOST_Rect bounds, correctedBounds;
|
||||||
|
|
||||||
/* fallback to window bounds */
|
/* fallback to window bounds */
|
||||||
if(window->getCursorGrabBounds(bounds)==GHOST_kFailure)
|
if(window->getCursorGrabBounds(bounds)==GHOST_kFailure)
|
||||||
window->getClientBounds(bounds);
|
window->getClientBounds(bounds);
|
||||||
|
|
||||||
//Switch back to Cocoa coordinates orientation (y=0 at botton,the same as blender internal btw!), and to client coordinates
|
//Switch back to Cocoa coordinates orientation (y=0 at botton,the same as blender internal btw!), and to client coordinates
|
||||||
window->getClientBounds(windowBounds);
|
window->screenToClient(bounds.m_l, bounds.m_b, correctedBounds.m_l, correctedBounds.m_b);
|
||||||
window->screenToClient(bounds.m_l,bounds.m_b, correctedBounds.m_l, correctedBounds.m_t);
|
window->screenToClient(bounds.m_r, bounds.m_t, correctedBounds.m_r, correctedBounds.m_t);
|
||||||
window->screenToClient(bounds.m_r, bounds.m_t, correctedBounds.m_r, correctedBounds.m_b);
|
|
||||||
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
|
//Update accumulation counts
|
||||||
window->getCursorGrabAccum(x_accum, y_accum);
|
window->getCursorGrabAccum(x_accum, y_accum);
|
||||||
@@ -1574,19 +1545,24 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
|
|||||||
m_cursorDelta_y = y_mouse-mousePos.y;
|
m_cursorDelta_y = y_mouse-mousePos.y;
|
||||||
|
|
||||||
//Set new cursor position
|
//Set new cursor position
|
||||||
window->clientToScreen(x_mouse, y_mouse, x_cur, y_cur);
|
window->clientToScreenIntern(x_mouse, y_mouse, x_cur, y_cur);
|
||||||
setMouseCursorPosition(x_cur, y_cur); /* wrap */
|
setMouseCursorPosition(x_cur, y_cur); /* wrap */
|
||||||
|
|
||||||
//Post event
|
//Post event
|
||||||
window->getCursorGrabInitPos(x_cur, y_cur);
|
window->getCursorGrabInitPos(x_cur, y_cur);
|
||||||
pushEventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, x_cur + x_accum, y_cur + y_accum);
|
window->clientToScreenIntern(x_cur + x_accum, y_cur + y_accum, x, y);
|
||||||
|
pushEvent(new GHOST_EventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, x, y));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
//Normal cursor operation: send mouse position in window
|
//Normal cursor operation: send mouse position in window
|
||||||
NSPoint mousePos = [event locationInWindow];
|
NSPoint mousePos = [event locationInWindow];
|
||||||
pushEventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, mousePos.x, mousePos.y);
|
GHOST_TInt32 x, y;
|
||||||
|
|
||||||
|
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_x=0;
|
||||||
m_cursorDelta_y=0; //Mouse motion occurred between two cursor warps, so we can reset the delta counter
|
m_cursorDelta_y=0; //Mouse motion occurred between two cursor warps, so we can reset the delta counter
|
||||||
}
|
}
|
||||||
@@ -1608,6 +1584,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
NSPoint mousePos = [event locationInWindow];
|
NSPoint mousePos = [event locationInWindow];
|
||||||
|
GHOST_TInt32 x, y;
|
||||||
double dx = [event deltaX];
|
double dx = [event deltaX];
|
||||||
double dy = -[event deltaY];
|
double dy = -[event deltaY];
|
||||||
|
|
||||||
@@ -1624,7 +1601,10 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
|
|||||||
if (dy<0.0) dy-=0.5; else dy+=0.5;
|
if (dy<0.0) dy-=0.5; else dy+=0.5;
|
||||||
if (dy< -deltaMax) dy= -deltaMax; else if (dy>deltaMax) dy=deltaMax;
|
if (dy< -deltaMax) dy= -deltaMax; else if (dy>deltaMax) dy=deltaMax;
|
||||||
|
|
||||||
pushEventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventScroll, mousePos.x, mousePos.y, dx, dy);
|
window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
|
||||||
|
dy = -dy;
|
||||||
|
|
||||||
|
pushEvent(new GHOST_EventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventScroll, x, y, dx, dy));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1632,16 +1612,20 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
|
|||||||
case NSEventTypeMagnify:
|
case NSEventTypeMagnify:
|
||||||
{
|
{
|
||||||
NSPoint mousePos = [event locationInWindow];
|
NSPoint mousePos = [event locationInWindow];
|
||||||
pushEventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventMagnify, mousePos.x, mousePos.y,
|
GHOST_TInt32 x, y;
|
||||||
[event magnification]*250.0 + 0.1, 0);
|
window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
|
||||||
|
pushEvent(new GHOST_EventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventMagnify, x, y,
|
||||||
|
[event magnification]*250.0 + 0.1, 0));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NSEventTypeRotate:
|
case NSEventTypeRotate:
|
||||||
{
|
{
|
||||||
NSPoint mousePos = [event locationInWindow];
|
NSPoint mousePos = [event locationInWindow];
|
||||||
pushEventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventRotate, mousePos.x, mousePos.y,
|
GHOST_TInt32 x, y;
|
||||||
-[event rotation] * 5.0, 0);
|
window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
|
||||||
|
pushEvent(new GHOST_EventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventRotate, x, y,
|
||||||
|
-[event rotation] * 5.0, 0));
|
||||||
}
|
}
|
||||||
case NSEventTypeBeginGesture:
|
case NSEventTypeBeginGesture:
|
||||||
m_isGestureInProgress = true;
|
m_isGestureInProgress = true;
|
||||||
|
@@ -180,6 +180,26 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
|
virtual void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a point in screen coordinates to client rectangle coordinates
|
||||||
|
* but without the y coordinate conversion needed for ghost compatibility.
|
||||||
|
* @param inX The x-coordinate in the client rectangle.
|
||||||
|
* @param inY The y-coordinate in the client rectangle.
|
||||||
|
* @param outX The x-coordinate on the screen.
|
||||||
|
* @param outY The y-coordinate on the screen.
|
||||||
|
*/
|
||||||
|
void clientToScreenIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a point in screen coordinates to client rectangle coordinates,
|
||||||
|
* but without the y coordinate conversion needed for ghost compatibility.
|
||||||
|
* @param inX The x-coordinate in the client rectangle.
|
||||||
|
* @param inY The y-coordinate in the client rectangle.
|
||||||
|
* @param outX The x-coordinate on the screen.
|
||||||
|
* @param outY The y-coordinate on the screen.
|
||||||
|
*/
|
||||||
|
void screenToClientIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the screen the window is displayed in
|
* Gets the screen the window is displayed in
|
||||||
* @return The NSScreen object
|
* @return The NSScreen object
|
||||||
|
@@ -691,17 +691,8 @@ GHOST_TWindowState GHOST_WindowCocoa::getState() const
|
|||||||
void GHOST_WindowCocoa::screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
|
void GHOST_WindowCocoa::screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
|
||||||
{
|
{
|
||||||
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::screenToClient(): window invalid")
|
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::screenToClient(): window invalid")
|
||||||
|
|
||||||
NSPoint screenCoord;
|
screenToClientIntern(inX, inY, outX, outY);
|
||||||
NSPoint baseCoord;
|
|
||||||
|
|
||||||
screenCoord.x = inX;
|
|
||||||
screenCoord.y = inY;
|
|
||||||
|
|
||||||
baseCoord = [m_window convertScreenToBase:screenCoord];
|
|
||||||
|
|
||||||
outX = baseCoord.x;
|
|
||||||
outY = baseCoord.y;
|
|
||||||
|
|
||||||
/* switch y to match ghost convention */
|
/* switch y to match ghost convention */
|
||||||
GHOST_Rect cBnds;
|
GHOST_Rect cBnds;
|
||||||
@@ -718,7 +709,26 @@ void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST
|
|||||||
GHOST_Rect cBnds;
|
GHOST_Rect cBnds;
|
||||||
getClientBounds(cBnds);
|
getClientBounds(cBnds);
|
||||||
inY = (cBnds.getHeight() - 1) - inY;
|
inY = (cBnds.getHeight() - 1) - inY;
|
||||||
|
|
||||||
|
clientToScreenIntern(inX, inY, outX, outY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GHOST_WindowCocoa::screenToClientIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
|
||||||
|
{
|
||||||
|
NSPoint screenCoord;
|
||||||
|
NSPoint baseCoord;
|
||||||
|
|
||||||
|
screenCoord.x = inX;
|
||||||
|
screenCoord.y = inY;
|
||||||
|
|
||||||
|
baseCoord = [m_window convertScreenToBase:screenCoord];
|
||||||
|
|
||||||
|
outX = baseCoord.x;
|
||||||
|
outY = baseCoord.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GHOST_WindowCocoa::clientToScreenIntern(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
|
||||||
|
{
|
||||||
NSPoint screenCoord;
|
NSPoint screenCoord;
|
||||||
NSPoint baseCoord;
|
NSPoint baseCoord;
|
||||||
|
|
||||||
@@ -1220,7 +1230,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode
|
|||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
|
|
||||||
m_systemCocoa->getCursorPosition(x_old,y_old);
|
m_systemCocoa->getCursorPosition(x_old,y_old);
|
||||||
screenToClient(x_old, y_old, m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
|
screenToClientIntern(x_old, y_old, m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
|
||||||
//Warp position is stored in client (window base) coordinates
|
//Warp position is stored in client (window base) coordinates
|
||||||
setCursorGrabAccum(0, 0);
|
setCursorGrabAccum(0, 0);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user