From 1541ee20c87fe5b981b81ab3add6fa0df29e91d1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 22 Sep 2012 13:23:12 +0000 Subject: Improvement to own commit r50810. Add an optional ghost argument to set the new mouse location when un-grabbing. - without this the mouse would flicker at the old location before moving to the new location - when using the color picker for eg. --- intern/ghost/GHOST_C-api.h | 3 ++- intern/ghost/GHOST_IWindow.h | 2 +- intern/ghost/intern/GHOST_C-api.cpp | 14 ++++++++++++-- intern/ghost/intern/GHOST_Window.cpp | 10 +++++++++- intern/ghost/intern/GHOST_Window.h | 2 +- source/blender/editors/interface/interface_handlers.c | 13 ++++++++++--- source/blender/windowmanager/WM_api.h | 4 ++-- source/blender/windowmanager/intern/wm_cursors.c | 13 ++++++++----- source/blender/windowmanager/intern/wm_event_system.c | 4 ++-- 9 files changed, 47 insertions(+), 18 deletions(-) diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h index ae30458a5e5..87ab3c013c6 100644 --- a/intern/ghost/GHOST_C-api.h +++ b/intern/ghost/GHOST_C-api.h @@ -387,11 +387,12 @@ extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle, * \param windowhandle The handle to the window * \param mode The new grab state of the cursor. * \param bounds The grab ragion (optional) - left,top,right,bottom + * \param mouse_ungrab_xy XY for new mouse location (optional) - x,y * \return Indication of success. */ extern GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, GHOST_TGrabCursorMode mode, - int *bounds); + int bounds[4], int mouse_ungrab_xy[2]); /*************************************************************************************** * Access to mouse button and keyboard states. diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h index a1a1acfca75..7ec6417ca4f 100644 --- a/intern/ghost/GHOST_IWindow.h +++ b/intern/ghost/GHOST_IWindow.h @@ -303,7 +303,7 @@ public: * \param grab The new grab state of the cursor. * \return Indication of success. */ - virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds) { return GHOST_kSuccess; } + virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds, GHOST_TInt32 mouse_ungrab_xy[2]) { return GHOST_kSuccess; } #ifdef WITH_CXX_GUARDEDALLOC MEM_CXX_CLASS_ALLOC_FUNCS("GHOST:GHOST_IWindow") diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp index 0a4325930d5..88d02c46f61 100644 --- a/intern/ghost/intern/GHOST_C-api.cpp +++ b/intern/ghost/intern/GHOST_C-api.cpp @@ -355,10 +355,11 @@ GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle, GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, GHOST_TGrabCursorMode mode, - int *bounds) + int bounds[4], int mouse_ungrab_xy[2]) { GHOST_IWindow *window = (GHOST_IWindow *) windowhandle; GHOST_Rect bounds_rect, bounds_win; + GHOST_TInt32 mouse_ungrab_xy_global[2]; if (bounds) { /* if this is X11 specific we need a function that converts */ @@ -368,7 +369,16 @@ GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle, } - return window->setCursorGrab(mode, bounds ? &bounds_rect : NULL); + 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]); + } + + return window->setCursorGrab(mode, + bounds ? &bounds_rect : NULL, + mouse_ungrab_xy ? mouse_ungrab_xy_global : NULL); } diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp index eb80a073b44..fd3ff4f85f0 100644 --- a/intern/ghost/intern/GHOST_Window.cpp +++ b/intern/ghost/intern/GHOST_Window.cpp @@ -38,6 +38,7 @@ #include "GHOST_Window.h" +#include GHOST_Window::GHOST_Window( GHOST_TUns32 width, GHOST_TUns32 height, @@ -105,11 +106,18 @@ GHOST_TSuccess GHOST_Window::setCursorVisibility(bool visible) } } -GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds) +GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds, GHOST_TInt32 mouse_ungrab_xy[2]) { if (m_cursorGrab == mode) return GHOST_kSuccess; + /* override with new location */ + if (mouse_ungrab_xy) { + assert(mode == GHOST_kGrabDisable); + m_cursorGrabInitPos[0] = mouse_ungrab_xy[0]; + m_cursorGrabInitPos[1] = mouse_ungrab_xy[1]; + } + if (setWindowCursorGrab(mode)) { if (mode == GHOST_kGrabDisable) diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h index fe21b91b991..fd870327fd4 100644 --- a/intern/ghost/intern/GHOST_Window.h +++ b/intern/ghost/intern/GHOST_Window.h @@ -178,7 +178,7 @@ public: * \param mode The new grab state of the cursor. * \return Indication of success. */ - virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds); + virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds, GHOST_TInt32 mouse_ungrab_xy[2]); /** * Gets the cursor grab region, if unset the window is used. diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 0da029f1363..a1f6b4bbd38 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -5372,14 +5372,21 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s else if (data->state == BUTTON_STATE_NUM_EDITING) { ui_numedit_end(but, data); if (ui_is_a_warp_but(but)) { - WM_cursor_grab_disable(CTX_wm_window(C)); - /* XXX, you can see that the cursor is revealed, then moved - should do at once */ #ifdef USE_CONT_MOUSE_CORRECT if (data->ungrab_mval[0] != FLT_MAX) { + int mouse_ungrab_xy[2]; ui_block_to_window_fl(data->region, but->block, &data->ungrab_mval[0], &data->ungrab_mval[1]); - WM_cursor_warp(CTX_wm_window(C), data->ungrab_mval[0], data->ungrab_mval[1]); + mouse_ungrab_xy[0] = data->ungrab_mval[0]; + mouse_ungrab_xy[1] = data->ungrab_mval[1]; + + WM_cursor_grab_disable(data->window, mouse_ungrab_xy); + } + else { + WM_cursor_grab_disable(data->window, NULL); } +#else + WM_cursor_grab_disable(data->window, ); #endif } } diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 0ef94f3db61..9570638fb25 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -114,8 +114,8 @@ void WM_cursor_set (struct wmWindow *win, int curs); void WM_cursor_modal (struct wmWindow *win, int curs); void WM_cursor_restore (struct wmWindow *win); void WM_cursor_wait (int val); -void WM_cursor_grab_enable(struct wmWindow *win, int wrap, int hide, int *bounds); -void WM_cursor_grab_disable(struct wmWindow *win); +void WM_cursor_grab_enable(struct wmWindow *win, int wrap, int hide, int bounds[4]); +void WM_cursor_grab_disable(struct wmWindow *win, int mouse_ungrab_xy[2]); void WM_cursor_time (struct wmWindow *win, int nr); void *WM_paint_cursor_activate(struct wmWindowManager *wm, diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c index 6fc6a57ade1..7853b40c98a 100644 --- a/source/blender/windowmanager/intern/wm_cursors.c +++ b/source/blender/windowmanager/intern/wm_cursors.c @@ -179,7 +179,10 @@ void WM_cursor_wait(int val) } } -void WM_cursor_grab_enable(wmWindow *win, int wrap, int hide, int *bounds) +/** + * \param bounds can be NULL + */ +void WM_cursor_grab_enable(wmWindow *win, int wrap, int hide, int bounds[4]) { /* Only grab cursor when not running debug. * It helps not to get a stuck WM when hitting a breakpoint @@ -193,20 +196,20 @@ void WM_cursor_grab_enable(wmWindow *win, int wrap, int hide, int *bounds) const GHOST_TabletData *tabletdata = GHOST_GetTabletData(win->ghostwin); /* Note: There is no tabletdata on Windows if no tablet device is connected. */ if (!tabletdata) - GHOST_SetCursorGrab(win->ghostwin, mode, bounds); + GHOST_SetCursorGrab(win->ghostwin, mode, bounds, NULL); else if (tabletdata->Active == GHOST_kTabletModeNone) - GHOST_SetCursorGrab(win->ghostwin, mode, bounds); + GHOST_SetCursorGrab(win->ghostwin, mode, bounds, NULL); win->grabcursor = mode; } } } -void WM_cursor_grab_disable(wmWindow *win) +void WM_cursor_grab_disable(wmWindow *win, int mouse_ungrab_xy[2]) { if ((G.debug & G_DEBUG) == 0) { if (win && win->ghostwin) { - GHOST_SetCursorGrab(win->ghostwin, GHOST_kGrabDisable, NULL); + GHOST_SetCursorGrab(win->ghostwin, GHOST_kGrabDisable, NULL, mouse_ungrab_xy); win->grabcursor = GHOST_kGrabDisable; } } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 17f17baba0e..c05d9532f74 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1202,7 +1202,7 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers) CTX_wm_region_set(C, region); } - WM_cursor_grab_disable(CTX_wm_window(C)); + WM_cursor_grab_disable(CTX_wm_window(C), NULL); WM_operator_free(handler->op); } else if (handler->ui_remove) { @@ -1432,7 +1432,7 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand /* remove modal handler, operator itself should have been canceled and freed */ if (retval & (OPERATOR_CANCELLED | OPERATOR_FINISHED)) { - WM_cursor_grab_disable(CTX_wm_window(C)); + WM_cursor_grab_disable(CTX_wm_window(C), NULL); BLI_remlink(handlers, handler); wm_event_free_handler(handler); -- cgit v1.2.3