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.
This commit is contained in:
Campbell Barton 2012-09-22 13:23:12 +00:00
parent 9bb90f4d85
commit 1541ee20c8
9 changed files with 47 additions and 18 deletions

@ -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.

@ -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")

@ -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);
}

@ -38,6 +38,7 @@
#include "GHOST_Window.h"
#include <assert.h>
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)

@ -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.

@ -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
}
}

@ -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,

@ -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;
}
}

@ -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);