diff --git a/headers/os/interface/Window.h b/headers/os/interface/Window.h index 66f1ba9fb8..1b87682ee9 100644 --- a/headers/os/interface/Window.h +++ b/headers/os/interface/Window.h @@ -335,6 +335,7 @@ private: void _AdoptResize(); void _SetFocus(BView* focusView, bool notifyIputServer = false); + void _SetName(const char* title); Shortcut* _FindShortcut(uint32 key, uint32 modifiers); BView* _FindView(BView* view, BPoint point) const; diff --git a/src/kits/interface/Window.cpp b/src/kits/interface/Window.cpp index 37df9745f7..840bbe7c50 100644 --- a/src/kits/interface/Window.cpp +++ b/src/kits/interface/Window.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -268,7 +269,7 @@ BWindow::Shortcut::PrepareKey(uint32 key) BWindow::BWindow(BRect frame, const char* title, window_type type, - uint32 flags, uint32 workspace) + uint32 flags, uint32 workspace) : BLooper(title, B_DISPLAY_PRIORITY) { window_look look; @@ -279,8 +280,8 @@ BWindow::BWindow(BRect frame, const char* title, window_type type, } -BWindow::BWindow(BRect frame, const char* title, window_look look, window_feel feel, - uint32 flags, uint32 workspace) +BWindow::BWindow(BRect frame, const char* title, window_look look, + window_feel feel, uint32 flags, uint32 workspace) : BLooper(title, B_DISPLAY_PRIORITY) { _InitData(frame, title, look, feel, flags, workspace); @@ -852,10 +853,9 @@ BWindow::DispatchMessage(BMessage *msg, BHandler *target) height = nextHeight; MessageQueue()->RemoveMessage(pendingMessage); - // TODO: the BeBook says that MessageQueue::RemoveMessage() deletes the message! delete pendingMessage; - // this deletes the first *additional* message - // fCurrentMessage is safe + // this deletes the first *additional* message + // fCurrentMessage is safe } else { MessageQueue()->RemoveMessage(pendingMessage); } @@ -1798,25 +1798,7 @@ BWindow::SetTitle(const char *title) free(fTitle); fTitle = strdup(title); - // we will change BWindow's thread name to "w>window title" - - char threadName[B_OS_NAME_LENGTH]; - strcpy(threadName, "w>"); -#ifdef __HAIKU__ - strlcat(threadName, title, B_OS_NAME_LENGTH); -#else - int32 length = strlen(title); - length = min_c(length, B_OS_NAME_LENGTH - 3); - memcpy(threadName + 2, title, length); - threadName[length + 2] = '\0'; -#endif - - // change the handler's name - SetName(threadName); - - // if the message loop has been started... - if (Thread() >= B_OK) - rename_thread(Thread(), threadName); + _SetName(title); // we notify the app_server so we can actually see the change if (Lock()) { @@ -2367,9 +2349,10 @@ BWindow::_InitData(BRect frame, const char* title, window_look look, if (title == NULL) title = ""; -// TODO: Where's da "w>"? + fTitle = strdup(title); - SetName(title); + + _SetName(title); fFeel = feel; fLook = look; @@ -2441,65 +2424,57 @@ BWindow::_InitData(BRect frame, const char* title, window_look look, STRACE(("BWindow::InitData(): contacting app_server...\n")); - // HERE we are in BApplication's thread, so for locking we use be_app variable - // we'll lock the be_app to be sure we're the only one writing at BApplication's server port - bool locked = false; - if (!be_app->IsLocked()) { -// TODO: This doesn't look good. If a window is created in the message handling -// code of another window, then the lock of that other window is already being -// held. So, if the application tries to lock that window from its message -// handling code, we get a beautiful deadlock. Start Icon-O-Matic, quit it, and -// start it a second time to see that in action. - be_app->Lock(); - locked = true; - } - // let app_server know that a window has been created. fLink = new BPrivate::PortLink( BApplication::Private::ServerLink()->SenderPort(), receivePort); - if (bitmapToken < 0) { - fLink->StartMessage(AS_CREATE_WINDOW); - } else { - fLink->StartMessage(AS_CREATE_OFFSCREEN_WINDOW); - fLink->Attach(bitmapToken); + { + BPrivate::AppServerLink lockLink; + // we're talking to the server application using our own + // communication channel (fLink) - we better make sure no one + // interferes by locking that channel (which AppServerLink does + // implicetly) + + if (bitmapToken < 0) { + fLink->StartMessage(AS_CREATE_WINDOW); + } else { + fLink->StartMessage(AS_CREATE_OFFSCREEN_WINDOW); + fLink->Attach(bitmapToken); + } + + fLink->Attach(fFrame); + fLink->Attach((uint32)fLook); + fLink->Attach((uint32)fFeel); + fLink->Attach(fFlags); + fLink->Attach(workspace); + fLink->Attach(_get_object_token_(this)); + fLink->Attach(receivePort); + fLink->Attach(fMsgPort); + fLink->AttachString(title); + + port_id sendPort; + int32 code; + if (fLink->FlushWithReply(code) == B_OK + && code == B_OK + && fLink->Read(&sendPort) == B_OK) { + // read the frame size and its limits that were really + // enforced on the server side + + fLink->Read(&fFrame); + fLink->Read(&fMinWidth); + fLink->Read(&fMaxWidth); + fLink->Read(&fMinHeight); + fLink->Read(&fMaxHeight); + + fMaxZoomWidth = fMaxWidth; + fMaxZoomHeight = fMaxHeight; + } else + sendPort = -1; + + // Redirect our link to the new window connection + fLink->SetSenderPort(sendPort); } - fLink->Attach(fFrame); - fLink->Attach((uint32)fLook); - fLink->Attach((uint32)fFeel); - fLink->Attach(fFlags); - fLink->Attach(workspace); - fLink->Attach(_get_object_token_(this)); - fLink->Attach(receivePort); - fLink->Attach(fMsgPort); - fLink->AttachString(title); - - port_id sendPort; - int32 code; - if (fLink->FlushWithReply(code) == B_OK - && code == B_OK - && fLink->Read(&sendPort) == B_OK) { - // read the frame size and its limits that were really - // enforced on the server side - - fLink->Read(&fFrame); - fLink->Read(&fMinWidth); - fLink->Read(&fMaxWidth); - fLink->Read(&fMinHeight); - fLink->Read(&fMaxHeight); - - fMaxZoomWidth = fMaxWidth; - fMaxZoomHeight = fMaxHeight; - } else - sendPort = -1; - - // Redirect our link to the new window connection - fLink->SetSenderPort(sendPort); - - if (locked) - be_app->Unlock(); - STRACE(("Server says that our send port is %ld\n", sendPort)); STRACE(("Window locked?: %s\n", IsLocked() ? "True" : "False")); @@ -2507,6 +2482,35 @@ BWindow::_InitData(BRect frame, const char* title, window_look look, } +//! Rename the handler and its thread +void +BWindow::_SetName(const char *title) +{ + if (title == NULL) + title = ""; + + // we will change BWindow's thread name to "w>window title" + + char threadName[B_OS_NAME_LENGTH]; + strcpy(threadName, "w>"); +#ifdef __HAIKU__ + strlcat(threadName, title, B_OS_NAME_LENGTH); +#else + int32 length = strlen(title); + length = min_c(length, B_OS_NAME_LENGTH - 3); + memcpy(threadName + 2, title, length); + threadName[length + 2] = '\0'; +#endif + + // change the handler's name + SetName(threadName); + + // if the message loop has been started... + if (Thread() >= B_OK) + rename_thread(Thread(), threadName); +} + + //! Reads all pending messages from the window port and put them into the queue. void BWindow::_DequeueAll()