From 4d1c4228028075b8982d13c645cd206a28419df7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Tue, 2 Oct 2007 14:09:11 +0000 Subject: [PATCH] * added a way for the ServerWindow message loop to determine the required type of locking before processing the message (single/all window lock) -> in most message cases, I could comment out the unlocking/locking which switched to the different lock, because the required lock is now already held, this removes some race conditions which were commented in the code already * EventDispatcher::SetDragMessage() didn't lock the object, this would have been bad if multiple windows tried to set a drag bitmap at once * the Desktop object keeps track of mouse position and pressed buttons, so that it doesn't need to lock the EventDispatcher for sending fake mouse moves to windows on show/hide of windows (solves some cases of possible dead locks with the new locking strategy) * the keyboard EventFilter switches the current workspace asynchrnously from the Desktop thread (another source of possible deadlocks) * the "reader is trying to become writer" check in MultiLocker is only used in DEBUG mode now As a summary: It would be nice if ServerWindow used a readlock for all messages it processes itself, and forwards all messages for which it needs a write lock to the Desktop thread. All cases where either the Desktop or the ServerWindow mess with the EventDispatcher are possible sources of deadlocks. This is solved right now by making sure that the lock is released before using the EventDispatcher. I have not observed any deadlocks while switching workspaces and launching many apps anymore, neither crashes. But I have not tested extensively except for in the test environment. That being said, I could reproduce the problems on first try before in Haiku. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22410 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/Desktop.cpp | 77 +++++++++++-- src/servers/app/Desktop.h | 12 ++ src/servers/app/EventDispatcher.cpp | 2 + src/servers/app/MultiLocker.cpp | 2 + src/servers/app/ServerWindow.cpp | 172 ++++++++++++++++++++-------- src/servers/app/ServerWindow.h | 4 +- src/servers/app/ViewLayer.cpp | 3 + 7 files changed, 209 insertions(+), 63 deletions(-) diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index df1d36464a..0b26437c30 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -167,7 +167,7 @@ KeyboardFilter::Filter(BMessage* message, EventTarget** _target, { STRACE(("Set Workspace %ld\n", key - 1)); - fDesktop->SetWorkspace(key - 2); + fDesktop->SetWorkspaceAsync(key - 2); return B_SKIP_MESSAGE; } } @@ -228,6 +228,10 @@ MouseFilter::Filter(BMessage* message, EventTarget** _target, int32* _viewToken, if (message->FindPoint("where", &where) != B_OK) return B_DISPATCH_MESSAGE; + int32 buttons; + if (message->FindInt32("buttons", &buttons) != B_OK) + buttons = 0; + if (!fDesktop->LockAllWindows()) return B_DISPATCH_MESSAGE; @@ -271,6 +275,8 @@ MouseFilter::Filter(BMessage* message, EventTarget** _target, int32* _viewToken, *_target = NULL; } + fDesktop->SetLastMouseState(where, buttons); + fDesktop->UnlockAllWindows(); return B_DISPATCH_MESSAGE; @@ -310,10 +316,17 @@ Desktop::Desktop(uid_t userID) fSubsetWindows(kSubsetList), fWorkspacesLayer(NULL), fActiveScreen(NULL), + fWindowLock("window lock"), + + fFocusFollowsMouse(false), + fMouseEventWindow(NULL), fWindowUnderMouse(NULL), fViewUnderMouse(B_NULL_TOKEN), + fLastMousePosition(B_ORIGIN), + fLastMouseButtons(0), + fFocus(NULL), fFront(NULL), fBack(NULL) @@ -605,6 +618,14 @@ Desktop::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) PostMessage(kMsgQuitLooper); break; + case AS_ACTIVATE_WORKSPACE: { + int32 index; + link.Read(&index); + + SetWorkspace(index); + break; + } + default: printf("Desktop %d:%s received unexpected code %ld\n", 0, "baron", code); @@ -660,11 +681,7 @@ Desktop::BroadcastToAllApps(int32 code) } -ServerCursor* -Desktop::Cursor() const -{ - return HWInterface()->Cursor(); -} +// #pragma mark - void @@ -681,6 +698,32 @@ Desktop::SetCursor(ServerCursor* newCursor) } +ServerCursor* +Desktop::Cursor() const +{ + return HWInterface()->Cursor(); +} + + +void +Desktop::SetLastMouseState(const BPoint& position, int32 buttons) +{ + fLastMousePosition = position; + fLastMouseButtons = buttons; +} + + +void +Desktop::GetLastMouseState(BPoint* position, int32* buttons) const +{ + *position = fLastMousePosition; + *buttons = fLastMouseButtons; +} + + +// #pragma mark - + + /*! \brief Redraws the background (ie. the desktop window, if any). */ @@ -769,6 +812,20 @@ Desktop::SetWorkspacesCount(int32 newCount) } +/*! + Changes the current workspace to the one specified by \a index. + You must not hold any window lock when calling this method. +*/ +void +Desktop::SetWorkspaceAsync(int32 index) +{ + BPrivate::LinkSender link(MessagePort()); + link.StartMessage(AS_ACTIVATE_WORKSPACE); + link.Attach(index); + link.Flush(); +} + + /*! Changes the current workspace to the one specified by \a index. You must not hold any window lock when calling this method. @@ -1163,10 +1220,6 @@ Desktop::_WindowChanged(WindowLayer* window) void Desktop::_SendFakeMouseMoved(WindowLayer* window) { - BPoint where; - int32 buttons; - EventDispatcher().GetMouse(where, buttons); - int32 viewToken = B_NULL_TOKEN; EventTarget* target = NULL; @@ -1175,11 +1228,11 @@ Desktop::_SendFakeMouseMoved(WindowLayer* window) if (window == NULL) window = MouseEventWindow(); if (window == NULL) - window = WindowAt(where); + window = WindowAt(fLastMousePosition); if (window != NULL) { BMessage message; - window->MouseMoved(&message, where, &viewToken, true); + window->MouseMoved(&message, fLastMousePosition, &viewToken, true); if (viewToken != B_NULL_TOKEN) target = &window->EventTarget(); diff --git a/src/servers/app/Desktop.h b/src/servers/app/Desktop.h index 3cb5c5654b..6429ff0330 100644 --- a/src/servers/app/Desktop.h +++ b/src/servers/app/Desktop.h @@ -77,6 +77,15 @@ class Desktop : public MessageLooper, public ScreenOwner { void SetCursor(ServerCursor* cursor); ServerCursor* Cursor() const; + void SetLastMouseState(const BPoint& position, + int32 buttons); + // for use by the mouse filter only + // both mouse position calls require + // the Desktop object to be locked + // already + void GetLastMouseState(BPoint* position, + int32* buttons) const; + // for use by ServerWindow void ScreenChanged(Screen* screen, bool makeDefault); @@ -92,6 +101,7 @@ class Desktop : public MessageLooper, public ScreenOwner { // Workspace methods + void SetWorkspaceAsync(int32 index); void SetWorkspace(int32 index); int32 CurrentWorkspace() { return fCurrentWorkspace; } @@ -263,6 +273,8 @@ class Desktop : public MessageLooper, public ScreenOwner { WindowLayer* fMouseEventWindow; const WindowLayer* fWindowUnderMouse; int32 fViewUnderMouse; + BPoint fLastMousePosition; + int32 fLastMouseButtons; WindowLayer* fFocus; WindowLayer* fFront; diff --git a/src/servers/app/EventDispatcher.cpp b/src/servers/app/EventDispatcher.cpp index 0ee42cfd24..e2a3b0af63 100644 --- a/src/servers/app/EventDispatcher.cpp +++ b/src/servers/app/EventDispatcher.cpp @@ -551,6 +551,8 @@ EventDispatcher::SetDragMessage(BMessage& message, { ETRACE(("EventDispatcher::SetDragMessage()\n")); + BAutolock _(this); + if (fDragBitmap != bitmap) { if (fDragBitmap) gBitmapManager->DeleteBitmap(fDragBitmap); diff --git a/src/servers/app/MultiLocker.cpp b/src/servers/app/MultiLocker.cpp index c2ce9d72f4..7853b97c32 100644 --- a/src/servers/app/MultiLocker.cpp +++ b/src/servers/app/MultiLocker.cpp @@ -443,8 +443,10 @@ MultiLocker::WriteLock() locked = true; } else { // new writer acquiring the lock +#if DEBUG if (IsReadLocked()) debugger("Reader wants to become writer!"); +#endif status_t status; do { diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index f5a1d8c11c..de5ba3cf8d 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -368,11 +368,16 @@ ServerWindow::_Show() if (fQuitting || !fWindowLayer->IsHidden() || fWindowLayer->IsOffscreenWindow()) return; -// TODO: race condition? maybe we need to dispatch a message to the desktop to show/hide us +// TODO: deadlock. Desktop::ShowWindow() will eventually lock the event thread, +// which might be blocking on the all window lock with it's own lock already +// head. +// Maybe we need to dispatch a message to the desktop to show/hide us // instead of doing it from this thread. -fDesktop->UnlockSingleWindow(); +//fDesktop->UnlockSingleWindow(); +fDesktop->UnlockAllWindows(); fDesktop->ShowWindow(fWindowLayer); -fDesktop->LockSingleWindow(); +fDesktop->LockAllWindows(); +//fDesktop->LockSingleWindow(); if (fDirectWindowData != NULL) HandleDirectConnection(B_DIRECT_START | B_BUFFER_RESET); @@ -394,9 +399,7 @@ ServerWindow::_Hide() // TODO: race condition? maybe we need to dispatch a message to the desktop to show/hide us // instead of doing it from this thread. -fDesktop->UnlockSingleWindow(); fDesktop->HideWindow(fWindowLayer); -fDesktop->LockSingleWindow(); } @@ -436,9 +439,9 @@ ServerWindow::SetTitle(const char* newTitle) } if (fWindowLayer != NULL) { -fDesktop->UnlockSingleWindow(); +//fDesktop->UnlockSingleWindow(); fDesktop->SetWindowTitle(fWindowLayer, newTitle); -fDesktop->LockSingleWindow(); +//fDesktop->LockSingleWindow(); } } @@ -586,12 +589,18 @@ ServerWindow::_CreateLayerTree(BPrivate::LinkReceiver &link, ViewLayer **_parent newLayer->SetEventMask(eventMask, eventOptions); if (eventMask != 0 || eventOptions != 0) { - fDesktop->UnlockSingleWindow(); +// fDesktop->UnlockSingleWindow(); +// fDesktop->LockAllWindows(); +fDesktop->UnlockAllWindows(); + // TODO: possible deadlock fDesktop->EventDispatcher().AddListener(EventTarget(), newLayer->Token(), eventMask, eventOptions); - fDesktop->LockSingleWindow(); +fDesktop->LockAllWindows(); +// fDesktop->UnlockAllWindows(); +// fDesktop->LockSingleWindow(); } + // TODO: default fonts should be created and stored in the Application DesktopSettings settings(fDesktop); ServerFont font; settings.GetDefaultPlainFont(font); @@ -661,12 +670,12 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) link.Read(&activate); -fDesktop->UnlockSingleWindow(); +//fDesktop->UnlockSingleWindow(); if (activate) fDesktop->ActivateWindow(fWindowLayer); else fDesktop->SendWindowBehind(fWindowLayer, NULL); -fDesktop->LockSingleWindow(); +//fDesktop->LockSingleWindow(); break; } case AS_SEND_BEHIND: @@ -681,10 +690,10 @@ fDesktop->LockSingleWindow(); WindowLayer *behindOf; if ((behindOf = fDesktop->FindWindowLayerByClientToken(token, teamID)) != NULL) { -fDesktop->UnlockSingleWindow(); +//fDesktop->UnlockSingleWindow(); // TODO: there is a big race condition when we unlock here (window could be gone by now)! fDesktop->SendWindowBehind(fWindowLayer, behindOf); -fDesktop->LockSingleWindow(); +//fDesktop->LockSingleWindow(); status = B_OK; } else status = B_NAME_NOT_FOUND; @@ -748,11 +757,11 @@ fDesktop->LockSingleWindow(); || windowLayer->Feel() != B_NORMAL_WINDOW_FEEL) { status = B_BAD_VALUE; } else { -fDesktop->UnlockSingleWindow(); +//fDesktop->UnlockSingleWindow(); // TODO: there is a big race condition when we unlock here (window could be gone by now)! status = fDesktop->AddWindowToSubset(fWindowLayer, windowLayer) ? B_OK : B_NO_MEMORY; -fDesktop->LockSingleWindow(); +//fDesktop->LockSingleWindow(); } } @@ -770,10 +779,10 @@ fDesktop->LockSingleWindow(); WindowLayer* windowLayer = fDesktop->FindWindowLayerByClientToken( token, App()->ClientTeam()); if (windowLayer != NULL) { -fDesktop->UnlockSingleWindow(); +//fDesktop->UnlockSingleWindow(); // TODO: there is a big race condition when we unlock here (window could be gone by now)! fDesktop->RemoveWindowFromSubset(fWindowLayer, windowLayer); -fDesktop->LockSingleWindow(); +//fDesktop->LockSingleWindow(); status = B_OK; } else status = B_BAD_VALUE; @@ -797,9 +806,9 @@ fDesktop->LockSingleWindow(); } if (status == B_OK && !fWindowLayer->IsOffscreenWindow()) { -fDesktop->UnlockSingleWindow(); +//fDesktop->UnlockSingleWindow(); fDesktop->SetWindowLook(fWindowLayer, (window_look)look); -fDesktop->LockSingleWindow(); +//fDesktop->LockSingleWindow(); } fLink.StartMessage(status); @@ -819,9 +828,9 @@ fDesktop->LockSingleWindow(); } if (status == B_OK && !fWindowLayer->IsOffscreenWindow()) { -fDesktop->UnlockSingleWindow(); +//fDesktop->UnlockSingleWindow(); fDesktop->SetWindowFeel(fWindowLayer, (window_feel)feel); -fDesktop->LockSingleWindow(); +//fDesktop->LockSingleWindow(); } fLink.StartMessage(status); @@ -841,9 +850,9 @@ fDesktop->LockSingleWindow(); } if (status == B_OK && !fWindowLayer->IsOffscreenWindow()) { -fDesktop->UnlockSingleWindow(); +//fDesktop->UnlockSingleWindow(); fDesktop->SetWindowFlags(fWindowLayer, flags); -fDesktop->LockSingleWindow(); +//fDesktop->LockSingleWindow(); } fLink.StartMessage(status); @@ -886,9 +895,9 @@ fDesktop->LockSingleWindow(); STRACE(("ServerWindow %s: Message AS_SET_WORKSPACES %lx\n", Title(), newWorkspaces)); -fDesktop->UnlockSingleWindow(); +//fDesktop->UnlockSingleWindow(); fDesktop->SetWindowWorkspaces(fWindowLayer, newWorkspaces); -fDesktop->LockSingleWindow(); +//fDesktop->LockSingleWindow(); break; } case AS_WINDOW_RESIZE: @@ -907,9 +916,9 @@ fDesktop->LockSingleWindow(); // pragmatically set window bounds fLink.StartMessage(B_BUSY); } else { -fDesktop->UnlockSingleWindow(); +//fDesktop->UnlockSingleWindow(); fDesktop->ResizeWindowBy(fWindowLayer, xResizeBy, yResizeBy); -fDesktop->LockSingleWindow(); +//fDesktop->LockSingleWindow(); fLink.StartMessage(B_OK); } fLink.Flush(); @@ -931,9 +940,9 @@ fDesktop->LockSingleWindow(); // pragmatically set window positions fLink.StartMessage(B_BUSY); } else { -fDesktop->UnlockSingleWindow(); +//fDesktop->UnlockSingleWindow(); fDesktop->MoveWindowBy(fWindowLayer, xMoveBy, yMoveBy); -fDesktop->LockSingleWindow(); +//fDesktop->LockSingleWindow(); fLink.StartMessage(B_OK); } fLink.Flush(); @@ -960,7 +969,7 @@ fDesktop->LockSingleWindow(); link.Read(&minHeight); link.Read(&maxHeight); */ - fDesktop->UnlockSingleWindow(); +//fDesktop->UnlockSingleWindow(); if (fDesktop->LockAllWindows()) { fWindowLayer->SetSizeLimits(minWidth, maxWidth, @@ -968,7 +977,7 @@ fDesktop->LockSingleWindow(); fDesktop->UnlockAllWindows(); } - fDesktop->LockSingleWindow(); +//fDesktop->LockSingleWindow(); // and now, sync the client to the limits that we were able to enforce fWindowLayer->GetSizeLimits(&minWidth, &maxWidth, @@ -995,9 +1004,9 @@ fDesktop->LockSingleWindow(); if (link.Read(buffer, size) == B_OK) { BMessage settings; if (settings.Unflatten(buffer) == B_OK) { -fDesktop->UnlockSingleWindow(); +//fDesktop->UnlockSingleWindow(); fDesktop->SetWindowDecoratorSettings(fWindowLayer, settings); -fDesktop->LockSingleWindow(); +//fDesktop->LockSingleWindow(); } } } @@ -1058,15 +1067,15 @@ fDesktop->LockSingleWindow(); { DTRACE(("ServerWindow %s: Message AS_GET_MOUSE\n", fTitle)); - fDesktop->UnlockSingleWindow(); +//fDesktop->UnlockSingleWindow(); // Returns // 1) BPoint mouse location // 2) int32 button state BPoint where; int32 buttons; - fDesktop->EventDispatcher().GetMouse(where, buttons); - fDesktop->LockSingleWindow(); + fDesktop->GetLastMouseState(&where, &buttons); +//fDesktop->LockSingleWindow(); fLink.StartMessage(B_OK); fLink.Attach(where); @@ -1103,10 +1112,10 @@ fDesktop->LockSingleWindow(); status_t status = B_OK; if (!fWindowLayer->IsOffscreenWindow()) { - fDesktop->UnlockSingleWindow(); +//fDesktop->UnlockSingleWindow(); fDesktop->SetWindowFeel(fWindowLayer, enable ? kWindowScreenFeel : B_NORMAL_WINDOW_FEEL); - fDesktop->LockSingleWindow(); +//fDesktop->LockSingleWindow(); } else status = B_BAD_TYPE; @@ -1246,8 +1255,14 @@ ServerWindow::_DispatchViewMessage(int32 code, parent->RemoveChild(view); if (view->EventMask() != 0) { - fDesktop->EventDispatcher().RemoveListener(EventTarget(), - token); + // TODO: possible deadlock (event dispatcher already + // locked itself, waits for Desktop write lock, but + // we have it, now we are trying to lock the event + // dispatcher -> deadlock) +fDesktop->UnlockSingleWindow(); + fDesktop->EventDispatcher().RemoveListener( + EventTarget(), token); +fDesktop->LockSingleWindow(); } if (fCurrentLayer == view) _SetCurrentLayer(parent); @@ -1288,14 +1303,15 @@ ServerWindow::_DispatchViewMessage(int32 code, } case AS_LAYER_SET_EVENT_MASK: { - STRACE(("ServerWindow %s: Message AS_LAYER_SET_MOUSE_EVENT_MASK: ViewLayer name: %s\n", fTitle, fCurrentLayer->Name())); + STRACE(("ServerWindow %s: Message AS_LAYER_SET_EVENT_MASK: ViewLayer name: %s\n", fTitle, fCurrentLayer->Name())); uint32 eventMask, options; link.Read(&eventMask); if (link.Read(&options) == B_OK) { - fDesktop->UnlockSingleWindow(); fCurrentLayer->SetEventMask(eventMask, options); +fDesktop->UnlockSingleWindow(); + // TODO: possible deadlock! if (eventMask != 0 || options != 0) { fDesktop->EventDispatcher().AddListener(EventTarget(), fCurrentLayer->Token(), eventMask, options); @@ -1303,7 +1319,7 @@ ServerWindow::_DispatchViewMessage(int32 code, fDesktop->EventDispatcher().RemoveListener(EventTarget(), fCurrentLayer->Token()); } - fDesktop->LockSingleWindow(); +fDesktop->LockSingleWindow(); } break; } @@ -1314,7 +1330,8 @@ ServerWindow::_DispatchViewMessage(int32 code, link.Read(&eventMask); if (link.Read(&options) == B_OK) { - fDesktop->UnlockSingleWindow(); +fDesktop->UnlockSingleWindow(); + // TODO: possible deadlock if (eventMask != 0 || options != 0) { fDesktop->EventDispatcher().AddTemporaryListener(EventTarget(), fCurrentLayer->Token(), eventMask, options); @@ -1322,7 +1339,7 @@ ServerWindow::_DispatchViewMessage(int32 code, fDesktop->EventDispatcher().RemoveTemporaryListener(EventTarget(), fCurrentLayer->Token()); } - fDesktop->LockSingleWindow(); +fDesktop->LockSingleWindow(); } // TODO: support B_LOCK_WINDOW_FOCUS option in Desktop @@ -1896,8 +1913,11 @@ ServerWindow::_DispatchViewMessage(int32 code, if (link.Read(buffer, bufferSize) == B_OK && dragMessage.Unflatten(buffer) == B_OK) { ServerBitmap* bitmap = fServerApp->FindBitmap(bitmapToken); + // TODO: possible deadlock +fDesktop->UnlockSingleWindow(); fDesktop->EventDispatcher().SetDragMessage(dragMessage, - bitmap, offset); + bitmap, offset); +fDesktop->LockSingleWindow(); } delete[] buffer; } @@ -1925,8 +1945,11 @@ ServerWindow::_DispatchViewMessage(int32 code, BMessage dragMessage; if (link.Read(buffer, bufferSize) == B_OK && dragMessage.Unflatten(buffer) == B_OK) { + // TODO: possible deadlock +fDesktop->UnlockSingleWindow(); fDesktop->EventDispatcher().SetDragMessage(dragMessage, NULL /* should be dragRect */, offset); +fDesktop->LockSingleWindow(); } delete[] buffer; } @@ -2857,6 +2880,7 @@ ServerWindow::_MessageLooper() int32 messagesProcessed = 0; bool lockedDesktop = false; + bool needsAllWindowsLocked = false; while (true) { if (code == AS_DELETE_WINDOW || code == kMsgQuitLooper) { @@ -2881,10 +2905,21 @@ ServerWindow::_MessageLooper() break; } - if (!lockedDesktop) { + needsAllWindowsLocked = _MessageNeedsAllWindowsLocked(code); + + if (!lockedDesktop && !needsAllWindowsLocked) { // only lock it once fDesktop->LockSingleWindow(); lockedDesktop = true; + } else if (lockedDesktop && !needsAllWindowsLocked) { + // nothing to do + } else if (needsAllWindowsLocked) { + if (lockedDesktop) { + // unlock single before locking all + fDesktop->UnlockSingleWindow(); + lockedDesktop = false; + } + fDesktop->LockAllWindows(); } if (atomic_and(&fRedrawRequested, 0) != 0) { @@ -2902,7 +2937,6 @@ ServerWindow::_MessageLooper() # endif #endif } - #ifdef PROFILE_MESSAGE_LOOP @@ -2924,9 +2958,13 @@ ServerWindow::_MessageLooper() } #endif + if (needsAllWindowsLocked) + fDesktop->UnlockAllWindows(); + // only process up to 70 waiting messages at once (we have the Desktop locked) if (!receiver.HasMessages() || ++messagesProcessed > 70) { - fDesktop->UnlockSingleWindow(); + if (lockedDesktop) + fDesktop->UnlockSingleWindow(); break; } @@ -2935,7 +2973,8 @@ ServerWindow::_MessageLooper() if (status < B_OK) { // that shouldn't happen, it's our port printf("Someone deleted our message port!\n"); - fDesktop->UnlockSingleWindow(); + if (lockedDesktop) + fDesktop->UnlockSingleWindow(); // try to let our client die happily NotifyQuitRequested(); @@ -3152,6 +3191,39 @@ ServerWindow::_UpdateDrawState(ViewLayer* layer) } +bool +ServerWindow::_MessageNeedsAllWindowsLocked(uint32 code) const +{ + switch (code) { + case AS_SHOW_WINDOW: + case AS_HIDE_WINDOW: + case AS_MINIMIZE_WINDOW: + case AS_ACTIVATE_WINDOW: + case AS_SET_WINDOW_TITLE: + case AS_ADD_TO_SUBSET: + case AS_REMOVE_FROM_SUBSET: + case AS_LAYER_CREATE_ROOT: + case AS_LAYER_CREATE: + case AS_SEND_BEHIND: + case AS_SET_LOOK: + case AS_SET_FEEL: + case AS_SET_FLAGS: + case AS_SET_WORKSPACES: + case AS_WINDOW_MOVE: + case AS_WINDOW_RESIZE: + case AS_SET_SIZE_LIMITS: + case AS_SET_DECORATOR_SETTINGS: + case AS_GET_MOUSE: + case AS_DIRECT_WINDOW_SET_FULLSCREEN: +// case AS_LAYER_SET_EVENT_MASK: +// case AS_LAYER_SET_MOUSE_EVENT_MASK: + return true; + default: + return false; + } +} + + status_t ServerWindow::PictureToRegion(ServerPicture *picture, BRegion ®ion, bool inverse, BPoint where) diff --git a/src/servers/app/ServerWindow.h b/src/servers/app/ServerWindow.h index 41d53ce94f..3cedb2ae7d 100644 --- a/src/servers/app/ServerWindow.h +++ b/src/servers/app/ServerWindow.h @@ -127,6 +127,8 @@ private: void _SetCurrentLayer(ViewLayer* view); void _UpdateDrawState(ViewLayer* view); + bool _MessageNeedsAllWindowsLocked(uint32 code) const; + // TODO: Move me elsewhere status_t PictureToRegion(ServerPicture *picture, BRegion &, @@ -158,7 +160,7 @@ private: ViewLayer* fCurrentLayer; BRegion fCurrentDrawingRegion; bool fCurrentDrawingRegionValid; - + direct_window_data* fDirectWindowData; }; diff --git a/src/servers/app/ViewLayer.cpp b/src/servers/app/ViewLayer.cpp index f12946eb88..0bb832f418 100644 --- a/src/servers/app/ViewLayer.cpp +++ b/src/servers/app/ViewLayer.cpp @@ -1289,6 +1289,9 @@ ViewLayer::Draw(DrawingEngine* drawingEngine, BRegion* effectiveClipping, } +// #pragma mark - + + void ViewLayer::MouseDown(BMessage* message, BPoint where) {