* 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
This commit is contained in:
Axel Dörfler
2005-12-02 15:42:28 +00:00
parent 48ccf5abef
commit 4c0269b979
4 changed files with 152 additions and 93 deletions
+116 -91
View File
@@ -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<int32>(&bitmapToken);
link.Read<BRect>(&frame);
link.Read<uint32>(&look);
link.Read<uint32>(&feel);
link.Read<uint32>(&flags);
link.Read<uint32>(&workspaces);
link.Read<int32>(&token);
link.Read<port_id>(&clientReplyPort);
link.Read<port_id>(&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<int32>(&bitmapToken);
link.Read<BRect>(&frame);
link.Read<uint32>(&look);
link.Read<uint32>(&feel);
link.Read<uint32>(&flags);
link.Read<uint32>(&workspaces);
link.Read<int32>(&token);
link.Read<port_id>(&clientReplyPort);
link.Read<port_id>(&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
{
+3
View File
@@ -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;
+32
View File
@@ -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()
{
+1 -2
View File
@@ -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();