Skip to content

Commit 8eb0156

Browse files
committed
#4651 Handle window's sessions termination
1 parent ac2cbdc commit 8eb0156

File tree

9 files changed

+99
-17
lines changed

9 files changed

+99
-17
lines changed

indra/llwindow/llwindowcallbacks.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,13 @@ void LLWindowCallbacks::handleMouseLeave(LLWindow *window)
6868
return;
6969
}
7070

71-
bool LLWindowCallbacks::handleCloseRequest(LLWindow *window)
71+
bool LLWindowCallbacks::handleCloseRequest(LLWindow *window, bool from_user)
72+
{
73+
//allow the window to close
74+
return true;
75+
}
76+
77+
bool LLWindowCallbacks::handleSessionExit(LLWindow* window)
7278
{
7379
//allow the window to close
7480
return true;

indra/llwindow/llwindowcallbacks.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ class LLWindowCallbacks
4242
virtual bool handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
4343
virtual void handleMouseLeave(LLWindow *window);
4444
// return true to allow window to close, which will then cause handleQuit to be called
45-
virtual bool handleCloseRequest(LLWindow *window);
45+
virtual bool handleCloseRequest(LLWindow *window, bool from_user);
46+
virtual bool handleSessionExit(LLWindow* window);
4647
// window is about to be destroyed, clean up your business
4748
virtual void handleQuit(LLWindow *window);
4849
virtual bool handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);

indra/llwindow/llwindowmacosx.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ void callQuitHandler()
610610
{
611611
if (gWindowImplementation && gWindowImplementation->getCallbacks())
612612
{
613-
if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation))
613+
if(gWindowImplementation->getCallbacks()->handleCloseRequest(gWindowImplementation, true))
614614
{
615615
gWindowImplementation->getCallbacks()->handleQuit(gWindowImplementation);
616616
}

