now that mouse capture was properly implemented, menus could be opened
authorDiederick Niehorster <dcnieho@gmail.com>
Wed, 27 Feb 2013 11:36:14 +0000 (11:36 +0000)
committerDiederick Niehorster <dcnieho@gmail.com>
Wed, 27 Feb 2013 11:36:14 +0000 (11:36 +0000)
outside the window when the window had capture because another mouse
button was depressed. fixed
Also implemented WM_CANCELMODE, which could be important as we should
cancel capture when it comes in

git-svn-id: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@1526 7f0cb862-5218-0410-a997-914c9d46530a

src/fg_menu.c
src/mswin/fg_main_mswin.c

index e60a5f8..d44c6f4 100644 (file)
@@ -667,10 +667,18 @@ GLboolean fgCheckActiveMenu ( SFG_Window *window, int button, GLboolean pressed,
         ( window->Menu[ button ] ) &&
         pressed )
     {
-        /* XXX Posting a requisite Redisplay seems bogus. */
-        window->State.Redisplay = GL_TRUE;
-        fghActivateMenu( window, button );
-        return GL_TRUE;
+        /* If mouseclick was outside the parent window, ignore. This can
+         * happen when another mouse button is already depressed and the
+         * window thus has mouse capture
+         */
+        if (window->State.MouseX>0 && window->State.MouseY>0 &&
+            window->State.MouseX<window->State.Width && window->State.MouseX<window->State.Height)
+        {
+            /* XXX Posting a requisite Redisplay seems bogus. */
+            window->State.Redisplay = GL_TRUE;
+            fghActivateMenu( window, button );
+            return GL_TRUE;
+        }
     }
 
     return GL_FALSE;
index e4fcce5..baf4b3b 100644 (file)
@@ -361,6 +361,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
 {
     SFG_Window *window;
     LRESULT lRet = 1;
+    static int setCaptureActive = 0;
 
     FREEGLUT_INTERNAL_ERROR_EXIT_IF_NOT_INITIALISED ( "Event Handler" ) ;
 
@@ -623,6 +624,17 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
          */
         return 0;
 
+    case WM_CANCELMODE:
+        /*
+         * The window manager sends this message when it detects a change
+         * that requires that an application cancel any modal state it has
+         * entered. If we've called SetCapture in the mouse button handler,
+         * call ReleaseCapture.
+         */
+        if (setCaptureActive)
+            ReleaseCapture();
+        break;
+
     case WM_MOUSEMOVE:
     {
 #if defined(_WIN32_WCE)
@@ -743,7 +755,11 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
          * This is consistent with the behavior on X11.
          */
         if ( pressed == GL_TRUE )
-          SetCapture ( window->Window.Handle ) ;
+        {
+            if (!setCaptureActive)
+                SetCapture ( window->Window.Handle ) ;
+            setCaptureActive = 1; /* Set to false in WM_CAPTURECHANGED handler */
+        }
         else if (!GetAsyncKeyState(VK_LBUTTON) && !GetAsyncKeyState(VK_MBUTTON) && !GetAsyncKeyState(VK_RBUTTON))
           /* Make sure all mouse buttons are released before releasing capture */
           ReleaseCapture () ;
@@ -864,6 +880,9 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
     break;
 
     case WM_CAPTURECHANGED:
+        if (!lParam || !fgWindowByHandle((HWND)lParam))
+            /* Capture released or capture taken by non-FreeGLUT window */
+            setCaptureActive = 0;
         /* User has finished resizing the window, force a redraw */
         INVOKE_WCB( *window, Display, ( ) );
         lRet = 0;   /* Per docs, should return zero */