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:
parent
f16d04cfd1
commit
3bd2a31b9a
@ -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( )
|
||||||
|
@ -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;
|
||||||
|
@ -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 )
|
||||||
|
{
|
||||||
|
/* 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();
|
menu = fgGetActiveMenu();
|
||||||
|
|
||||||
if ( menu )
|
if (newFocusWnd != menu->ParentWindow->Window.Handle)
|
||||||
{
|
{
|
||||||
if (newFocusWnd != menu->Window->Window.Handle)
|
/* focus shifted to another window than the menu's parent, close menus */
|
||||||
/* 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);
|
fgDeactivateMenu(menu->ParentWindow);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user