From 4c0269b979e64569c25a44567bb26a33f4877ac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 2 Dec 2005 15:42:28 +0000 Subject: [PATCH] * WindowLayer::OnWorkspace() should now work correctly for all window feels. * introduced ServerApp::OnWorkspace(). * moved AS_CREATE_[OFFSCREEN_]WINDOW into its own method, ServerApp::_CreateWindow(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15283 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/ServerApp.cpp | 207 ++++++++++++++++++-------------- src/servers/app/ServerApp.h | 3 + src/servers/app/WindowLayer.cpp | 32 +++++ src/servers/app/WindowLayer.h | 3 +- 4 files changed, 152 insertions(+), 93 deletions(-) diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index 4374b609eb..8085f68f59 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -79,17 +79,11 @@ using std::nothrow; static const uint32 kMsgAppQuit = 'appQ'; -/*! - \brief Constructor - \param sendport port ID for the BApplication which will receive the ServerApp's messages - \param rcvport port by which the ServerApp will receive messages from its BApplication. - \param fSignature NULL-terminated string which contains the BApplication's - MIME fSignature. -*/ ServerApp::ServerApp(Desktop* desktop, port_id clientReplyPort, - port_id clientLooperPort, team_id clientTeam, int32 clientToken, - const char* signature) + port_id clientLooperPort, team_id clientTeam, + int32 clientToken, const char* signature) : MessageLooper("application"), + fMessagePort(-1), fClientReplyPort(clientReplyPort), fDesktop(desktop), @@ -138,8 +132,7 @@ ServerApp::ServerApp(Desktop* desktop, port_id clientReplyPort, } -//! Does all necessary teardown for application -ServerApp::~ServerApp(void) +ServerApp::~ServerApp() { STRACE(("*ServerApp %s:~ServerApp()\n", Signature())); @@ -419,89 +412,12 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) fDesktop->EventDispatcher().SetTo(gInputManager->GetStream()); break; } + case AS_CREATE_WINDOW: case AS_CREATE_OFFSCREEN_WINDOW: { - // Create a ServerWindow/OffscreenServerWindow - - // Attached data: - // 1) int32 bitmap token (only for AS_CREATE_OFFSCREEN_WINDOW) - // 2) BRect window frame - // 3) uint32 window look - // 4) uint32 window feel - // 5) uint32 window flags - // 6) uint32 workspace index - // 7) int32 BHandler token of the window - // 8) port_id window's reply port - // 9) port_id window's looper port - // 10) const char * title - - BRect frame; - int32 bitmapToken; - uint32 look; - uint32 feel; - uint32 flags; - uint32 workspaces; - int32 token = B_NULL_TOKEN; - port_id clientReplyPort = -1; - port_id looperPort = -1; - char *title = NULL; - - if (code == AS_CREATE_OFFSCREEN_WINDOW) - link.Read(&bitmapToken); - - link.Read(&frame); - link.Read(&look); - link.Read(&feel); - link.Read(&flags); - link.Read(&workspaces); - link.Read(&token); - link.Read(&clientReplyPort); - link.Read(&looperPort); - if (link.ReadString(&title) != B_OK) - break; - - if (!frame.IsValid()) { - // make sure we pass a valid rectangle to ServerWindow - frame.right = frame.left + 1; - frame.bottom = frame.top + 1; - } - - status_t status = B_ERROR; - ServerWindow *window = NULL; - - if (code == AS_CREATE_OFFSCREEN_WINDOW) { - ServerBitmap* bitmap = FindBitmap(bitmapToken); - - if (bitmap != NULL) { - window = new OffscreenServerWindow(title, this, clientReplyPort, - looperPort, token, bitmap); - } - } else { - window = new ServerWindow(title, this, clientReplyPort, looperPort, token); - STRACE(("\nServerApp %s: New Window %s (%g:%g, %g:%g)\n", - fSignature(), title, frame.left, frame.top, - frame.right, frame.bottom)); - } - - free(title); - - // NOTE: the reply to the client is handled in ServerWindow::Run() - if (window != NULL) { - status = window->Init(frame, (window_look)look, (window_feel)feel, - flags, workspaces); - if (status == B_OK && !window->Run()) - status = B_ERROR; - - // add the window to the list - if (status == B_OK && fWindowListLock.Lock()) { - status = fWindowList.AddItem(window) ? B_OK : B_NO_MEMORY; - fWindowListLock.Unlock(); - } - - if (status < B_OK) - delete window; - } + port_id clientReplyPort = -1; + status_t status = _CreateWindow(code, link, clientReplyPort); // if sucessful, ServerWindow::Run() will already have replied if (status < B_OK) { @@ -2406,6 +2322,92 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) } +status_t +ServerApp::_CreateWindow(int32 code, BPrivate::LinkReceiver& link, + port_id& clientReplyPort) +{ + // Attached data: + // 1) int32 bitmap token (only for AS_CREATE_OFFSCREEN_WINDOW) + // 2) BRect window frame + // 3) uint32 window look + // 4) uint32 window feel + // 5) uint32 window flags + // 6) uint32 workspace index + // 7) int32 BHandler token of the window + // 8) port_id window's reply port + // 9) port_id window's looper port + // 10) const char * title + + BRect frame; + int32 bitmapToken; + uint32 look; + uint32 feel; + uint32 flags; + uint32 workspaces; + int32 token; + port_id looperPort; + char* title; + + if (code == AS_CREATE_OFFSCREEN_WINDOW) + link.Read(&bitmapToken); + + link.Read(&frame); + link.Read(&look); + link.Read(&feel); + link.Read(&flags); + link.Read(&workspaces); + link.Read(&token); + link.Read(&clientReplyPort); + link.Read(&looperPort); + if (link.ReadString(&title) != B_OK) + return B_ERROR; + + if (!frame.IsValid()) { + // make sure we pass a valid rectangle to ServerWindow + frame.right = frame.left + 1; + frame.bottom = frame.top + 1; + } + + status_t status = B_ERROR; + ServerWindow *window = NULL; + + if (code == AS_CREATE_OFFSCREEN_WINDOW) { + ServerBitmap* bitmap = FindBitmap(bitmapToken); + + if (bitmap != NULL) { + window = new OffscreenServerWindow(title, this, clientReplyPort, + looperPort, token, bitmap); + } + } else { + window = new ServerWindow(title, this, clientReplyPort, looperPort, token); + STRACE(("\nServerApp %s: New Window %s (%g:%g, %g:%g)\n", + fSignature(), title, frame.left, frame.top, + frame.right, frame.bottom)); + } + + free(title); + + // NOTE: the reply to the client is handled in ServerWindow::Run() + if (window != NULL) { + status = window->Init(frame, (window_look)look, (window_feel)feel, + flags, workspaces); + if (status == B_OK && !window->Run()) + status = B_ERROR; + + // add the window to the list + if (status == B_OK && fWindowListLock.Lock()) { + status = fWindowList.AddItem(window) ? B_OK : B_NO_MEMORY; + fWindowListLock.Unlock(); + } + + if (status < B_OK) + delete window; + } + + return status; +} + + void ServerApp::RemoveWindow(ServerWindow* window) { @@ -2415,6 +2417,29 @@ ServerApp::RemoveWindow(ServerWindow* window) } +bool +ServerApp::OnWorkspace(int32 index) +{ + BAutolock locker(fWindowListLock); + + // we could cache this, but then we'd have to recompute the cached + // 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->GetWindowLayer(); + + // only normal windows count + + if (layer->Feel() == B_NORMAL_WINDOW_FEEL + && layer->OnWorkspace(index)) + return true; + } + + return false; +} + + int32 ServerApp::CountBitmaps() const { diff --git a/src/servers/app/ServerApp.h b/src/servers/app/ServerApp.h index b099f668ae..dde97ebe00 100644 --- a/src/servers/app/ServerApp.h +++ b/src/servers/app/ServerApp.h @@ -64,6 +64,7 @@ class ServerApp : public MessageLooper { const char *Signature() const { return fSignature.String(); } void RemoveWindow(ServerWindow* window); + bool OnWorkspace(int32 index); int32 CountBitmaps() const; ServerBitmap *FindBitmap(int32 token) const; @@ -81,6 +82,8 @@ class ServerApp : public MessageLooper { virtual void _DispatchMessage(int32 code, BPrivate::LinkReceiver &link); virtual void _MessageLooper(); virtual void _GetLooperName(char* name, size_t size); + status_t _CreateWindow(int32 code, BPrivate::LinkReceiver& link, + port_id& clientReplyPort); port_id fMessagePort; port_id fClientReplyPort; diff --git a/src/servers/app/WindowLayer.cpp b/src/servers/app/WindowLayer.cpp index 459aef4262..2044cc9164 100644 --- a/src/servers/app/WindowLayer.cpp +++ b/src/servers/app/WindowLayer.cpp @@ -669,6 +669,38 @@ WindowLayer::UpdateScreen() } +/*! + \brief Returns wether or not the window is visible on the specified + workspace. + + A modal or floating window may be visible on all workscreens one + of its subset windows are visible. +*/ +bool +WindowLayer::OnWorkspace(int32 index) const +{ + if ((fWorkspaces & (1UL << index)) != 0 + || fFeel == B_MODAL_ALL_WINDOW_FEEL + || fFeel == B_FLOATING_ALL_WINDOW_FEEL) + return true; + + if (fFeel == B_MODAL_APP_WINDOW_FEEL + || fFeel == B_FLOATING_APP_WINDOW_FEEL) + return Window()->App()->OnWorkspace(index); + + if (fFeel == B_MODAL_SUBSET_WINDOW_FEEL + || fFeel == B_FLOATING_SUBSET_WINDOW_FEEL) { + for (int32 i = 0; i < fSubsets.CountItems(); i++) { + WindowLayer* window = fSubsets.ItemAt(i); + if (window->OnWorkspace(index)) + return true; + } + } + + return false; +} + + bool WindowLayer::SupportsFront() { diff --git a/src/servers/app/WindowLayer.h b/src/servers/app/WindowLayer.h index 0979c44ad2..12c4174e38 100644 --- a/src/servers/app/WindowLayer.h +++ b/src/servers/app/WindowLayer.h @@ -101,8 +101,7 @@ class WindowLayer : public Layer { uint32 Workspaces() const { return fWorkspaces; } void SetWorkspaces(uint32 workspaces) { fWorkspaces = workspaces; } - bool OnWorkspace(int32 index) const - { return (fWorkspaces & (1UL << index)) != 0; } + bool OnWorkspace(int32 index) const; bool SupportsFront();