* Pass on mouse location on window leave/enter too, fixing some
  issues with button highlights and tooltips.
* When a modal operator runs, grab the mouse cursor so that for
  example transform still works when you move your mouse outside
  of the window, previously it would just stop then. This is
  automatic now for all modal ops, perhaps not always needed?
* Fix for a trailing button highlight issue.
This commit is contained in:
Brecht Van Lommel 2009-07-09 16:05:01 +00:00
parent 5e659c0b08
commit b00409e72d
12 changed files with 112 additions and 4 deletions

View File

@ -367,6 +367,17 @@ extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
GHOST_TInt32 x,
GHOST_TInt32 y);
/**
* Grabs the cursor for a modal operation, to keep receiving
* 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.
* @return Indication of success.
*/
extern GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
int grab);
/***************************************************************************************
** Access to mouse button and keyboard states.
***************************************************************************************/

View File

@ -252,6 +252,14 @@ public:
* @return Indication of success.
*/
virtual GHOST_TSuccess setCursorVisibility(bool visible) = 0;
/**
* Grabs the cursor for a modal operation.
* @param grab The new grab state of the cursor.
* @return Indication of success.
*/
virtual GHOST_TSuccess setCursorGrab(bool grab) { printf("?! grab\n"); return GHOST_kSuccess; };
};
#endif // _GHOST_IWINDOW_H_

View File

@ -354,6 +354,14 @@ GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
}
GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
int grab)
{
GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
return window->setCursorGrab(grab?true:false);
}
GHOST_TSuccess GHOST_GetModifierKeyState(GHOST_SystemHandle systemhandle,
GHOST_TModifierKeyMask mask,

View File

@ -550,11 +550,26 @@ GHOST_SystemX11::processEvent(XEvent *xe)
// We're not interested in the following things.(yet...)
case NoExpose :
case GraphicsExpose :
break;
case EnterNotify:
case LeaveNotify:
{
// XCrossingEvents pointer leave enter window.
// also do cursor move here, MotionNotify only
// happens when motion starts & ends inside window
XCrossingEvent &xce = xe->xcrossing;
g_event = new
GHOST_EventCursor(
getMilliSeconds(),
GHOST_kEventCursorMove,
window,
xce.x_root,
xce.y_root
);
break;
}
case MapNotify:
/*
* From ICCCM:

View File

@ -50,6 +50,7 @@ GHOST_Window::GHOST_Window(
:
m_drawingContextType(type),
m_cursorVisible(true),
m_cursorGrabbed(true),
m_cursorShape(GHOST_kStandardCursorDefault),
m_stereoVisual(stereoVisual)
{
@ -93,6 +94,20 @@ GHOST_TSuccess GHOST_Window::setCursorVisibility(bool visible)
}
}
GHOST_TSuccess GHOST_Window::setCursorGrab(bool grab)
{
if(m_cursorGrabbed == grab)
return GHOST_kSuccess;
if (setWindowCursorGrab(grab)) {
m_cursorGrabbed = grab;
return GHOST_kSuccess;
}
else {
return GHOST_kFailure;
}
}
GHOST_TSuccess GHOST_Window::setCursorShape(GHOST_TStandardCursor cursorShape)
{
if (setWindowCursorShape(cursorShape)) {

View File

@ -166,6 +166,13 @@ public:
*/
virtual GHOST_TSuccess setCursorVisibility(bool visible);
/**
* Sets the cursor grab.
* @param grab The new grab state of the cursor.
* @return Indication of success.
*/
virtual GHOST_TSuccess setCursorGrab(bool grab);
/**
* Returns the type of drawing context used in this window.
* @return The current type of drawing context.
@ -218,6 +225,12 @@ protected:
* native window system calls.
*/
virtual GHOST_TSuccess setWindowCursorVisibility(bool visible) = 0;
/**
* Sets the cursor grab on the window using
* native window system calls.
*/
virtual GHOST_TSuccess setWindowCursorGrab(bool grab) = 0;
/**
* Sets the cursor shape on the window using
@ -242,6 +255,9 @@ protected:
/** The current visibility of the cursor */
bool m_cursorVisible;
/** The current grabbed state of the cursor */
bool m_cursorGrabbed;
/** The current shape of the cursor */
GHOST_TStandardCursor m_cursorShape;

View File

@ -1271,6 +1271,21 @@ setWindowCursorVisibility(
GHOST_TSuccess
GHOST_WindowX11::
setWindowCursorGrab(
bool grab
){
if(grab)
XGrabPointer(m_display, m_window, True, ButtonPressMask| ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
else
XUngrabPointer(m_display, CurrentTime);
XFlush(m_display);
return GHOST_kSuccess;
}
GHOST_TSuccess
GHOST_WindowX11::
setWindowCursorShape(
GHOST_TStandardCursor shape
){

View File

@ -249,6 +249,15 @@ protected:
bool visible
);
/**
* Sets the cursor grab on the window using
* native window system calls.
*/
GHOST_TSuccess
setWindowCursorGrab(
bool grab
);
/**
* Sets the cursor shape on the window using
* native window system calls.

View File

@ -3775,8 +3775,7 @@ static void ui_handle_button_return_submenu(bContext *C, wmEvent *event, uiBut *
button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
}
else {
but= ui_but_find_activated(data->region);
if(but) {
if(event->type != MOUSEMOVE) {
but->active->used_mouse= 0;
button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT);
}

View File

@ -65,6 +65,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 val);
void WM_timecursor (struct wmWindow *win, int nr);
void *WM_paint_cursor_activate(struct wmWindowManager *wm, int (*poll)(struct bContext *C), void (*draw)(struct bContext *C, int, int, void *customdata), void *customdata);

View File

@ -156,6 +156,11 @@ void WM_cursor_wait(int val)
}
}
void WM_cursor_grab(wmWindow *win, int val)
{
GHOST_SetCursorGrab(win->ghostwin, val);
}
/* afer this you can call restore too */
void WM_timecursor(wmWindow *win, int nr)
{

View File

@ -378,9 +378,12 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P
else
WM_operator_free(op);
}
else if(!(retval & OPERATOR_RUNNING_MODAL)) {
WM_operator_free(op);
else if(retval & OPERATOR_RUNNING_MODAL) {
/* automatically grab cursor during modal ops (X11) */
WM_cursor_grab(CTX_wm_window(C), 1);
}
else
WM_operator_free(op);
}
return retval;
@ -548,6 +551,7 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers)
}
WM_operator_free(handler->op);
WM_cursor_grab(CTX_wm_window(C), 0);
}
else if(handler->ui_remove) {
ScrArea *area= CTX_wm_area(C);
@ -704,6 +708,8 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand
/* remove modal handler, operator itself should have been cancelled and freed */
if(retval & (OPERATOR_CANCELLED|OPERATOR_FINISHED)) {
WM_cursor_grab(CTX_wm_window(C), 0);
BLI_remlink(handlers, handler);
wm_event_free_handler(handler);