wrap the mouse within the region while grabbing so on release the current view never changes and less likelyhood of loosing the cursor when running blender on 2+ screens. (assuming the 3d view isnt stretched over both)

This commit is contained in:
2009-10-17 19:32:28 +00:00
parent 484bf962c6
commit 69c6a33ba1
14 changed files with 71 additions and 20 deletions

View File

@@ -372,11 +372,13 @@ extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
* events when the mouse is outside the window. X11 only, others
* do this automatically.
* @param windowhandle The handle to the window
* @param grab The new grab state of the cursor.
* @param mode The new grab state of the cursor.
* @param bounds The grab ragion (optional) - left,top,right,bottom
* @return Indication of success.
*/
extern GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
GHOST_TGrabCursorMode mode);
GHOST_TGrabCursorMode mode,
int* bounds);
/***************************************************************************************
** Access to mouse button and keyboard states.

View File

@@ -271,7 +271,7 @@ public:
* @param grab The new grab state of the cursor.
* @return Indication of success.
*/
virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode) { return GHOST_kSuccess; };
virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds) { return GHOST_kSuccess; };
};

View File

@@ -355,11 +355,21 @@ GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
GHOST_TGrabCursorMode mode)
GHOST_TGrabCursorMode mode,
int *bounds)
{
GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
GHOST_Rect bounds_rect, bounds_win;
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);
}
return window->setCursorGrab(mode);
return window->setCursorGrab(mode, bounds ? &bounds_rect:NULL);
}

View File

@@ -395,7 +395,9 @@ GHOST_SystemX11::processEvent(XEvent *xe)
GHOST_TInt32 x_accum, y_accum;
GHOST_Rect bounds;
window->getClientBounds(bounds);
/* fallback to window bounds */
if(window->getCursorGrabBounds(bounds)==GHOST_kFailure)
window->getClientBounds(bounds);
/* could also clamp to screen bounds
* wrap with a window outside the view will fail atm */

View File

