When receiving WM_SETFOCUS, check if its child window that should
authorDiederick Niehorster <dcnieho@gmail.com>
Mon, 23 Jul 2012 07:00:14 +0000 (07:00 +0000)
committerDiederick Niehorster <dcnieho@gmail.com>
Mon, 23 Jul 2012 07:00:14 +0000 (07:00 +0000)
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
src/mswin/fg_main_mswin.c
src/mswin/fg_window_mswin.c

index 3ad2cb1..65ec674 100644 (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;
-            }
+            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 );
     }
index a7ca9d8..28e1b64 100644 (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 );
+        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;
index bc6b886..7af029d 100644 (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"! */
-
 }