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:
parent
77ae3c4f4c
commit
fc2ee24b1b
@ -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 );
|
||||||
}
|
}
|
||||||
|
@ -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,9 +511,9 @@ 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();
|
||||||
|
@ -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"! */
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user