diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index fda000f29a..8e9130f6c7 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -2021,7 +2021,7 @@ Desktop::SetViewUnderMouse(const WindowLayer* window, int32 viewToken) int32 Desktop::ViewUnderMouse(const WindowLayer* window) { - if (fWindowUnderMouse == window) + if (window != NULL && fWindowUnderMouse == window) return fViewUnderMouse; return B_NULL_TOKEN; @@ -2086,16 +2086,18 @@ Desktop::WindowAction(int32 windowToken, int32 action) LockAllWindows(); ::ServerWindow* serverWindow; + WindowLayer* window; if (BPrivate::gDefaultTokens.GetToken(windowToken, - B_SERVER_TOKEN, (void**)&serverWindow) != B_OK) { + B_SERVER_TOKEN, (void**)&serverWindow) != B_OK + || (window = serverWindow->Window()) == NULL) { UnlockAllWindows(); return; } if (action == B_BRING_TO_FRONT - && !serverWindow->Window()->IsMinimized()) { + && !window->IsMinimized()) { // the window is visible, we just need to make it the front window - ActivateWindow(serverWindow->Window()); + ActivateWindow(window); } else serverWindow->NotifyMinimize(action == B_MINIMIZE_WINDOW); diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index 7e4162bab4..fc9697118b 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -271,9 +271,9 @@ ServerApp::_HasWindowUnderMouse() BAutolock locker(fWindowListLock); for (int32 i = fWindowList.CountItems(); i-- > 0;) { - ServerWindow* window = fWindowList.ItemAt(i); + ServerWindow* serverWindow = fWindowList.ItemAt(i); - if (fDesktop->ViewUnderMouse(window->Window()) != B_NULL_TOKEN) + if (fDesktop->ViewUnderMouse(serverWindow->Window()) != B_NULL_TOKEN) return true; } @@ -439,7 +439,10 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) if (fWindowListLock.Lock()) { for (int32 i = fWindowList.CountItems(); i-- > 0;) { ServerWindow* serverWindow = fWindowList.ItemAt(i); + WindowLayer* window = serverWindow->Window(); + if (window == NULL || window->IsOffscreenWindow()) + continue; if (window->Feel() == kWindowScreenFeel) fDesktop->SetWindowFeel(window, B_NORMAL_WINDOW_FEEL); @@ -2479,12 +2482,15 @@ ServerApp::InWorkspace(int32 index) const // TODO: support initial application workspace! for (int32 i = fWindowList.CountItems(); i-- > 0;) { - ServerWindow* window = fWindowList.ItemAt(i); - const WindowLayer* layer = window->Window(); + ServerWindow* serverWindow = fWindowList.ItemAt(i); + + const WindowLayer* window = serverWindow->Window(); + if (window == NULL || window->IsOffscreenWindow()) + continue; // only normal and unhidden windows count - if (layer->IsNormal() && !layer->IsHidden() && layer->InWorkspace(index)) + if (window->IsNormal() && !window->IsHidden() && window->InWorkspace(index)) return true; } @@ -2503,13 +2509,16 @@ ServerApp::Workspaces() const // value everytime a window has closed or changed workspaces for (int32 i = fWindowList.CountItems(); i-- > 0;) { - ServerWindow* window = fWindowList.ItemAt(i); - const WindowLayer* layer = window->Window(); + ServerWindow* serverWindow = fWindowList.ItemAt(i); + + const WindowLayer* window = serverWindow->Window(); + if (window == NULL || window->IsOffscreenWindow()) + continue; // only normal and unhidden windows count - if (layer->IsNormal() && !layer->IsHidden()) - workspaces |= layer->Workspaces(); + if (window->IsNormal() && !window->IsHidden()) + workspaces |= window->Workspaces(); } // TODO: add initial application workspace! diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 3cbcd94630..6e216babf2 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -151,6 +151,7 @@ ServerWindow::ServerWindow(const char *title, ServerApp *app, fDesktop(app->GetDesktop()), fServerApp(app), fWindowLayer(NULL), + fWindowAddedToDesktop(false), fClientTeam(app->ClientTeam()), @@ -187,14 +188,16 @@ ServerWindow::~ServerWindow() { STRACE(("ServerWindow(%s@%p):~ServerWindow()\n", fTitle, this)); - if (!fWindowLayer->IsOffscreenWindow()) + if (!fWindowLayer->IsOffscreenWindow()) { + fWindowAddedToDesktop = false; fDesktop->RemoveWindow(fWindowLayer); - - delete fWindowLayer; + } if (App() != NULL) App()->RemoveWindow(this); + delete fWindowLayer; + free(fTitle); delete_port(fMessagePort); @@ -243,8 +246,10 @@ ServerWindow::Init(BRect frame, window_look look, window_feel feel, if (!fWindowLayer) return B_NO_MEMORY; - if (!fWindowLayer->IsOffscreenWindow()) + if (!fWindowLayer->IsOffscreenWindow()) { fDesktop->AddWindow(fWindowLayer); + fWindowAddedToDesktop = true; + } return B_OK; } @@ -459,10 +464,19 @@ ServerWindow::GetInfo(window_info& info) } +/*! + Returns the ServerWindow's WindowLayer, if it exists and has been + added to the Desktop already. + In other words, you cannot assume this method will always give you + a valid pointer. +*/ WindowLayer* ServerWindow::Window() const { // TODO: ensure desktop is locked! + if (!fWindowAddedToDesktop) + return NULL; + return fWindowLayer; } @@ -833,7 +847,7 @@ fDesktop->LockSingleWindow(); STRACE(("ServerWindow %s: Message AS_WINDOW_RESIZE %.1f, %.1f\n", Title(), xResizeBy, yResizeBy)); - if (Window()->IsResizing()) { + if (fWindowLayer->IsResizing()) { // While the user resizes the window, we ignore // pragmatically set window bounds fLink.StartMessage(B_BUSY); @@ -857,7 +871,7 @@ fDesktop->LockSingleWindow(); STRACE(("ServerWindow %s: Message AS_WINDOW_MOVE: %.1f, %.1f\n", Title(), xMoveBy, yMoveBy)); - if (Window()->IsDragging()) { + if (fWindowLayer->IsDragging()) { // While the user moves the window, we ignore // pragmatically set window positions fLink.StartMessage(B_BUSY); diff --git a/src/servers/app/ServerWindow.h b/src/servers/app/ServerWindow.h index 9c1c79f875..4e3bd379ce 100644 --- a/src/servers/app/ServerWindow.h +++ b/src/servers/app/ServerWindow.h @@ -136,6 +136,7 @@ private: ::Desktop* fDesktop; ServerApp* fServerApp; WindowLayer* fWindowLayer; + bool fWindowAddedToDesktop; team_id fClientTeam;