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 <GL/freeglut.h>
#include "fg_internal.h" #include "fg_internal.h"
/* -- DEFINITIONS ---------------------------------------------------------- */ /* -- DEFINITIONS ---------------------------------------------------------- */
/* /*
@ -403,7 +404,7 @@ static void fghDisplayMenuBox( SFG_Menu* menu )
/* /*
* Private static function to set the parent window of a submenu and all * 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 ) 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 * is dealt with in the WM_KILLFOCUS handler of fgPlatformWindowProc
*/ */
{ {
if (window->ActiveMenu->ParentWindow) fgDeactivateMenu( 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_Menu* menu;
SFG_MenuEntry *menuEntry; 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? */ /* 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 ); freeglut_return_if_fail( menu );
parent_window = menu->ParentWindow; parent_window = menu->ParentWindow;
@ -711,7 +692,7 @@ void fgDeactivateMenu( SFG_Window *window )
{ {
menuEntry->IsActive = GL_FALSE; menuEntry->IsActive = GL_FALSE;
/* Is that an active submenu by any case? */ /* Is that an active submenu by any chance? */
if( menuEntry->SubMenu ) if( menuEntry->SubMenu )
fghDeactivateSubMenu( menuEntry ); fghDeactivateSubMenu( menuEntry );
} }

View File

@ -228,6 +228,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
SFG_Window* window; SFG_Window* window;
PAINTSTRUCT ps; PAINTSTRUCT ps;
LRESULT lRet = 1; LRESULT lRet = 1;
GLboolean gotChild = GL_FALSE;
FREEGLUT_INTERNAL_ERROR_EXIT_IF_NOT_INITIALISED ( "Event Handler" ) ; 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 ); ScreenToClient( window->Window.Handle, &mouse_pos );
hwnd = ChildWindowFromPoint(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 */ if (hwnd) /* can be NULL if mouse outside parent by the time we get here */
{
window = fgWindowByHandle(hwnd); window = fgWindowByHandle(hwnd);
if (window->Parent)
gotChild = GL_TRUE;
}
} }
if ( window ) if ( window )
@ -486,10 +491,16 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
case WM_SETFOCUS: case WM_SETFOCUS:
/* printf("WM_SETFOCUS: %p\n", window ); */ /* 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 ); lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
INVOKE_WCB( *window, Entry, ( GLUT_ENTERED ) ); INVOKE_WCB( *window, Entry, ( GLUT_ENTERED ) );
UpdateWindow ( hWnd ); UpdateWindow ( hWnd );
if (gotChild)
UpdateWindow ( window->Window.Handle );
break; break;
case WM_KILLFOCUS: case WM_KILLFOCUS:
@ -500,13 +511,13 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam,
INVOKE_WCB( *window, Entry, ( GLUT_LEFT ) ); INVOKE_WCB( *window, Entry, ( GLUT_LEFT ) );
/* If we have an open menu, see if the open menu should be closed /* If we have an open menu, see if the open menu should be closed
when focus was lost because user either switched * when focus was lost because user either switched
application or FreeGLUT window (if one is running multiple * application or FreeGLUT window (if one is running multiple
windows). If so, close menu the active menu. * windows). If so, close menu the active menu.
*/ */
if ( fgStructure.Menus.First ) if ( fgStructure.Menus.First )
menu = fgGetActiveMenu(); menu = fgGetActiveMenu();
if ( menu ) if ( menu )
{ {
SFG_Window* wnd = NULL; SFG_Window* wnd = NULL;

View File

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