Fix [#25480] Unable to use Windows titlebar icons after Loopcut
authorNathan Letwory <nathan@letworyinteractive.com>
Fri, 18 Mar 2011 21:59:45 +0000 (21:59 +0000)
committerNathan Letwory <nathan@letworyinteractive.com>
Fri, 18 Mar 2011 21:59:45 +0000 (21:59 +0000)
reported by Georg K
with patch [#26469] Windows mouse fix
by Alexander Kuznetsov

The amount of mouse grabs wasn't properly balanced with ungrabs, thus preventing from using proper mouse input outside client area.

intern/ghost/intern/GHOST_SystemWin32.cpp
intern/ghost/intern/GHOST_WindowWin32.cpp
intern/ghost/intern/GHOST_WindowWin32.h

index db6956de7402786826edf24ac2c3d619806c15a0..dc16711b532979355ce7b4d282313b0364e50af1 100644 (file)
@@ -862,19 +862,19 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
                                // Mouse events, processed
                                ////////////////////////////////////////////////////////////////////////
                                case WM_LBUTTONDOWN:
-                                       window->registerMouseClickEvent(true);
+                                       window->registerMouseClickEvent(0);
                                        event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskLeft);
                                        break;
                                case WM_MBUTTONDOWN:
-                                       window->registerMouseClickEvent(true);
+                                       window->registerMouseClickEvent(0);
                                        event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskMiddle);
                                        break;
                                case WM_RBUTTONDOWN:
-                                       window->registerMouseClickEvent(true);
+                                       window->registerMouseClickEvent(0);
                                        event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskRight);
                                        break;
                                case WM_XBUTTONDOWN:
-                                       window->registerMouseClickEvent(true);
+                                       window->registerMouseClickEvent(0);
                                        if ((short) HIWORD(wParam) == XBUTTON1){
                                                event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskButton4);
                                        }else if((short) HIWORD(wParam) == XBUTTON2){
@@ -882,19 +882,19 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
                                        }
                                        break;
                                case WM_LBUTTONUP:
-                                       window->registerMouseClickEvent(false);
+                                       window->registerMouseClickEvent(1);
                                        event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft);
                                        break;
                                case WM_MBUTTONUP:
-                                       window->registerMouseClickEvent(false);
+                                       window->registerMouseClickEvent(1);
                                        event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskMiddle);
                                        break;
                                case WM_RBUTTONUP:
-                                       window->registerMouseClickEvent(false);
+                                       window->registerMouseClickEvent(1);
                                        event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskRight);
                                        break;
                                case WM_XBUTTONUP:
-                                       window->registerMouseClickEvent(false);
+                                       window->registerMouseClickEvent(1);
                                        if ((short) HIWORD(wParam) == XBUTTON1){
                                                event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskButton4);
                                        }else if((short) HIWORD(wParam) == XBUTTON2){
index 9e3ae0f8d4c9f74ce5c24ae894b00fe30749f392..0a660161cded6cae120772301a10b4e43267d2ef 100644 (file)
@@ -125,6 +125,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(
        m_hDC(0),
        m_hGlRc(0),
        m_hasMouseCaptured(false),
+       m_hasGrabMouse(false),
        m_nPressedButtons(0),
        m_customCursor(0),
        m_wintab(NULL),
@@ -831,28 +832,34 @@ GHOST_TSuccess GHOST_WindowWin32::removeDrawingContext()
 
 void GHOST_WindowWin32::lostMouseCapture()
 {
-       if (m_hasMouseCaptured) {
-               m_hasMouseCaptured = false;
-               m_nPressedButtons = 0;
-       }
+       if(m_hasMouseCaptured)
+               {       m_hasGrabMouse = false;
+                       m_nPressedButtons = 0;
+                       m_hasMouseCaptured = false;
+               };
 }
 
-void GHOST_WindowWin32::registerMouseClickEvent(bool press)
+void GHOST_WindowWin32::registerMouseClickEvent(int press)
 {
-       if (press) {
-               if (!m_hasMouseCaptured) {
+
+       switch(press)
+       {
+               case 0: m_nPressedButtons++;    break;
+               case 1: if(m_nPressedButtons)   m_nPressedButtons--; break;
+               case 2: m_hasGrabMouse=true;    break;
+               case 3: m_hasGrabMouse=false;   break;
+       }
+
+       if(!m_nPressedButtons && !m_hasGrabMouse && m_hasMouseCaptured)
+       {
+                       ::ReleaseCapture();
+                       m_hasMouseCaptured = false;
+       }
+       else if((m_nPressedButtons || m_hasGrabMouse) && !m_hasMouseCaptured)
+       {
                        ::SetCapture(m_hWnd);
                        m_hasMouseCaptured = true;
-               }
-               m_nPressedButtons++;
-       } else {
-               if (m_nPressedButtons) {
-                       m_nPressedButtons--;
-                       if (!m_nPressedButtons) {
-                               ::ReleaseCapture();
-                               m_hasMouseCaptured = false;
-                       }
-               }
+
        }
 }
 
@@ -924,7 +931,7 @@ GHOST_TSuccess GHOST_WindowWin32::setWindowCursorGrab(GHOST_TGrabCursorMode mode
                        if(mode == GHOST_kGrabHide)
                                setWindowCursorVisibility(false);
                }
-               registerMouseClickEvent(true);
+               registerMouseClickEvent(2);
        }
        else {
                if (m_cursorGrab==GHOST_kGrabHide) {
@@ -943,7 +950,7 @@ GHOST_TSuccess GHOST_WindowWin32::setWindowCursorGrab(GHOST_TGrabCursorMode mode
                /* 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 */
-               registerMouseClickEvent(false);
+               registerMouseClickEvent(3);
        }
        
        return GHOST_kSuccess;
index 42cb25f1542c583e393c981e677583f6ad8e1e20..20212bbc2afd6d45f86dcbbe2981929ababcc5bc 100644 (file)
@@ -251,9 +251,13 @@ public:
         * for any real button press, controls mouse
         * capturing).
         *
-        * @param press True the event was a button press.
+        * @param press 
+        *              0 - mouse pressed
+        *              1 - mouse released
+        *              2 - operator grab
+        *              3 - operator ungrab
         */
-       void registerMouseClickEvent(bool press);
+       void registerMouseClickEvent(int press);
 
        /**
         * Inform the window that it has lost mouse capture,
@@ -342,6 +346,9 @@ protected:
        static HDC s_firstHDC;
        /** Flag for if window has captured the mouse */
        bool m_hasMouseCaptured;
+       /** Flag if an operator grabs the mouse with WM_cursor_grab/ungrab() 
+        * Multiple grabs must be realesed with a single ungrab*/
+       bool m_hasGrabMouse;
        /** Count of number of pressed buttons */
        int m_nPressedButtons;
        /** HCURSOR structure of the custom cursor */