error in checking if mouse is in window when opening menu...
[freeglut] / src / fg_menu.c
index 4f8e1a6..0247a88 100644 (file)
@@ -76,7 +76,7 @@ static float menu_pen_hback [4] = FREEGLUT_MENU_PEN_HBACK_COLORS;
 
 
 extern GLvoid fgPlatformGetGameModeVMaxExtent( SFG_Window* window, int* x, int* y );
-extern void fghPlatformGetCursorPos(SFG_XYUse *mouse_pos);
+extern void fghPlatformGetCursorPos(const SFG_Window *window, GLboolean client, SFG_XYUse *mouse_pos);
 
 /* -- PRIVATE FUNCTIONS ---------------------------------------------------- */
 
@@ -534,7 +534,7 @@ static void fghActivateMenu( SFG_Window* window, int button )
      * origin when looking at a child window
      * for parent windows: window->State.MouseX + glutGet( GLUT_WINDOW_X ) == mouse_pos.X
      */
-    fghPlatformGetCursorPos(&mouse_pos);
+    fghPlatformGetCursorPos(NULL, GL_FALSE, &mouse_pos);
     menu->X = mouse_pos.X;
     menu->Y = mouse_pos.Y;
 
@@ -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.MouseY<window->State.Height)
+        {
+            /* XXX Posting a requisite Redisplay seems bogus. */
+            window->State.Redisplay = GL_TRUE;
+            fghActivateMenu( window, button );
+            return GL_TRUE;
+        }
     }
 
     return GL_FALSE;
@@ -679,6 +687,7 @@ GLboolean fgCheckActiveMenu ( SFG_Window *window, int button, GLboolean pressed,
 /*
  * Deactivates a menu pointed by the function argument.
  */
+static SFG_Menu* menuDeactivating = NULL;
 void fgDeactivateMenu( SFG_Window *window )
 {
     SFG_Window *parent_window = NULL;
@@ -690,6 +699,10 @@ void fgDeactivateMenu( SFG_Window *window )
     /* Check if there is an active menu attached to this window... */
     menu = window->ActiveMenu;
     freeglut_return_if_fail( menu );
+    /* Check if we are already deactivating this menu, abort in that case (glutHideWindow below can cause this function to be called again on the same menu..) */
+    if (menu==menuDeactivating)
+        return;
+    menuDeactivating = menu;
 
     parent_window = menu->ParentWindow;
 
@@ -717,6 +730,8 @@ void fgDeactivateMenu( SFG_Window *window )
         if( menuEntry->SubMenu )
             fghDeactivateSubMenu( menuEntry );
     }
+    /* Done deactivating menu */
+    menuDeactivating = NULL;
 
     fgSetWindow ( parent_window ) ;
 
@@ -729,12 +744,9 @@ void fgDeactivateMenu( SFG_Window *window )
             fgState.MenuStateCallback(GLUT_MENU_NOT_IN_USE);
         if (fgState.MenuStatusCallback)
         {
-            /* Get cursor position on screen and convert to relative to parent_window's client area */
+            /* Get cursor position relative to parent_window's client area */
             SFG_XYUse mouse_pos;
-            fghPlatformGetCursorPos(&mouse_pos);
-            
-            mouse_pos.X -= glutGet( GLUT_WINDOW_X );
-            mouse_pos.Y -= glutGet( GLUT_WINDOW_Y );
+            fghPlatformGetCursorPos(parent_window, GL_TRUE, &mouse_pos);
 
             fgState.MenuStatusCallback(GLUT_MENU_NOT_IN_USE, mouse_pos.X, mouse_pos.Y);
         }