diff --git a/src/servers/app/MessageLooper.cpp b/src/servers/app/MessageLooper.cpp index d563046bfd..fab93de8c7 100644 --- a/src/servers/app/MessageLooper.cpp +++ b/src/servers/app/MessageLooper.cpp @@ -55,6 +55,23 @@ MessageLooper::Run() void MessageLooper::Quit() { + fQuitting = true; + _PrepareQuit(); + + if (fThread < B_OK) { + // thread has not been started yet + delete this; + return; + } + + if (fThread == find_thread(NULL)) { + // called from our message looper + delete this; + exit_thread(0); + } else { + // called from a different thread + PostMessage(kMsgQuitLooper); + } } @@ -71,6 +88,13 @@ MessageLooper::PostMessage(int32 code) } +void +MessageLooper::_PrepareQuit() +{ + // to be implemented by subclasses +} + + void MessageLooper::_GetLooperName(char* name, size_t length) { diff --git a/src/servers/app/MessageLooper.h b/src/servers/app/MessageLooper.h index db6141f671..5e00a6c88c 100644 --- a/src/servers/app/MessageLooper.h +++ b/src/servers/app/MessageLooper.h @@ -26,6 +26,7 @@ class MessageLooper : public BLocker { thread_id Thread() const { return fThread; } private: + virtual void _PrepareQuit(); virtual void _GetLooperName(char* name, size_t length); virtual void _DispatchMessage(int32 code, BPrivate::LinkReceiver &link); virtual void _MessageLooper(); @@ -39,4 +40,6 @@ class MessageLooper : public BLocker { bool fQuitting; }; +static const uint32 kMsgQuitLooper = 'quit'; + #endif /* MESSAGE_LOOPER_H */ diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index d76a53cfae..457cb9a804 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -10,6 +10,16 @@ * Axel Dörfler, axeld@pinc-software.de */ +/*! + \class ServerWindow + \brief Shadow BWindow class + + A ServerWindow handles all the intraserver tasks required of it by its BWindow. There are + too many tasks to list as being done by them, but they include handling View transactions, + coordinating and linking a window's WinBorder half with its messaging half, dispatching + mouse and key events from the server to its window, and other such things. +*/ + #include #include @@ -65,9 +75,6 @@ #endif -static const uint32 kMsgWindowQuit = 'winQ'; - - /*! \brief Constructor @@ -168,27 +175,15 @@ ServerWindow::Run() void -ServerWindow::Quit() +ServerWindow::_PrepareQuit() { - fQuitting = true; - - if (fThread < B_OK) { - delete this; - return; - } - if (fThread == find_thread(NULL)) { // make sure we're hidden Hide(); App()->RemoveWindow(this); - - delete this; - exit_thread(0); - } else { + } else if (fThread >= B_OK) PostMessage(AS_HIDE_WINDOW); - PostMessage(kMsgWindowQuit); - } } @@ -2141,7 +2136,7 @@ ServerWindow::_MessageLooper() switch (code) { case AS_DELETE_WINDOW: - case kMsgWindowQuit: + case kMsgQuitLooper: // this means the client has been killed STRACE(("ServerWindow %s received 'AS_DELETE_WINDOW' message code\n", Title())); diff --git a/src/servers/app/ServerWindow.h b/src/servers/app/ServerWindow.h index 7f748a6632..dfa2fb1d13 100644 --- a/src/servers/app/ServerWindow.h +++ b/src/servers/app/ServerWindow.h @@ -44,15 +44,6 @@ struct window_info; #define AS_UPDATE_COLORS 'asuc' #define AS_UPDATE_FONTS 'asuf' -/*! - \class ServerWindow ServerWindow.h - \brief Shadow BWindow class - - A ServerWindow handles all the intraserver tasks required of it by its BWindow. There are - too many tasks to list as being done by them, but they include handling View transactions, - coordinating and linking a window's WinBorder half with its messaging half, dispatching - mouse and key events from the server to its window, and other such things. -*/ class ServerWindow : public MessageLooper { public: ServerWindow(const char *title, ServerApp *app, @@ -64,7 +55,6 @@ public: uint32 feel, uint32 flags, uint32 workspace); virtual bool Run(); - virtual void Quit(); void ReplaceDecorator(); void Show(); @@ -121,8 +111,9 @@ private: void _DispatchMessage(int32 code, BPrivate::LinkReceiver &link); void _DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link); void _MessageLooper(); - virtual void _GetLooperName(char* name, size_t size); - virtual port_id _MessagePort() const { return fMessagePort; } + virtual void _PrepareQuit(); + virtual void _GetLooperName(char* name, size_t size); + virtual port_id _MessagePort() const { return fMessagePort; } // TODO: Move me elsewhere status_t PictureToRegion(ServerPicture *picture,