When receiving WM_SETFOCUS, check if its child window that should

actually get focus
That fixes corner case issue with menus in main and child windows being
open at the same time


git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1361 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
dcnieho 2012-07-23 07:00:14 +00:00
parent 77ae3c4f4c
commit fc2ee24b1b
3 changed files with 23 additions and 32 deletions

View File

@ -29,6 +29,7 @@
#include <GL/freeglut.h>
#include "fg_internal.h"
/* -- DEFINITIONS ---------------------------------------------------------- */
/*
@ -403,7 +404,7 @@ static void fghDisplayMenuBox( SFG_Menu* menu )
/*
* Private static function to set the parent window of a submenu and all
* of its submenus
* of its submenus.
*/
static void fghSetMenuParentWindow( SFG_Window *window, SFG_Menu *menu )
{
@ -624,27 +625,7 @@ GLboolean fgCheckActiveMenu ( SFG_Window *window, int button, GLboolean pressed,
* is dealt with in the WM_KILLFOCUS handler of fgPlatformWindowProc
*/
{
if (window->ActiveMenu->ParentWindow)
fgDeactivateMenu( window->ActiveMenu->ParentWindow );
else
{
/*
* Its a rare occasion that a window has an ActiveMenu but
* that menus does not have a parent window. It happens
* however in the corner case bug when one opens a menu in
* a main window, then opens a different menu in this main
* window's child (you now have two menus open
* simultaneously, thats the bug) and then click somewhere
* else that causes both menus to close. One of them is
* then not properly cleaned up. This finishes the cleaning
* and minimizes the impact on the user, he only needs one
* extra mouse click.
*/
fghSetMenuParentWindow ( NULL, window->ActiveMenu );
window->ActiveMenu->IsActive = GL_FALSE;
window->ActiveMenu->ActiveEntry = NULL;
window->ActiveMenu = NULL;
}
}
/*
@ -683,10 +664,10 @@ void fgDeactivateMenu( SFG_Window *window )
SFG_Menu* menu;
SFG_MenuEntry *menuEntry;
/* Check if there is an active menu attached to this window... */
freeglut_return_if_fail( window );
menu = window->ActiveMenu;
/* Did we find an active window? */
freeglut_return_if_fail( window );
/* Check if there is an active menu attached to this window... */
menu = window->ActiveMenu;
freeglut_return_if_fail( menu );
parent_window = menu->ParentWindow;
@ -711,7 +692,7 @@ void fgDeactivateMenu( SFG_Window *window )
{
menuEntry->IsActive = GL_FALSE;
/* Is that an active submenu by any case? */
/* Is that an active submenu by any chance? */
if( menuEntry->SubMenu )
fghDeactivateSubMenu( menuEntry );
}

View File

@ -228,6 +228,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
SFG_Window* window;
PAINTSTRUCT ps;
LRESULT lRet = 1;
GLboolean gotChild = GL_FALSE;
FREEGLUT_INTERNAL_ERROR_EXIT_IF_NOT_INITIALISED ( "Event Handler" ) ;
@ -252,7 +253,11 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
ScreenToClient( window->Window.Handle, &mouse_pos );
hwnd = ChildWindowFromPoint(window->Window.Handle, mouse_pos);
if (hwnd) /* can be NULL if mouse outside parent by the time we get here */
{
window = fgWindowByHandle(hwnd);
if (window->Parent)
gotChild = GL_TRUE;
}
}
if ( window )
@ -486,10 +491,16 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
case WM_SETFOCUS:
/* printf("WM_SETFOCUS: %p\n", window ); */
if (gotChild)
/* If child should have focus instead, set it here. */
SetFocus(window->Window.Handle);
lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
INVOKE_WCB( *window, Entry, ( GLUT_ENTERED ) );
UpdateWindow ( hWnd );
if (gotChild)
UpdateWindow ( window->Window.Handle );
break;
case WM_KILLFOCUS:
@ -500,9 +511,9 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
INVOKE_WCB( *window, Entry, ( GLUT_LEFT ) );
/* 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.
* 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.
*/
if ( fgStructure.Menus.First )
menu = fgGetActiveMenu();

View File

@ -808,7 +808,6 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title,
UpdateWindow( window->Window.Handle );
ShowCursor( TRUE ); /* XXX Old comments say "hide cursor"! */
}