X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fmswin%2Ffg_menu_mswin.c;h=33b59ba6f6e20a64ca4d7afebe60cf2465a24e25;hb=91cac2f34bfc430f6a68ea950cc8f5169327b794;hp=a5afd46b128319fd3a8ae9e7060fedfa58373f3c;hpb=af4474129987c478bad43ff0b4f44c2470298a8d;p=freeglut diff --git a/src/mswin/fg_menu_mswin.c b/src/mswin/fg_menu_mswin.c index a5afd46..33b59ba 100644 --- a/src/mswin/fg_menu_mswin.c +++ b/src/mswin/fg_menu_mswin.c @@ -29,7 +29,9 @@ #include #include "../fg_internal.h" -extern void fghGetClientArea( RECT *clientRect, const SFG_Window *window ); + +extern void fgEnumMenus( FGCBMenuEnumerator enumCallback, SFG_Enumerator* enumerator ); + GLvoid fgPlatformGetGameModeVMaxExtent( SFG_Window* window, int* x, int* y ) @@ -38,46 +40,57 @@ GLvoid fgPlatformGetGameModeVMaxExtent( SFG_Window* window, int* x, int* y ) *y = glutGet ( GLUT_SCREEN_HEIGHT ); } -void fgPlatformCheckMenuDeactivate() +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) { - /* If we have an open menu, see if the open menu should be closed - * when focus was lost because user either switched - * application or FreeGLUT window (if one is running multiple - * windows). If so, close menu the active menu. + /* 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 ( fgStructure.Menus.First ) - menu = fgGetActiveMenu(); - - if ( menu ) + if ( fgState.ActiveMenus ) { - SFG_Window* wnd = NULL; - HWND hwnd = GetFocus(); /* Get window with current focus - NULL for non freeglut windows */ - if (hwnd) - /* See which of our windows it is */ - wnd = fgWindowByHandle(hwnd); - - if (!hwnd || !wnd) - /* User switched to another application*/ - fgDeactivateMenu(menu->ParentWindow); - else if (!wnd->IsMenu) /* Make sure we don't kill the menu when trying to enter a submenu */ + /* 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 ) { - if (wnd!=menu->ParentWindow) - /* User switched to another FreeGLUT window */ - fgDeactivateMenu(menu->ParentWindow); - else + /* 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) { - /* Check if focus lost because non-client area of - * window was pressed (pressing on client area is - * handled in fgCheckActiveMenu) - */ - POINT mouse_pos; - RECT clientArea; - fghGetClientArea(&clientArea,menu->ParentWindow); - GetCursorPos(&mouse_pos); - if ( !PtInRect( &clientArea, mouse_pos ) ) - fgDeactivateMenu(menu->ParentWindow); + /* focus shifted to another window than the menu's parent, close menus */ + fgDeactivateMenu(menu->ParentWindow); + return; } } }