@@ -97,12 +97,18 @@ GHOST_TSuccess GHOST_Window::setCursorVisibility(bool visible)
}
}
GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode)
GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds)
{
if(m_cursorGrab == mode)
return GHOST_kSuccess;
if (setWindowCursorGrab(mode)) {
if(mode==GHOST_kGrabDisable)
m_cursorGrabBounds.m_l= m_cursorGrabBounds.m_r= -1;
else if (bounds) {
m_cursorGrabBounds= *bounds;
}
m_cursorGrab = mode;
return GHOST_kSuccess;
}
@@ -111,6 +117,12 @@ GHOST_TSuccess GHOST_Window::setCursorGrab(GHOST_TGrabCursorMode mode)
}
}
GHOST_TSuccess GHOST_Window::getCursorGrabBounds(GHOST_Rect& bounds)
{
bounds= m_cursorGrabBounds;
return (bounds.m_l==-1 && bounds.m_r==-1) ? GHOST_kFailure : GHOST_kSuccess;
}
GHOST_TSuccess GHOST_Window::setCursorShape(GHOST_TStandardCursor cursorShape)
{
if (setWindowCursorShape(cursorShape)) {

View File

@@ -171,10 +171,16 @@ public:
/**
* Sets the cursor grab.
* @param grab The new grab state of the cursor.
* @param mode The new grab state of the cursor.
* @return Indication of success.
*/
virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode);
virtual GHOST_TSuccess setCursorGrab(GHOST_TGrabCursorMode mode, GHOST_Rect *bounds);
/**
* Gets the cursor grab region, if unset the window is used.
* reset when grab is disabled.
*/
virtual GHOST_TSuccess getCursorGrabBounds(GHOST_Rect& bounds);
/**
* Sets the window "modified" status, indicating unsaved changes
@@ -281,6 +287,9 @@ protected:
/** Accumulated offset from m_cursorGrabInitPos. */
GHOST_TInt32 m_cursorGrabAccumPos[2];
/** Wrap the cursor within this region. */
GHOST_Rect m_cursorGrabBounds;
/** The current shape of the cursor */
GHOST_TStandardCursor m_cursorShape;

View File

@@ -1421,6 +1421,7 @@ setWindowCursorGrab(
/* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
setCursorGrabAccum(0, 0);
m_cursorGrabBounds.m_l= m_cursorGrabBounds.m_r= -1; /* disable */
XUngrabPointer(m_display, CurrentTime);
}

View File

@@ -78,6 +78,7 @@
#include "BKE_animsys.h"
#include "BKE_action.h"
#include "BKE_fcurve.h"
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_key.h"
@@ -669,7 +670,7 @@ bAnimListElem *make_new_animlistelem (void *data, short datatype, void *owner, s
* then free the MEM_alloc'd string
*/
if (rna_path) {
ale->key_data= list_find_fcurve(&act->curves, rna_path, 0);
ale->key_data= (void *)list_find_fcurve(&act->curves, rna_path, 0);
MEM_freeN(rna_path);
}
}

View File

@@ -3750,7 +3750,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
/* number editing */
if(state == BUTTON_STATE_NUM_EDITING) {
if(ui_is_a_warp_but(but))
WM_cursor_grab(CTX_wm_window(C), TRUE, TRUE);
WM_cursor_grab(CTX_wm_window(C), TRUE, TRUE, NULL);
ui_numedit_begin(but, data);
} else if(data->state == BUTTON_STATE_NUM_EDITING) {
ui_numedit_end(but, data);

View File

@@ -52,6 +52,7 @@ static void rna_userdef_update(bContext *C, PointerRNA *ptr)
WM_event_add_notifier(C, NC_WINDOW, NULL);
}
#if 0
static void rna_userdef_lmb_select_set(PointerRNA *ptr,int value)
{
UserDef *userdef = (UserDef*)ptr->data;
@@ -64,7 +65,6 @@ static void rna_userdef_lmb_select_set(PointerRNA *ptr,int value)
userdef->flag &= ~USER_LMOUSESELECT;
}
#if 0
static void rna_userdef_rmb_select_set(PointerRNA *ptr,int value)
{
rna_userdef_lmb_select_set(ptr, !value);

View File

@@ -680,8 +680,9 @@ static void rna_def_windowmanager(BlenderRNA *brna)
static void rna_def_keyconfig(BlenderRNA *brna)
{
StructRNA *srna;
FunctionRNA *func;
PropertyRNA *prop, *parm;
// FunctionRNA *func;
// PropertyRNA *parm;
PropertyRNA *prop;
static EnumPropertyItem map_type_items[] = {
{KMI_TYPE_KEYBOARD, "KEYBOARD", 0, "Keyboard", ""},

View File

@@ -76,7 +76,7 @@ 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(struct wmWindow *win, int wrap, int hide);
void WM_cursor_grab(struct wmWindow *win, int wrap, int hide, int *bounds);
void WM_cursor_ungrab(struct wmWindow *win);
void WM_timecursor (struct wmWindow *win, int nr);

View File

@@ -163,26 +163,27 @@ void WM_cursor_wait(int val)
}
}
void WM_cursor_grab(wmWindow *win, int wrap, int hide)
void WM_cursor_grab(wmWindow *win, int wrap, int hide, int *bounds)
{
/* Only grab cursor when not running debug.
* It helps not to get a stuck WM when hitting a breakpoint
* */
GHOST_TGrabCursorMode mode = GHOST_kGrabNormal;
int bounds_arr[4] = {-1, -1, -1, -1}; /* l/t/r/b */
if(hide) mode = GHOST_kGrabHide;
else if(wrap) mode = GHOST_kGrabWrap;
if ((G.f & G_DEBUG) == 0)
if(win)
GHOST_SetCursorGrab(win->ghostwin, mode);
GHOST_SetCursorGrab(win->ghostwin, mode, bounds);
}
void WM_cursor_ungrab(wmWindow *win)
{
if ((G.f & G_DEBUG) == 0)
if(win)
GHOST_SetCursorGrab(win->ghostwin, GHOST_kGrabDisable);
GHOST_SetCursorGrab(win->ghostwin, GHOST_kGrabDisable, NULL);
}
/* afer this you can call restore too */

View File

@@ -463,8 +463,20 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P
else if(retval & OPERATOR_RUNNING_MODAL) {
/* grab cursor during blocking modal ops (X11) */
if(ot->flag & OPTYPE_BLOCKING) {
int warp = (U.uiflag & USER_CONTINUOUS_MOUSE) && ((op->flag & OP_GRAB_POINTER) || (ot->flag & OPTYPE_GRAB_POINTER));
WM_cursor_grab(CTX_wm_window(C), warp, FALSE);
int bounds[4] = {-1,-1,-1,-1};
int wrap = (U.uiflag & USER_CONTINUOUS_MOUSE) && ((op->flag & OP_GRAB_POINTER) || (ot->flag & OPTYPE_GRAB_POINTER));
if(wrap) {
ARegion *ar= CTX_wm_region(C);
if(ar) {
bounds[0]= ar->winrct.xmin;
bounds[1]= ar->winrct.ymax;
bounds[2]= ar->winrct.xmax;
bounds[3]= ar->winrct.ymin;
}
}
WM_cursor_grab(CTX_wm_window(C), wrap, FALSE, bounds);
}
}
else