indra/llwindow/llwindowsdl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1881,7 +1881,7 @@ void LLWindowSDL::gatherInput()
18811881
{
18821882
// *FIX: More informative dialog?
18831883
LL_INFOS() << "Could not recreate context after resize! Quitting..." << LL_ENDL;
1884-
if(mCallbacks->handleCloseRequest(this))
1884+
if(mCallbacks->handleCloseRequest(this, false))
18851885
{
18861886
// Get the app to initiate cleanup.
18871887
mCallbacks->handleQuit(this);
@@ -1931,7 +1931,7 @@ void LLWindowSDL::gatherInput()
19311931
break;
19321932

19331933
case SDL_QUIT:
1934-
if(mCallbacks->handleCloseRequest(this))
1934+
if(mCallbacks->handleCloseRequest(this, true))
19351935
{
19361936
// Get the app to initiate cleanup.
19371937
mCallbacks->handleQuit(this);

indra/llwindow/llwindowwin32.cpp

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2461,10 +2461,13 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
24612461
case WM_CLOSE:
24622462
{
24632463
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_CLOSE");
2464+
// todo: WM_CLOSE can be caused by user and by task manager,
2465+
// distinguish these cases.
2466+
// For now assume it is always user.
24642467
window_imp->post([=]()
24652468
{
24662469
// Will the app allow the window to close?
2467-
if (window_imp->mCallbacks->handleCloseRequest(window_imp))
2470+
if (window_imp->mCallbacks->handleCloseRequest(window_imp, true))
24682471
{
24692472
// Get the app to initiate cleanup.
24702473
window_imp->mCallbacks->handleQuit(window_imp);
@@ -2482,6 +2485,50 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
24822485
}
24832486
return 0;
24842487
}
2488+
case WM_QUERYENDSESSION:
2489+
{
2490+
// Generally means that OS is going to shut down or user is going to log off.
2491+
// Can use ShutdownBlockReasonCreate here.
2492+
LL_INFOS("Window") << "Received WM_QUERYENDSESSION with wParam: " << (U32)w_param << " lParam: " << (U32)l_param << LL_ENDL;
2493+
return TRUE; // 1 = ok to end session. 0 no longer works by itself, use ShutdownBlockReasonCreate
2494+
}
2495+
case WM_ENDSESSION:
2496+
{
2497+
// OS session is shutting down, initiate cleanup.
2498+
// Comes after WM_QUERYENDSESSION
2499+
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_ENDSESSION");
2500+
LL_INFOS("Window") << "Received WM_ENDSESSION with wParam: " << (U32)w_param << " lParam: " << (U32)l_param << LL_ENDL;
2501+
unsigned int end_session_flags = (U32)w_param;
2502+
if (end_session_flags == 0)
2503+
{
2504+
// session is not actually ending
2505+
return 0;
2506+
}
2507+
2508+
if ((end_session_flags & ENDSESSION_CLOSEAPP)
2509+
|| (end_session_flags & ENDSESSION_CRITICAL)
2510+
|| (end_session_flags & ENDSESSION_LOGOFF))
2511+
{
2512+
window_imp->post([=]()
2513+
{
2514+
// Check if app needs cleanup or can be closed immediately.
2515+
if (window_imp->mCallbacks->handleSessionExit(window_imp))
2516+
{
2517+
// Get the app to initiate cleanup.
2518+
window_imp->mCallbacks->handleQuit(window_imp);
2519+
// The app is responsible for calling destroyWindow when done with GL
2520+
}
2521+
});
2522+
// Give app a second to finish up. That's not enough for a clean exit,
2523+
// but better than nothing.
2524+
// Todo: sync this better, some kind of waitForResult? Can't wait forever,
2525+
// but can potentially use ShutdownBlockReasonCreate for a bigger delay.
2526+
ms_sleep(1000);
2527+
}
2528+
// Don't need to post quit or destroy window,
2529+
// if session is ending OS is going to take care of it.
2530+
return 0;
2531+
}
24852532
case WM_COMMAND:
24862533
{
24872534
LL_PROFILE_ZONE_NAMED_CATEGORY_WIN32("mwp - WM_COMMAND");

indra/newview/llappviewer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4195,7 +4195,7 @@ void LLAppViewer::earlyExit(const std::string& name, const LLSD& substitutions)
41954195
// case where we need the viewer to exit without any need for notifications
41964196
void LLAppViewer::earlyExitNoNotify()
41974197
{
4198-
LL_WARNS() << "app_early_exit with no notification: " << LL_ENDL;
4198+
LL_WARNS() << "app_early_exit with no notification." << LL_ENDL;
41994199
gDoDisconnect = true;
42004200
finish_early_exit( LLSD(), LLSD() );
42014201
}

indra/newview/llappviewer.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,12 @@ class LLAppViewer : public LLApp
149149
std::string getWindowTitle() const; // The window display name.
150150

151151
void forceDisconnect(const std::string& msg); // Force disconnection, with a message to the user.
152+
153+
// sendSimpleLogoutRequest does not create a marker file.
154+
// Meant for lost network case, and for forced shutdowns,
155+
// to at least attempt to remove the ghost from the world.
156+
void sendSimpleLogoutRequest();
157+
152158
void badNetworkHandler(); // Cause a crash state due to bad network packet.
153159

154160
bool hasSavedFinalSnapshot() { return mSavedFinalSnapshot; }
@@ -310,10 +316,6 @@ class LLAppViewer : public LLApp
310316
void sendLogoutRequest();
311317
void disconnectViewer();
312318

313-
// Does not create a marker file. For lost network case,
314-
// to at least attempt to remove the ghost from the world.
315-
void sendSimpleLogoutRequest();
316-
317319
// *FIX: the app viewer class should be some sort of singleton, no?
318320
// Perhaps its child class is the singleton and this should be an abstract base.
319321
static LLAppViewer* sInstance;

indra/newview/llviewerwindow.cpp

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,18 +1461,43 @@ void LLViewerWindow::handleMouseLeave(LLWindow *window)
14611461
LLToolTipMgr::instance().blockToolTips();
14621462
}
14631463

1464-
bool LLViewerWindow::handleCloseRequest(LLWindow *window)
1464+
bool LLViewerWindow::handleCloseRequest(LLWindow *window, bool from_user)
14651465
{
14661466
if (!LLApp::isExiting() && !LLApp::isStopped())
14671467
{
1468-
// User has indicated they want to close, but we may need to ask
1469-
// about modified documents.
1470-
LLAppViewer::instance()->userQuit();
1471-
// Don't quit immediately
1468+
if (from_user)
1469+
{
1470+
// User has indicated they want to close, but we may need to ask
1471+
// about modified documents.
1472+
LLAppViewer::instance()->userQuit();
1473+
// Don't quit immediately
1474+
}
1475+
else
1476+
{
1477+
// OS is asking us to quit, assume we have time and start cleanup
1478+
LLAppViewer::instance()->requestQuit();
1479+
}
14721480
}
14731481
return false;
14741482
}
14751483

1484+
bool LLViewerWindow::handleSessionExit(LLWindow* window)
1485+
{
1486+
if (!LLApp::isExiting() && !LLApp::isStopped())
1487+
{
1488+
// Viewer received WM_ENDSESSION and app will be killed soon if it doesn't respond
1489+
LLAppViewer* app = LLAppViewer::instance();
1490+
app->sendSimpleLogoutRequest();
1491+
app->earlyExitNoNotify();
1492+
1493+
// Not viewer's fault, remove marker files so
1494+
// that statistics won't consider this to be a crash
1495+
app->removeMarkerFiles();
1496+
return false;
1497+
}
1498+
return true;
1499+
}
1500+
14761501
void LLViewerWindow::handleQuit(LLWindow *window)
14771502
{
14781503
if (gNonInteractive)

indra/newview/llviewerwindow.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,8 @@ class LLViewerWindow : public LLWindowCallbacks
197197
/*virtual*/ bool handleUnicodeChar(llwchar uni_char, MASK mask); // NOT going to handle extended
198198
/*virtual*/ bool handleMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
199199
/*virtual*/ bool handleMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);
200-
/*virtual*/ bool handleCloseRequest(LLWindow *window);
200+
/*virtual*/ bool handleCloseRequest(LLWindow *window, bool from_user);
201+
/*virtual*/ bool handleSessionExit(LLWindow* window);
201202
/*virtual*/ void handleQuit(LLWindow *window);
202203
/*virtual*/ bool handleRightMouseDown(LLWindow *window, LLCoordGL pos, MASK mask);
203204
/*virtual*/ bool handleRightMouseUp(LLWindow *window, LLCoordGL pos, MASK mask);

0 commit comments

Comments
 (0)