Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intern/ghost/GHOST_C-api.h11
-rw-r--r--intern/ghost/GHOST_IWindow.h8
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp8
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp15
-rw-r--r--intern/ghost/intern/GHOST_Window.cpp15
-rw-r--r--intern/ghost/intern/GHOST_Window.h16
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp15
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.h9
-rw-r--r--source/blender/editors/interface/interface_handlers.c3
-rw-r--r--source/blender/windowmanager/WM_api.h1
-rw-r--r--source/blender/windowmanager/intern/wm_cursors.c5
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c10
12 files changed, 112 insertions, 4 deletions
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index c3158214830..c0b7077fb53 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -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.
***************************************************************************************/
diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h
index 0861d8b8946..a05e014dc4f 100644
--- a/intern/ghost/GHOST_IWindow.h
+++ b/intern/ghost/GHOST_IWindow.h
@@ -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_
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 401dba8d240..5c23b6c42a3 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -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,
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index a975322e9ce..fcf78d9ad20 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -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:
diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp
index a35680d1586..dee890830a1 100644
--- a/intern/ghost/intern/GHOST_Window.cpp
+++ b/intern/ghost/intern/GHOST_Window.cpp
@@ -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)) {
diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h
index 06318613b14..43744b70be2 100644
--- a/intern/ghost/intern/GHOST_Window.h
+++ b/intern/ghost/intern/GHOST_Window.h
@@ -167,6 +167,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;
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index 2cc30aaa5bc..1525b4eb16d 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -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
){
diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h
index 1392e2c19a6..6f8940bdcbb 100644
--- a/intern/ghost/intern/GHOST_WindowX11.h
+++ b/intern/ghost/intern/GHOST_WindowX11.h
@@ -250,6 +250,15 @@ protected:
);
/**
+ * 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.
*/
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 7ad422ef3b5..ee86b612332 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -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);
}
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index ff3a2feb521..7fe98488ec0 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -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);
diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c
index 9b64ad6d38c..5ddd8f5a1a9 100644
--- a/source/blender/windowmanager/intern/wm_cursors.c
+++ b/source/blender/windowmanager/intern/wm_cursors.c
@@ -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)
{
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index b5d51ef650b..5bcbf526460 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -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);