diff options
| -rw-r--r-- | indra/llwindow/llwindowcallbacks.cpp | 8 | ||||
| -rw-r--r-- | indra/llwindow/llwindowcallbacks.h | 3 | ||||
| -rw-r--r-- | indra/llwindow/llwindowmacosx.cpp | 2 | ||||
| -rw-r--r-- | indra/llwindow/llwindowsdl.cpp | 4 | ||||
| -rw-r--r-- | indra/llwindow/llwindowwin32.cpp | 49 | ||||
| -rw-r--r-- | indra/newview/llappviewer.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/llappviewer.h | 10 | ||||
| -rw-r--r-- | indra/newview/llviewerwindow.cpp | 35 | ||||
| -rw-r--r-- | indra/newview/llviewerwindow.h | 3 |
9 files changed, 99 insertions, 17 deletions
diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp index 195f68e08b..7331f50ba0 100644 --- a/indra/llwindow/llwindowcallbacks.cpp +++ b/indra/llwindow/llwindowcallbacks.cpp @@ -68,7 +68,13 @@ void LLWindowCallbacks::handleMouseLeave(LLWindow *window) return; } -bool LLWindowCallbacks::handleCloseRequest(LLWindow *window) +bool LLWindowCallbacks::handleCloseRequest(LLWindow *window, bool from_user) +{ + //allow the window to close + return true; +} + +bool LLWindowCallbacks::handleSessionExit(LLWindow* window) { //allow the window to close return true; diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h index d812f93524..59dcdd3ade 100644 --- a/indra/llwindow/llwindowcallbacks.h +++ b/indra/llwindow/llwindowcallbacks.h @@ -42,7 +42,8 @@ public: virtual bool handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); virtual void handleMouseLeave(LLWindow *window); // return true to allow window to close, which will then cause handleQuit to be called - virtual bool handleCloseRequest(LLWindow *window); + virtual bool handleCloseRequest(LLWindow *window, bool from_user); + virtual bool handleSessionExit(LLWindow* window); // window is about to be destroyed, clean up your business virtual void handleQuit(LLWindow *window); virtual bool handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index dadbc83f45..3314fa42a7 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -610,7 +610,7 @@ void callQuitHandler() { if (gWindowImplementation && gWindowImplementation->getCallbacks()) { - if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation)) + if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation, true)) { gWindowImplementation->getCallbacks()->handleQuit(gWindowImplementation); } diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp index 7433ad6bd2..05be319c0b 100644 --- a/indra/llwindow/llwindowsdl.cpp +++ b/indra/llwindow/llwindowsdl.cpp @@ -1881,7 +1881,7 @@ void LLWindowSDL::gatherInput() { // *FIX: More informative dialog? LL_INFOS() << "Could not recreate context after resize! Quitting..." << LL_ENDL; - if(mCallbacks->handleCloseRequest(this)) + if(mCallbacks->handleCloseRequest(this, false)) { // Get the app to initiate cleanup. mCallbacks->handleQuit(this); @@ -1931,7 +1931,7 @@ void LLWindowSDL::gatherInput() break; case SDL_QUIT: - if(mCallbacks->handleCloseRequest(this)) + if(mCallbacks->handleCloseRequest(this, true)) { // Get the app to initiate cleanup. mCallbacks->handleQuit(this); diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index b127c9b48f..9194628b44 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -2461,10 +2461,13 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ case WM_CLOSE: { LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_CLOSE"); + // todo: WM_CLOSE can be caused by user and by task manager, + // distinguish these cases. + // For now assume it is always user. window_imp->post([=]() { // Will the app allow the window to close? - if (window_imp->mCallbacks->handleCloseRequest(window_imp)) + if (window_imp->mCallbacks->handleCloseRequest(window_imp, true)) { // Get the app to initiate cleanup. window_imp->mCallbacks->handleQuit(window_imp); @@ -2482,6 +2485,50 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ } return 0; } + case WM_QUERYENDSESSION: + { + // Generally means that OS is going to shut down or user is going to log off. + // Can use ShutdownBlockReasonCreate here. + LL_INFOS("Window") << "Received WM_QUERYENDSESSION with wParam: " << (U32)w_param << " lParam: " << (U32)l_param << LL_ENDL; + return TRUE; // 1 = ok to end session. 0 no longer works by itself, use ShutdownBlockReasonCreate + } + case WM_ENDSESSION: + { + // OS session is shutting down, initiate cleanup. + // Comes after WM_QUERYENDSESSION + LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_ENDSESSION"); + LL_INFOS("Window") << "Received WM_ENDSESSION with wParam: " << (U32)w_param << " lParam: " << (U32)l_param << LL_ENDL; + unsigned int end_session_flags = (U32)w_param; + if (end_session_flags == 0) + { + // session is not actually ending + return 0; + } + + if ((end_session_flags & ENDSESSION_CLOSEAPP) + || (end_session_flags & ENDSESSION_CRITICAL) + || (end_session_flags & ENDSESSION_LOGOFF)) + { + window_imp->post([=]() + { + // Check if app needs cleanup or can be closed immediately. + if (window_imp->mCallbacks->handleSessionExit(window_imp)) + { + // Get the app to initiate cleanup. + window_imp->mCallbacks->handleQuit(window_imp); + // The app is responsible for calling destroyWindow when done with GL + } + }); + // Give app a second to finish up. That's not enough for a clean exit, + // but better than nothing. + // Todo: sync this better, some kind of waitForResult? Can't wait forever, + // but can potentially use ShutdownBlockReasonCreate for a bigger delay. + ms_sleep(1000); + } + // Don't need to post quit or destroy window, + // if session is ending OS is going to take care of it. + return 0; + } case WM_COMMAND: { LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_COMMAND"); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index ac9464d86e..b36ed46a39 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4195,7 +4195,7 @@ void LLAppViewer::earlyExit(const std::string& name, const LLSD& substitutions) // case where we need the viewer to exit without any need for notifications void LLAppViewer::earlyExitNoNotify() { - LL_WARNS() << "app_early_exit with no notification: " << LL_ENDL; + LL_WARNS() << "app_early_exit with no notification." << LL_ENDL; gDoDisconnect = true; finish_early_exit( LLSD(), LLSD() ); } diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index e7de2d9b28..24d55a00fe 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -149,6 +149,12 @@ public: std::string getWindowTitle() const; // The window display name. void forceDisconnect(const std::string& msg); // Force disconnection, with a message to the user. + + // sendSimpleLogoutRequest does not create a marker file. + // Meant for lost network case, and for forced shutdowns, + // to at least attempt to remove the ghost from the world. + void sendSimpleLogoutRequest(); + void badNetworkHandler(); // Cause a crash state due to bad network packet. bool hasSavedFinalSnapshot() { return mSavedFinalSnapshot; } @@ -310,10 +316,6 @@ private: void sendLogoutRequest(); void disconnectViewer(); - // Does not create a marker file. For lost network case, - // to at least attempt to remove the ghost from the world. - void sendSimpleLogoutRequest(); - // *FIX: the app viewer class should be some sort of singleton, no? // Perhaps its child class is the singleton and this should be an abstract base. static LLAppViewer* sInstance; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 0edb7c70ea..42ad82d731 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1461,18 +1461,43 @@ void LLViewerWindow::handleMouseLeave(LLWindow *window) LLToolTipMgr::instance().blockToolTips(); } -bool LLViewerWindow::handleCloseRequest(LLWindow *window) +bool LLViewerWindow::handleCloseRequest(LLWindow *window, bool from_user) { if (!LLApp::isExiting() && !LLApp::isStopped()) { - // User has indicated they want to close, but we may need to ask - // about modified documents. - LLAppViewer::instance()->userQuit(); - // Don't quit immediately + if (from_user) + { + // User has indicated they want to close, but we may need to ask + // about modified documents. + LLAppViewer::instance()->userQuit(); + // Don't quit immediately + } + else + { + // OS is asking us to quit, assume we have time and start cleanup + LLAppViewer::instance()->requestQuit(); + } } return false; } +bool LLViewerWindow::handleSessionExit(LLWindow* window) +{ + if (!LLApp::isExiting() && !LLApp::isStopped()) + { + // Viewer received WM_ENDSESSION and app will be killed soon if it doesn't respond + LLAppViewer* app = LLAppViewer::instance(); + app->sendSimpleLogoutRequest(); + app->earlyExitNoNotify(); + + // Not viewer's fault, remove marker files so + // that statistics won't consider this to be a crash + app->removeMarkerFiles(); + return false; + } + return true; +} + void LLViewerWindow::handleQuit(LLWindow *window) { if (gNonInteractive) diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index d55c2d3817..61aa84394c 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -197,7 +197,8 @@ public: /*virtual*/ bool handleUnicodeChar(llwchar uni_char, MASK mask); // NOT going to handle extended /*virtual*/ bool handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); /*virtual*/ bool handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); - /*virtual*/ bool handleCloseRequest(LLWindow *window); + /*virtual*/ bool handleCloseRequest(LLWindow *window, bool from_user); + /*virtual*/ bool handleSessionExit(LLWindow* window); /*virtual*/ void handleQuit(LLWindow *window); /*virtual*/ bool handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask); /*virtual*/ bool handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask); |
