#4651 Handle window's sessions termination
parent
ac2cbdcc02
commit
8eb015666e
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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() );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue