void Redisplay();\r
void Reshape(int width, int height);\r
void Position(int x, int y);\r
+void WindowStatus(int state);\r
\r
\r
\r
glEnd();\r
}\r
\r
+void UnhideTimer(int window)\r
+{\r
+ glutSetWindow(window);\r
+ glutShowWindow();\r
+}\r
+\r
void SampleKeyboard( unsigned char cChar, int nMouseX, int nMouseY )\r
{\r
switch (cChar)\r
glutDisplayFunc( Redisplay );\r
glutReshapeFunc( Reshape );\r
glutPositionFunc( Position );\r
+ glutWindowStatusFunc( WindowStatus );\r
}\r
else\r
{\r
break;\r
\r
\r
+ case 'i':\r
+ case 'I':\r
+ glutIconifyWindow();\r
+ break;\r
+\r
+\r
+ case 'h':\r
+ case 'H':\r
+ if (nChildWindow!=-1 && cChar=='h') /* Capital H always hides the main window*/\r
+ {\r
+ glutSetWindow(nChildWindow);\r
+ glutTimerFunc(2000, UnhideTimer, nChildWindow);\r
+ }\r
+ else\r
+ {\r
+ glutSetWindow(nWindow);\r
+ glutTimerFunc(2000, UnhideTimer, nWindow);\r
+ }\r
+ glutHideWindow();\r
+\r
default:\r
break;\r
}\r
x, y);\r
}\r
\r
+void WindowStatus(int state)\r
+{\r
+ int win = glutGetWindow();\r
+ printf("windowstatus (win %i): %i\n",win,state);\r
+}\r
+\r
void Redisplay(void)\r
{\r
int win = glutGetWindow();\r
nWidth, nHeight,\r
nPosX ,nPosY);
- /* (re)set the timer callback and ask glut to call it in 1 second */
- glutTimerFunc(300, Timer, 0);
+ /* (re)set the timer callback and ask glut to call it in 500 ms */
+ glutTimerFunc(500, Timer, 0);
}\r
\r
\r
glutDisplayFunc( Redisplay );\r
glutReshapeFunc( Reshape );\r
glutPositionFunc( Position );\r
+ glutWindowStatusFunc( WindowStatus );\r
\r
glutTimerFunc(300, Timer, 0);\r
\r
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutIconifyWindow" );
FREEGLUT_EXIT_IF_NO_WINDOW ( "glutIconifyWindow" );
- fgStructure.CurrentWindow->State.Visible = GL_FALSE;
-
fgPlatformGlutIconifyWindow ();
fgStructure.CurrentWindow->State.Redisplay = GL_FALSE;
BOOL OldMaximized; /* window maximized state - stored before the window is made fullscreen */
GLboolean MouseTracking; /* Needed for generating GLUT_ENTERED and GLUT_LEFT entry func callbacks on windows */
+ GLboolean WindowFuncCalled; /* Indicate whether windowStatus/visibility func was notified that this window was created */
};
}
}
-static void fghNotifyWindowStatus(SFG_Window *window)
+void fghNotifyWindowStatus(SFG_Window *window)
{
- SFG_Window* child;
-
INVOKE_WCB( *window, WindowStatus, ( window->State.Visible?GLUT_FULLY_RETAINED:GLUT_HIDDEN ) );
- /* Also notify children */
- for( child = ( SFG_Window * )window->Children.First;
- child;
- child = ( SFG_Window * )child->Node.Next )
- {
- fghNotifyWindowStatus(child);
- }
+ /* Don't notify children, they get their own just before first time they're drawn */
}
void fgPlatformMainLoopPreliminaryWork ( void )
{
- SFG_Window *window = (SFG_Window *)fgStructure.Windows.First ;
-
- /*
- * Processing before the main loop: If there is a window which is open and
- * which has a visibility/windowStatus callback, call it to inform the client
- * code that the window is visible. I know this is an ugly hack,
- * but I'm not sure what else to do about it. Depending on WM_ACTIVATE would
- * not work as not all windows get this when you are opening multiple before
- * the mainloop starts. WM_SHOWWINDOW looked like an interesting candidate, but
- * it is generated and processed before glutCreate(Sub)Window returns, so no
- * callback can yet be set on the window.
- */
- while( window )
- {
- if ( FETCH_WCB( *window, WindowStatus ) )
- {
- SFG_Window *current_window = fgStructure.CurrentWindow ;
-
- fghNotifyWindowStatus(window);
- fgSetWindow( current_window );
- }
-
- window = (SFG_Window *)window->Node.Next ;
- }
+ /* no-op */
}
break;
case WM_SIZE:
- //printf("WM_SIZE (ID: %i): wParam: %i, new size: %ix%i \n",window->ID,wParam,LOWORD(lParam),HIWORD(lParam));
- /*
- * If the window is visible, then it is the user manually resizing it.
- * If it is not, then it is the system sending us a dummy resize with
- * zero dimensions on a "glutIconifyWindow" call.
- */
+ /* printf("WM_SIZE (ID: %i): wParam: %i, new size: %ix%i \n",window->ID,wParam,LOWORD(lParam),HIWORD(lParam)); */
+
+ /* Update visibility state of the window */
+ if (wParam==SIZE_MINIMIZED)
+ fghUpdateWindowStatus(window,GL_FALSE);
+ else if (wParam==SIZE_RESTORED && !window->State.Visible)
+ fghUpdateWindowStatus(window,GL_TRUE);
+
+ /* Check window visible, we don't want to resize when the user or glutIconifyWindow minimized the window */
if( window->State.Visible )
{
/* get old values first to compare to below */
SFG_Window* saved_window = fgStructure.CurrentWindow;
RECT windowRect;
- /* Check window visible, we don't want to call the position callback when the user minimized the window */
- if (window->State.Visible)
+ /* Check window is minimized, we don't want to call the position callback when the user or glutIconifyWindow minimized the window */
+ if (!IsIconic(window->Window.Handle))
{
/* Get top-left of non-client area of window, matching coordinates of
* glutInitPosition and glutPositionWindow, but not those of
fgSetWindow(saved_window);
}
}
+
+ /* according to docs, should return 0 */
+ lRet = 0;
break;
case WM_SETFOCUS:
break;
case WM_SHOWWINDOW:
- //printf("WM_SHOWWINDOW\n");
- fghUpdateWindowStatus(window, GL_TRUE);
- window->State.Redisplay = GL_TRUE;
+ /* printf("WM_SHOWWINDOW, shown? %i, source: %i\n",wParam,lParam); */
+ if (wParam)
+ {
+ fghUpdateWindowStatus(window, GL_TRUE);
+ window->State.Redisplay = GL_TRUE;
+ }
+ else
+ {
+ fghUpdateWindowStatus(window, GL_FALSE);
+ window->State.Redisplay = GL_FALSE;
+ }
break;
case WM_PAINT:
case SC_MINIMIZE :
/* User has clicked on the "-" to minimize the window */
- /* Turn off the visibility */
- fghUpdateWindowStatus(window, GL_FALSE);
+ /* Turning off the visibility is handled in WM_SIZE handler */
break ;
break ;
case SC_RESTORE :
- fghUpdateWindowStatus(window, GL_TRUE);
break ;
case SC_TASKLIST :
typedef BOOL (WINAPI *pRegisterTouchWindow)(HWND,ULONG);
static pRegisterTouchWindow fghRegisterTouchWindow = (pRegisterTouchWindow)0xDEADBEEF;
#endif
+extern void fghNotifyWindowStatus(SFG_Window *window);
/*
fgState.ForceIconic ? SW_SHOWMINIMIZED : SW_SHOWNORMAL );
#endif /* defined(_WIN32_WCE) */
- UpdateWindow( window->Window.Handle );
- ShowCursor( TRUE ); /* XXX Old comments say "hide cursor"! */
+ ShowCursor( TRUE );
}
RECT windowRect;
/*
+ * HACK HACK HACK:
+ * Before we do anything else, check if this is a newly created window
+ * that did not have its windowStatus/visibility func called yet
+ * we do that on first paint, but because I want to keep the paint
+ * operation as lean as possible, we do it here. The first paint
+ * goes together with a first resize call before the display callback
+ * is called, so this is just in time. Shitty place to do it, but this
+ * is the only reliable way I can think of to call the callback upon
+ * first draw of the window.
+ * More broadly speaking, I know this is an ugly hack, but I'm not sure
+ * what else to do about it. Depending on WM_ACTIVATE would not work
+ * as not all windows get this when you are opening multiple before the
+ * mainloop starts. WM_SHOWWINDOW looked like an interesting candidate,
+ * but it is generated and processed before glutCreate(Sub)Window
+ * returns, so no callback can yet be set on the window.
+ */
+ /* Check windowStatus/visibility func has been notified that window is visible (deferred from creation time to give user opportunity to register callbacks) */
+ if (!window->State.pWState.WindowFuncCalled)
+ {
+ fghNotifyWindowStatus(window);
+ window->State.pWState.WindowFuncCalled = GL_TRUE;
+ }
+
+ /*
* For windowed mode, get the current position of the
* window and resize taking the size of the frame
* decorations into account.
*/
void fgPlatformGlutIconifyWindow( void )
{
- ShowWindow( fgStructure.CurrentWindow->Window.Handle, SW_MINIMIZE );
+ SFG_Window *win = fgStructure.CurrentWindow;
+
+ /* Call on parent window */
+ while (win->Parent)
+ win = win->Parent;
+
+ /* Visibility status of window gets updated in the WM_SHOWWINDOW handler */
+ ShowWindow(win->Window.Handle, SW_MINIMIZE);
}
/*
XIconifyWindow( fgDisplay.pDisplay.Display, fgStructure.CurrentWindow->Window.Handle,
fgDisplay.pDisplay.Screen );
XFlush( fgDisplay.pDisplay.Display ); /* XXX Shouldn't need this */
+
+ fgStructure.CurrentWindow->State.Visible = GL_FALSE;
}
/*