From 72f5d8600c9ca01eebfc4a9c960aa22ffe046158 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 20 Dec 2004 12:57:00 +0000 Subject: [PATCH] Moved the quit window code into window_quit_loop() which is now called by quit_all_windows(). I've also implemented the file panel quit mechanism, but I'm not sure it's correctly done yet. The BApplication destructor now locks the looper. Added commented out deletion of fServerTo port and a ToDo comment if this should be done. Run() no longer checks fMsgPort somewhere, but fInitError at the beginning; if a missing fMsgPort doesn't set this, I guess InitData() is broken (or better, BRoster::Private::CompleteRegistration() is). It now also deletes any fPulseRunner (could be moved to ~BApplication, though). QuitRequested() now correctly calls quit_all_windows(). Added a question to Quit() about the usefulness of special casing calling the function from another thread. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10500 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/app/Application.cpp | 96 ++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/src/kits/app/Application.cpp b/src/kits/app/Application.cpp index 866ff008d8..4a6660f69f 100644 --- a/src/kits/app/Application.cpp +++ b/src/kits/app/Application.cpp @@ -58,9 +58,8 @@ #include #include -// Local Includes -------------------------------------------------------------- -// Local Defines --------------------------------------------------------------- +using namespace BPrivate; // Globals --------------------------------------------------------------------- BApplication *be_app = NULL; @@ -207,28 +206,10 @@ BApplication::BApplication(const char *signature, status_t *_error) BApplication::~BApplication() { + Lock(); + // tell all loopers(usually windows) to quit. Also, wait for them. - - // TODO: As Axel suggested, this functionality should probably be moved - // to quit_all_windows(), and that function should be called from both - // here and QuitRequested(). - - BWindow *window = NULL; - BList looperList; - { - using namespace BPrivate; - BObjectLocker ListLock(gLooperList); - if (ListLock.IsLocked()) - gLooperList.GetLooperList(&looperList); - } - - for (int32 i = 0; i < looperList.CountItems(); i++) { - window = dynamic_cast((BLooper*)looperList.ItemAt(i)); - if (window) { - window->Lock(); - window->Quit(); - } - } + quit_all_windows(true); // unregister from the roster BRoster::Private().RemoveApp(Team()); @@ -240,11 +221,11 @@ BApplication::~BApplication() link.Flush(); #endif // RUN_WITHOUT_APP_SERVER - // uninitialize be_app and be_app_messenger + // ToDo: since we add the port, I guess we should remove it as well? -- axeld. + //delete_port(fServerTo); + + // uninitialize be_app, the be_app_messenger is invalidated automatically be_app = NULL; - - // R5 doesn't uninitialize be_app_messenger. - //be_app_messenger = BMessenger(); } @@ -305,6 +286,9 @@ BApplication::InitCheck() const thread_id BApplication::Run() { + if (fInitError != B_OK) + return fInitError; + AssertLocked(); if (fRunCalled) @@ -312,15 +296,14 @@ BApplication::Run() // Note: We need a local variable too (for the return value), since // fTaskID is cleared by Quit(). +// ToDo: actually, it's not clobbered there?! thread_id thread = fTaskID = find_thread(NULL); - if (fMsgPort < B_OK) - return fMsgPort; - fRunCalled = true; run_task(); + delete fPulseRunner; return thread; } @@ -343,6 +326,7 @@ BApplication::Quit() if (!fRunCalled) { delete this; } else if (find_thread(NULL) != fTaskID) { +// ToDo: why shouldn't we set fTerminating to true directly in this case? // We are not the looper thread. // We push a _QUIT_ into the queue. // TODO: When BLooper::AddMessage() is done, use that instead of @@ -369,11 +353,7 @@ BApplication::Quit() bool BApplication::QuitRequested() { - // No windows -- nothing to do. - // TODO: Au contraire, we can have opened windows, and we have - // to quit them. - - return BLooper::QuitRequested(); + return quit_all_windows(false); } @@ -558,7 +538,6 @@ BApplication::WindowAt(int32 index) const int32 BApplication::CountLoopers() const { - using namespace BPrivate; BObjectLocker ListLock(gLooperList); if (ListLock.IsLocked()) return gLooperList.CountLoopers(); @@ -571,7 +550,6 @@ BApplication::CountLoopers() const BLooper * BApplication::LooperAt(int32 index) const { - using namespace BPrivate; BLooper *Looper = NULL; BObjectLocker ListLock(gLooperList); if (ListLock.IsLocked()) @@ -827,7 +805,7 @@ BApplication::run_task() void -BApplication::InitData(const char *signature, status_t *error) +BApplication::InitData(const char *signature, status_t *_error) { // check whether there exists already an application if (be_app) @@ -1005,8 +983,8 @@ BApplication::InitData(const char *signature, status_t *error) // Return the error or exit, if there was an error and no error variable // has been supplied. - if (error) - *error = fInitError; + if (_error) + *_error = fInitError; else if (fInitError != B_OK) exit(0); } @@ -1144,17 +1122,43 @@ BApplication::write_drag(_BSession_ *session, BMessage *message) bool -BApplication::quit_all_windows(bool force) +BApplication::window_quit_loop(bool quitFilePanels, bool force) { - return false; // TODO: implement? + BList looperList; + BObjectLocker listLock(gLooperList); + if (listLock.IsLocked()) + gLooperList.GetLooperList(&looperList); + + for (int32 i = looperList.CountItems(); i-- > 0; ) { + BWindow *window = dynamic_cast((BLooper *)looperList.ItemAt(i)); + + // ToDo: windows in this list may already have been closed in the mean time?! + + if (window != NULL && window->Lock()) { + if ((window->IsFilePanel() && !quitFilePanels) + || (!force && !window->QuitRequested())) { + // the window does not want to quit, so we don't either + window->Unlock(); + return false; + } + + window->Quit(); + } + } + + return true; } bool -BApplication::window_quit_loop(bool, bool) +BApplication::quit_all_windows(bool force) { - // TODO: Implement and use in BApplication::QuitRequested() - return false; + AssertLocked(); + + if (window_quit_loop(false, force)) + return true; + + return window_quit_loop(true, force); } @@ -1239,8 +1243,6 @@ BApplication::window_at(uint32 index, bool includeMenus) const status_t BApplication::get_window_list(BList *list, bool includeMenus) const { - using namespace BPrivate; - ASSERT(list); // Windows are BLoopers, so we can just check each BLooper to see if it's