static unsigned char lControl = 0, rControl = 0, lShift = 0,
rShift = 0, lAlt = 0, rAlt = 0;
- SFG_Window* window;
+ SFG_Window *window, *child_window = NULL;
PAINTSTRUCT ps;
LRESULT lRet = 1;
/* printf ( "Window %3d message <%04x> %12d %12d\n", window?window->ID:0,
uMsg, wParam, lParam ); */
- /* events only sent to main window. Check if the current window that the mouse
- is over is a child window and if so, make sure we call the callback on that
- child instead.
- */
+ /* Some events only sent to main window. Check if the current window that
+ * the mouse is over is a child window. Below when handling some messages,
+ * we make sure that we process callbacks on the child window instead.
+ * This mirrors how GLUT does things.
+ */
if (window && window->Children.First)
{
POINT mouse_pos;
SFG_WindowHandleType hwnd;
+ SFG_Window* temp_window;
GetCursorPos( &mouse_pos );
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);
+ {
+ temp_window = fgWindowByHandle(hwnd);
+ if (temp_window->Parent) /* Verify we got a child window */
+ child_window = temp_window;
+ }
}
if ( window )
{
+ SFG_Window* temp_window = child_window?child_window:window;
+
fgState.Modifiers = fgPlatformGetModifiers( );
/* Checking for CTRL, ALT, and SHIFT key positions: Key Down! */
if ( !lControl && GetAsyncKeyState ( VK_LCONTROL ) )
{
- INVOKE_WCB ( *window, Special,
- ( GLUT_KEY_CTRL_L, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, Special,
+ ( GLUT_KEY_CTRL_L, temp_window->State.MouseX, temp_window->State.MouseY )
);
lControl = 1;
if ( !rControl && GetAsyncKeyState ( VK_RCONTROL ) )
{
- INVOKE_WCB ( *window, Special,
- ( GLUT_KEY_CTRL_R, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, Special,
+ ( GLUT_KEY_CTRL_R, temp_window->State.MouseX, temp_window->State.MouseY )
);
rControl = 1;
if ( !lShift && GetAsyncKeyState ( VK_LSHIFT ) )
{
- INVOKE_WCB ( *window, Special,
- ( GLUT_KEY_SHIFT_L, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, Special,
+ ( GLUT_KEY_SHIFT_L, temp_window->State.MouseX, temp_window->State.MouseY )
);
lShift = 1;
if ( !rShift && GetAsyncKeyState ( VK_RSHIFT ) )
{
- INVOKE_WCB ( *window, Special,
- ( GLUT_KEY_SHIFT_R, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, Special,
+ ( GLUT_KEY_SHIFT_R, temp_window->State.MouseX, temp_window->State.MouseY )
);
rShift = 1;
if ( !lAlt && GetAsyncKeyState ( VK_LMENU ) )
{
- INVOKE_WCB ( *window, Special,
- ( GLUT_KEY_ALT_L, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, Special,
+ ( GLUT_KEY_ALT_L, temp_window->State.MouseX, temp_window->State.MouseY )
);
lAlt = 1;
if ( !rAlt && GetAsyncKeyState ( VK_RMENU ) )
{
- INVOKE_WCB ( *window, Special,
- ( GLUT_KEY_ALT_R, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, Special,
+ ( GLUT_KEY_ALT_R, temp_window->State.MouseX, temp_window->State.MouseY )
);
rAlt = 1;
/* Checking for CTRL, ALT, and SHIFT key positions: Key Up! */
if ( lControl && !GetAsyncKeyState ( VK_LCONTROL ) )
{
- INVOKE_WCB ( *window, SpecialUp,
- ( GLUT_KEY_CTRL_L, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, SpecialUp,
+ ( GLUT_KEY_CTRL_L, temp_window->State.MouseX, temp_window->State.MouseY )
);
lControl = 0;
if ( rControl && !GetAsyncKeyState ( VK_RCONTROL ) )
{
- INVOKE_WCB ( *window, SpecialUp,
- ( GLUT_KEY_CTRL_R, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, SpecialUp,
+ ( GLUT_KEY_CTRL_R, temp_window->State.MouseX, temp_window->State.MouseY )
);
rControl = 0;
if ( lShift && !GetAsyncKeyState ( VK_LSHIFT ) )
{
- INVOKE_WCB ( *window, SpecialUp,
- ( GLUT_KEY_SHIFT_L, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, SpecialUp,
+ ( GLUT_KEY_SHIFT_L, temp_window->State.MouseX, temp_window->State.MouseY )
);
lShift = 0;
if ( rShift && !GetAsyncKeyState ( VK_RSHIFT ) )
{
- INVOKE_WCB ( *window, SpecialUp,
- ( GLUT_KEY_SHIFT_R, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, SpecialUp,
+ ( GLUT_KEY_SHIFT_R, temp_window->State.MouseX, temp_window->State.MouseY )
);
rShift = 0;
if ( lAlt && !GetAsyncKeyState ( VK_LMENU ) )
{
- INVOKE_WCB ( *window, SpecialUp,
- ( GLUT_KEY_ALT_L, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, SpecialUp,
+ ( GLUT_KEY_ALT_L, temp_window->State.MouseX, temp_window->State.MouseY )
);
lAlt = 0;
if ( rAlt && !GetAsyncKeyState ( VK_RMENU ) )
{
- INVOKE_WCB ( *window, SpecialUp,
- ( GLUT_KEY_ALT_R, window->State.MouseX, window->State.MouseY )
+ INVOKE_WCB ( *temp_window, SpecialUp,
+ ( GLUT_KEY_ALT_R, temp_window->State.MouseX, temp_window->State.MouseY )
);
rAlt = 0;
case WM_SETFOCUS:
/* printf("WM_SETFOCUS: %p\n", window ); */
+
lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
- INVOKE_WCB( *window, Entry, ( GLUT_ENTERED ) );
- UpdateWindow ( hWnd );
+ if (child_window)
+ {
+ /* If child should have focus instead, set it here. */
+ SetFocus(child_window->Window.Handle);
+ SetActiveWindow( child_window->Window.Handle );
+ INVOKE_WCB( *child_window, Entry, ( GLUT_ENTERED ) );
+ UpdateWindow ( child_window->Window.Handle );
+ }
+ else
+ {
+ SetActiveWindow( window->Window.Handle );
+ INVOKE_WCB( *window, Entry, ( GLUT_ENTERED ) );
+ }
+ /* Always request update on main window to be safe */
+ UpdateWindow ( hWnd );
+
break;
case WM_KILLFOCUS:
{
SFG_Menu* menu = NULL;
-/* printf("WM_KILLFOCUS (ismenu: %i): %p\n", window->IsMenu, window ); */
+ SFG_Window* saved_window = fgStructure.CurrentWindow;
+/* printf("WM_KILLFOCUS: %p\n", window ); */
lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
INVOKE_WCB( *window, Entry, ( GLUT_LEFT ) );
+ fgSetWindow(saved_window);
/* 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.CurrentMenu )
+ if ( fgStructure.Menus.First )
menu = fgGetActiveMenu();
-
+
if ( menu )
{
SFG_Window* wnd = NULL;
- HWND hwnd = GetForegroundWindow(); /* Get window with current focus */
+ HWND hwnd = GetFocus(); /* Get window with current focus - NULL for non freeglut windows */
if (hwnd)
- /* See if its one of our windows */
+ /* See which of our windows it is */
wnd = fgWindowByHandle(hwnd);
if (!hwnd || !wnd)
/* User switched to another application*/
fgDeactivateMenu(menu->ParentWindow);
- else if (
- ( wnd->IsMenu && wnd->ActiveMenu && wnd->ActiveMenu->ParentWindow!=menu->ParentWindow) || /* Make sure we don't kill the menu when trying to enter a submenu */
- (!wnd->IsMenu && wnd!=menu->ParentWindow)
- )
- /* User switched to another FreeGLUT window */
- fgDeactivateMenu(menu->ParentWindow);
+ else if (!wnd->IsMenu) /* Make sure we don't kill the menu when trying to enter a submenu */
+ {
+ if (wnd!=menu->ParentWindow)
+ /* User switched to another FreeGLUT window */
+ fgDeactivateMenu(menu->ParentWindow);
+ else
+ {
+ /* Check if focus lost because non-client area of
+ * window was pressed (pressing on client area is
+ * handled in fgCheckActiveMenu)
+ */
+ POINT mouse_pos;
+ RECT clientArea = fghGetClientArea(menu->ParentWindow, GL_FALSE);
+ GetCursorPos(&mouse_pos);
+ if ( !PtInRect( &clientArea, mouse_pos ) )
+ fgDeactivateMenu(menu->ParentWindow);
+ }
+ }
}
}
break;
int keypress = -1;
POINT mouse_pos ;
+ if (child_window)
+ window = child_window;
if( ( fgState.KeyRepeat==GLUT_KEY_REPEAT_OFF || window->State.IgnoreKeyRepeat==GL_TRUE ) && (HIWORD(lParam) & KF_REPEAT) )
break;
int keypress = -1;
POINT mouse_pos;
+ if (child_window)
+ window = child_window;
+
/*
* Remember the current modifiers state. This is done here in order
* to make sure the VK_DELETE keyboard callback is executed properly.
case WM_SYSCHAR:
case WM_CHAR:
{
+ if (child_window)
+ window = child_window;
+
if( (fgState.KeyRepeat==GLUT_KEY_REPEAT_OFF || window->State.IgnoreKeyRepeat==GL_TRUE) && (HIWORD(lParam) & KF_REPEAT) )
break;