From 3a423ad871d823ee0707057c22b4ef90fd66e1aa Mon Sep 17 00:00:00 2001 From: Diederick Niehorster Date: Mon, 23 Jul 2012 07:00:14 +0000 Subject: [PATCH] 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: svn+ssh://svn.code.sf.net/p/freeglut/code/trunk/freeglut/freeglut@1361 7f0cb862-5218-0410-a997-914c9d46530a --- src/fg_menu.c | 31 ++++++------------------------- src/mswin/fg_main_mswin.c | 21 ++++++++++++++++----- src/mswin/fg_window_mswin.c | 1 - 3 files changed, 22 insertions(+), 31 deletions(-) diff --git a/src/fg_menu.c b/src/fg_menu.c index 3ad2cb1..65ec674 100644 --- a/src/fg_menu.c +++ b/src/fg_menu.c @@ -29,6 +29,7 @@ #include #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; - } + fgDeactivateMenu( window->ActiveMenu->ParentWindow ); } /* @@ -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... */ + /* 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; - /* Did we find an active window? */ 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 ); } diff --git a/src/mswin/fg_main_mswin.c b/src/mswin/fg_main_mswin.c index a7ca9d8..28e1b64 100644 --- a/src/mswin/fg_main_mswin.c +++ b/src/mswin/fg_main_mswin.c @@ -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 ); + UpdateWindow ( hWnd ); + if (gotChild) + UpdateWindow ( window->Window.Handle ); break; case WM_KILLFOCUS: @@ -500,13 +511,13 @@ 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(); - + if ( menu ) { SFG_Window* wnd = NULL; diff --git a/src/mswin/fg_window_mswin.c b/src/mswin/fg_window_mswin.c index bc6b886..7af029d 100644 --- a/src/mswin/fg_window_mswin.c +++ b/src/mswin/fg_window_mswin.c @@ -808,7 +808,6 @@ void fgPlatformOpenWindow( SFG_Window* window, const char* title, UpdateWindow( window->Window.Handle ); ShowCursor( TRUE ); /* XXX Old comments say "hide cursor"! */ - } -- 1.7.10.4