diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp index af992bf5a3c..9baa66abad9 100644 --- a/intern/ghost/intern/GHOST_C-api.cpp +++ b/intern/ghost/intern/GHOST_C-api.cpp @@ -358,27 +358,20 @@ GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, int bounds[4], const int mouse_ungrab_xy[2]) { GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; - GHOST_Rect bounds_rect, bounds_win; - GHOST_TInt32 mouse_ungrab_xy_global[2]; + GHOST_Rect bounds_rect; + GHOST_TInt32 mouse_xy[2]; if (bounds) { - /* if this is X11 specific we need a function that converts */ - window->getClientBounds(bounds_win); - window->clientToScreen(bounds[0], bounds_win.getHeight() - bounds[1], bounds_rect.m_l, bounds_rect.m_t); - window->clientToScreen(bounds[2], bounds_win.getHeight() - bounds[3], bounds_rect.m_r, bounds_rect.m_b); - + bounds_rect = GHOST_Rect(bounds[0], bounds[1], bounds[2], bounds[3]); } - if (mouse_ungrab_xy) { - if (bounds == NULL) - window->getClientBounds(bounds_win); - window->clientToScreen(mouse_ungrab_xy[0], bounds_win.getHeight() - mouse_ungrab_xy[1], - mouse_ungrab_xy_global[0], mouse_ungrab_xy_global[1]); + mouse_xy[0] = mouse_ungrab_xy[0]; + mouse_xy[1] = mouse_ungrab_xy[1]; } return window->setCursorGrab(mode, bounds ? &bounds_rect : NULL, - mouse_ungrab_xy ? mouse_ungrab_xy_global : NULL); + mouse_ungrab_xy ? mouse_xy : NULL); } diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index b9686e5af9b..37c2ac12315 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -1317,6 +1317,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) GHOST_TInt32 x_warp, y_warp, x_accum, y_accum, x, y; window->getCursorGrabInitPos(x_warp, y_warp); + window->screenToClientIntern(x_warp, y_warp, x_warp, y_warp); window->getCursorGrabAccum(x_accum, y_accum); x_accum += [event deltaX]; @@ -1368,6 +1369,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr) //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); pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y)); break; diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 9c7b5c3fee7..204d61de3df 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -1463,12 +1463,9 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode if (mode != GHOST_kGrabDisable) { //No need to perform grab without warp as it is always on in OS X if (mode != GHOST_kGrabNormal) { - GHOST_TInt32 x_old,y_old; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - m_systemCocoa->getCursorPosition(x_old,y_old); - screenToClientIntern(x_old, y_old, m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); - //Warp position is stored in client (window base) coordinates + m_systemCocoa->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); setCursorGrabAccum(0, 0); if (mode == GHOST_kGrabHide) { @@ -1486,7 +1483,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode } else { if (m_cursorGrab==GHOST_kGrabHide) { - //No need to set again cursor position, as it has not changed for Cocoa + m_systemCocoa->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]); setWindowCursorVisibility(true); } diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c index d84b65847ca..d9466cbd035 100644 --- a/source/blender/windowmanager/intern/wm_cursors.c +++ b/source/blender/windowmanager/intern/wm_cursors.c @@ -199,14 +199,10 @@ void WM_cursor_grab_enable(wmWindow *win, bool wrap, bool hide, int bounds[4]) * It helps not to get a stuck WM when hitting a breakpoint * */ GHOST_TGrabCursorMode mode = GHOST_kGrabNormal; - float fac = GHOST_GetNativePixelSize(win->ghostwin); - /* in case pixel coords differ from window/mouse coords */ if (bounds) { - bounds[0] /= fac; - bounds[1] /= fac; - bounds[2] /= fac; - bounds[3] /= fac; + wm_cursor_position_to_ghost(win, &bounds[0], &bounds[1]); + wm_cursor_position_to_ghost(win, &bounds[2], &bounds[3]); } if (hide) { @@ -234,7 +230,15 @@ void WM_cursor_grab_disable(wmWindow *win, const int mouse_ungrab_xy[2]) { if ((G.debug & G_DEBUG) == 0) { if (win && win->ghostwin) { - GHOST_SetCursorGrab(win->ghostwin, GHOST_kGrabDisable, NULL, mouse_ungrab_xy); + if (mouse_ungrab_xy) { + int mouse_xy[2] = {mouse_ungrab_xy[0], mouse_ungrab_xy[1]}; + wm_cursor_position_to_ghost(win, &mouse_xy[0], &mouse_xy[1]); + GHOST_SetCursorGrab(win->ghostwin, GHOST_kGrabDisable, NULL, mouse_xy); + } + else { + GHOST_SetCursorGrab(win->ghostwin, GHOST_kGrabDisable, NULL, NULL); + } + win->grabcursor = GHOST_kGrabDisable; } } diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 0b0cedf5825..030399a9c7d 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -676,7 +676,7 @@ int wm_window_fullscreen_toggle_exec(bContext *C, wmOperator *UNUSED(op)) /* ************ events *************** */ -static void wm_convert_cursor_position(wmWindow *win, int *x, int *y) +void wm_cursor_position_from_ghost(wmWindow *win, int *x, int *y) { float fac = GHOST_GetNativePixelSize(win->ghostwin); @@ -687,11 +687,21 @@ static void wm_convert_cursor_position(wmWindow *win, int *x, int *y) *y *= fac; } +void wm_cursor_position_to_ghost(wmWindow *win, int *x, int *y) +{ + float fac = GHOST_GetNativePixelSize(win->ghostwin); + + *x /= fac; + *y /= fac; + *y = win->sizey - *y - 1; + + GHOST_ClientToScreen(win->ghostwin, *x, *y, x, y); +} void wm_get_cursor_position(wmWindow *win, int *x, int *y) { GHOST_GetCursorPosition(g_system, x, y); - wm_convert_cursor_position(win, x, y); + wm_cursor_position_from_ghost(win, x, y); } typedef enum { @@ -1118,7 +1128,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr { GHOST_TEventTrackpadData *pd = data; - wm_convert_cursor_position(win, &pd->x, &pd->y); + wm_cursor_position_from_ghost(win, &pd->x, &pd->y); wm_event_add_ghostevent(wm, win, type, time, data); break; } @@ -1126,7 +1136,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr { GHOST_TEventCursorData *cd = data; - wm_convert_cursor_position(win, &cd->x, &cd->y); + wm_cursor_position_from_ghost(win, &cd->x, &cd->y); wm_event_add_ghostevent(wm, win, type, time, data); break; } @@ -1541,14 +1551,9 @@ void WM_init_native_pixels(bool do_it) void WM_cursor_warp(wmWindow *win, int x, int y) { if (win && win->ghostwin) { - float f = GHOST_GetNativePixelSize(win->ghostwin); int oldx = x, oldy = y; - x = x / f; - y = y / f; - y = win->sizey - y - 1; - - GHOST_ClientToScreen(win->ghostwin, x, y, &x, &y); + wm_cursor_position_to_ghost(win, &x, &y); GHOST_SetCursorPosition(g_system, x, y); win->eventstate->prevx = oldx; diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h index a104f6aba39..8633f297dda 100644 --- a/source/blender/windowmanager/wm_window.h +++ b/source/blender/windowmanager/wm_window.h @@ -64,7 +64,9 @@ bool wm_window_get_swap_interval(wmWindow *win, int *intervalOut); float wm_window_pixelsize(wmWindow *win); -void wm_get_cursor_position (wmWindow *win, int *x, int *y); +void wm_get_cursor_position (wmWindow *win, int *x, int *y); +void wm_cursor_position_from_ghost (wmWindow *win, int *x, int *y); +void wm_cursor_position_to_ghost (wmWindow *win, int *x, int *y); void wm_window_testbreak (void);