be more careful about closing menus when focus changes. Only do so when new focus window is not ANY of the open menus and when it is not the menu's parent window (all open menus are guaranteed to have the same parent in my reading of the code)

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: https://svn.code.sf.net/p/freeglut/code/trunk@1716 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
dcnieho 2014-10-16 17:43:22 +00:00
parent f16d04cfd1
commit 3bd2a31b9a
3 changed files with 51 additions and 12 deletions

View File

@ -568,7 +568,7 @@ static void fghcbGetActiveMenu( SFG_Menu *menu,
if ( enumerator->found ) if ( enumerator->found )
return; return;
/* Check the menu's ID. */ /* Check the menu's is active */
if( menu->IsActive ) if( menu->IsActive )
{ {
enumerator->found = GL_TRUE; 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. * 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... * This is easier than fgWindowByXXX as all menus are placed in one doubly linked list...
*/ */
SFG_Menu* fgGetActiveMenu( ) SFG_Menu* fgGetActiveMenu( )

View File

@ -1759,8 +1759,8 @@ void fgPlatformVisibilityWork(SFG_Window* window)
win = win->Parent; win = win->Parent;
break; break;
case DesireNormalState: case DesireNormalState:
if (win->IsMenu && (!fgStructure.GameModeWindow || win->ActiveMenu->ParentWindow != fgStructure.GameModeWindow)) if (win->IsMenu && !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... */ 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 else
cmdShow = SW_SHOW; cmdShow = SW_SHOW;
break; break;

View File

@ -30,6 +30,9 @@
#include "../fg_internal.h" #include "../fg_internal.h"
extern void fgEnumMenus( FGCBMenuEnumerator enumCallback, SFG_Enumerator* enumerator );
GLvoid fgPlatformGetGameModeVMaxExtent( SFG_Window* window, int* x, int* y ) 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 ); *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) void fgPlatformCheckMenuDeactivate(HWND newFocusWnd)
{ {
/* User/system switched application focus. /* User/system switched application focus.
* If we have an open menu, close it. * 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_Menu* menu = NULL;
SFG_Enumerator enumerator;
if ( fgState.ActiveMenus ) if ( fgState.ActiveMenus )
menu = fgGetActiveMenu();
if ( menu )
{ {
if (newFocusWnd != menu->Window->Window.Handle) /* see if there is an active menu whose window matches the one that got focus */
/* When in GameMode, the menu's parent window will lose focus when the menu is opened. enumerator.found = GL_FALSE;
* This is sadly necessary as we need to do an activating ShowWindow() for the menu enumerator.data = (void*) newFocusWnd;
* to pop up over the gamemode window fgEnumMenus(fghcbIsActiveMenu, &enumerator);
*/ if (enumerator.found)
fgDeactivateMenu(menu->ParentWindow); 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;
}
}
} }
}; };