be more careful about closing menus when focus changes. Only do so when new focus...
authorDiederick Niehorster <dcnieho@gmail.com>
Thu, 16 Oct 2014 17:43:22 +0000 (17:43 +0000)
committerDiederick Niehorster <dcnieho@gmail.com>
Thu, 16 Oct 2014 17:43:22 +0000 (17:43 +0000)
Also simplified situation in which menus are SW_SHOWed... if a gamemode window is open, it must the parent of any active windows as there can be no other windows open on top of the gamemode window.

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

src/fg_structure.c
src/mswin/fg_main_mswin.c
src/mswin/fg_menu_mswin.c

index 2a65b69..8e1b966 100644 (file)
@@ -568,7 +568,7 @@ static void fghcbGetActiveMenu( SFG_Menu *menu,
     if ( enumerator->found )
         return;
 
-    /* Check the menu's ID. */
+    /* Check the menu's is active */
     if( menu->IsActive )
     {
         enumerator->found = GL_TRUE;
@@ -580,6 +580,7 @@ static void fghcbGetActiveMenu( SFG_Menu *menu,
 
 /*
  * Returns active menu, if any. Assumption: only one menu active throughout application at any one time.
+ * This is false when a submenu is also open.
  * This is easier than fgWindowByXXX as all menus are placed in one doubly linked list...
  */
 SFG_Menu* fgGetActiveMenu( )
index 137fc06..55280f1 100644 (file)
@@ -1759,8 +1759,8 @@ void fgPlatformVisibilityWork(SFG_Window* window)
             win = win->Parent;
         break;
     case DesireNormalState:
-        if (win->IsMenu && (!fgStructure.GameModeWindow || win->ActiveMenu->ParentWindow != fgStructure.GameModeWindow))
-            cmdShow = SW_SHOWNA;    /* Just show, don't activate window if its a menu. Only exception is when the parent is a gamemode window as the menu would pop under it when we do this... */
+        if (win->IsMenu && !fgStructure.GameModeWindow)
+            cmdShow = SW_SHOWNA;    /* Just show, don't activate window if its a menu. Only exception is when there is a gamemode window as the menu would pop under it when we do this... */
         else
             cmdShow = SW_SHOW;
         break;
index 93c538e..33b59ba 100644 (file)
@@ -30,6 +30,9 @@
 #include "../fg_internal.h"
 
 
+extern void fgEnumMenus( FGCBMenuEnumerator enumCallback, SFG_Enumerator* enumerator );
+
+
 
 GLvoid fgPlatformGetGameModeVMaxExtent( SFG_Window* window, int* x, int* y )
 {
@@ -37,24 +40,59 @@ GLvoid fgPlatformGetGameModeVMaxExtent( SFG_Window* window, int* x, int* y )
     *y = glutGet ( GLUT_SCREEN_HEIGHT );
 }
 
+static void fghcbIsActiveMenu(SFG_Menu *menu,
+    SFG_Enumerator *enumerator)
+{
+    if (enumerator->found)
+        return;
+
+    /* Check the menu's active and the one we are searching for. */
+    if (menu->IsActive && menu->Window->Window.Handle==(HWND)enumerator->data)
+    {
+        enumerator->found = GL_TRUE;
+        enumerator->data  = (void*) menu;
+        return;
+    }
+}
+
 void fgPlatformCheckMenuDeactivate(HWND newFocusWnd)
 {
     /* User/system switched application focus.
      * If we have an open menu, close it.
+     * If the window that got focus is an active
+     * menu window, don't do anything. This occurs
+     * as it is sadly necessary to do an activating
+     * ShowWindow() for the menu to pop up over the
+     * gamemode window.
+     * If the window that got focus is the gamemode
+     * window, the menus pop under it. Bring them
+     * back in view in this special case.
      */
     SFG_Menu* menu = NULL;
+    SFG_Enumerator enumerator;
 
     if ( fgState.ActiveMenus )
-        menu = fgGetActiveMenu();
-
-    if ( menu )
     {
-        if (newFocusWnd != menu->Window->Window.Handle)
-            /* When in GameMode, the menu's parent window will lose focus when the menu is opened.
-             * This is sadly necessary as we need to do an activating ShowWindow() for the menu
-             * to pop up over the gamemode window
-             */
-            fgDeactivateMenu(menu->ParentWindow);
+        /* see if there is an active menu whose window matches the one that got focus */
+        enumerator.found = GL_FALSE;
+        enumerator.data  = (void*) newFocusWnd;
+        fgEnumMenus(fghcbIsActiveMenu, &enumerator);
+        if (enumerator.found)
+            menu = (SFG_Menu*) enumerator.data;
+
+        if ( !menu )
+        {
+            /* window that got focus was not one of the active menus. That means we'll
+             * close the active menu's unless the window that got focus was their parent */
+            menu = fgGetActiveMenu();
+            
+            if (newFocusWnd != menu->ParentWindow->Window.Handle)
+            {
+                /* focus shifted to another window than the menu's parent, close menus */
+                fgDeactivateMenu(menu->ParentWindow);
+                return;
+            }
+        }
     }
 };