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:
@@ -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.
|
||||
|
||||
@@ -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; };
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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", ""},
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user