diff --git a/src/servers/app/server/Layer.cpp b/src/servers/app/server/Layer.cpp index b8614f981f..25a6e45b2e 100644 --- a/src/servers/app/server/Layer.cpp +++ b/src/servers/app/server/Layer.cpp @@ -50,7 +50,7 @@ # define STRACE(x) ; #endif -#define DEBUG_LAYER_REBUILD +//#define DEBUG_LAYER_REBUILD #ifdef DEBUG_LAYER_REBUILD # define RBTRACE(x) printf x #else @@ -763,7 +763,7 @@ void Layer::RebuildFullRegion(void) void Layer::RebuildRegions( const BRegion& reg, uint32 action, BPoint pt, BPoint ptOffset) { STRACE(("Layer(%s)::RebuildRegions() START\n", GetName())); - + // TODO:/NOTE: this method must be executed as quickly as possible. // Currently SendView[Moved/Resized]Msg() simply constructs a message and calls @@ -876,12 +876,12 @@ void Layer::RebuildRegions( const BRegion& reg, uint32 action, BPoint pt, BPoint if (!IsHidden()) { - fFullVisible.MakeEmpty(); - fVisible = fFull; #ifdef DEBUG_LAYER_REBUILD printf("Layer(%s) real action START\n", GetName()); fFull.PrintToStream(); #endif + fFullVisible.MakeEmpty(); + fVisible = fFull; if (fParent && fVisible.CountRects() > 0) { diff --git a/src/servers/app/server/RootLayer.cpp b/src/servers/app/server/RootLayer.cpp index 899b0db51c..9f4ec469e9 100644 --- a/src/servers/app/server/RootLayer.cpp +++ b/src/servers/app/server/RootLayer.cpp @@ -539,6 +539,7 @@ void RootLayer::RemoveSubsetWinBorder(WinBorder *winBorder, WinBorder *fromWinBo void RootLayer::SetActiveWorkspace(int32 index) { STRACE(("RootLayer(%s)::SetActiveWorkspace(%ld)\n", GetName(), index)); + // we need to lock the window list here so no other window can be created desktop->Lock(); // if fWorkspace[index] object does not exist, create and add allowed WinBorders @@ -896,9 +897,9 @@ bool RootLayer::SetScreenResolution(int32 width, int32 height, uint32 colorspace //--------------------------------------------------------------------------- // Input related methods //--------------------------------------------------------------------------- +inline void RootLayer::MouseEventHandler(int32 code, BPortLink& msg) { - // TODO: locking mechanism needs SERIOUS rethought switch(code) { case B_MOUSE_DOWN: @@ -956,12 +957,11 @@ void RootLayer::MouseEventHandler(int32 code, BPortLink& msg) } else { - if (!(target->Window()->Flags() & B_WILL_ACCEPT_FIRST_CLICK)) + if (exFocus != FocusWinBorder() + && !(target->Window()->Flags() & B_WILL_ACCEPT_FIRST_CLICK)) sendMessage = false; - target->Window()->Lock(); target->MouseDown(evt, sendMessage); - target->Window()->Unlock(); } fMouseTarget = target; @@ -991,9 +991,7 @@ void RootLayer::MouseEventHandler(int32 code, BPortLink& msg) // currently mouse up goes to the same window which received mouse down if (fMouseTarget) { - fMouseTarget->Window()->Lock(); fMouseTarget->MouseUp(evt); - fMouseTarget->Window()->Unlock(); fMouseTarget = NULL; } @@ -1042,9 +1040,7 @@ void RootLayer::MouseEventHandler(int32 code, BPortLink& msg) } else { - fMouseTarget->Window()->Lock(); fMouseTarget->MouseMoved(evt); - fMouseTarget->Window()->Unlock(); } } else @@ -1052,9 +1048,7 @@ void RootLayer::MouseEventHandler(int32 code, BPortLink& msg) WinBorder *target = WinBorderAt(evt.where); if (target) { - target->Window()->Lock(); target->MouseMoved(evt); - target->Window()->Unlock(); } } @@ -1077,9 +1071,7 @@ void RootLayer::MouseEventHandler(int32 code, BPortLink& msg) if (FocusWinBorder()) { BPoint cursorPos = GetDisplayDriver()->GetCursorPosition(); - FocusWinBorder()->Window()->Lock(); FocusWinBorder()->MouseWheel(evt, cursorPos); - FocusWinBorder()->Window()->Unlock(); } break; } @@ -1091,6 +1083,7 @@ void RootLayer::MouseEventHandler(int32 code, BPortLink& msg) } } +inline void RootLayer::KeyboardEventHandler(int32 code, BPortLink& msg) { @@ -1268,8 +1261,6 @@ void RootLayer::KeyboardEventHandler(int32 code, BPortLink& msg) Workspace *ws=ActiveWorkspace(); - Lock(); - WinBorder *target=ws->Focus(); if(target) { @@ -1295,8 +1286,6 @@ void RootLayer::KeyboardEventHandler(int32 code, BPortLink& msg) } } - Unlock(); - if (string) free(string); break; @@ -1364,8 +1353,6 @@ void RootLayer::KeyboardEventHandler(int32 code, BPortLink& msg) Workspace *ws=ActiveWorkspace(); - Lock(); - WinBorder *target=ws->Focus(); if(target) { @@ -1389,8 +1376,6 @@ void RootLayer::KeyboardEventHandler(int32 code, BPortLink& msg) } } - Unlock(); - if (string) free(string); break; @@ -1416,8 +1401,6 @@ void RootLayer::KeyboardEventHandler(int32 code, BPortLink& msg) Workspace *ws=ActiveWorkspace(); - Lock(); - WinBorder *target=ws->Focus(); if(target) { @@ -1434,7 +1417,6 @@ void RootLayer::KeyboardEventHandler(int32 code, BPortLink& msg) } } - Unlock(); break; } case B_UNMAPPED_KEY_UP: @@ -1458,8 +1440,6 @@ void RootLayer::KeyboardEventHandler(int32 code, BPortLink& msg) Workspace *ws=ActiveWorkspace(); - Lock(); - WinBorder *target=ws->Focus(); if(target) { @@ -1476,7 +1456,6 @@ void RootLayer::KeyboardEventHandler(int32 code, BPortLink& msg) } } - Unlock(); break; } case B_MODIFIERS_CHANGED: @@ -1498,8 +1477,6 @@ void RootLayer::KeyboardEventHandler(int32 code, BPortLink& msg) Workspace *ws=ActiveWorkspace(); - Lock(); - WinBorder *target=ws->Focus(); if(target) { @@ -1515,7 +1492,7 @@ void RootLayer::KeyboardEventHandler(int32 code, BPortLink& msg) win->SendMessageToClient(&keymsg); } } - Unlock(); + break; } default: diff --git a/src/servers/app/server/ServerWindow.cpp b/src/servers/app/server/ServerWindow.cpp index c254715322..0c891760d6 100644 --- a/src/servers/app/server/ServerWindow.cpp +++ b/src/servers/app/server/ServerWindow.cpp @@ -249,9 +249,7 @@ void ServerWindow::ReplaceDecorator(void) //! Requests that the ServerWindow's BWindow quit void ServerWindow::Quit(void) { - if (!IsLocked()) - debugger("you must lock a ServerWindow object before calling ::Quit()\n"); - + // NOTE: if you do something else, other than sending a port message, PLEASE lock STRACE(("ServerWindow %s: Quit\n",fTitle.String())); BMessage msg; @@ -263,9 +261,8 @@ void ServerWindow::Quit(void) //! Shows the window's WinBorder void ServerWindow::Show(void) { + // NOTE: if you do something else, other than sending a port message, PLEASE lock STRACE(("ServerWindow %s: Show\n",fTitle.String())); - if (!IsLocked()) - debugger("you must lock a ServerWindow object before calling ::Show()\n"); if(!fWinBorder->IsHidden()) return; @@ -276,9 +273,8 @@ void ServerWindow::Show(void) //! Hides the window's WinBorder void ServerWindow::Hide(void) { + // NOTE: if you do something else, other than sending a port message, PLEASE lock STRACE(("ServerWindow %s: Hide\n",fTitle.String())); - if (!IsLocked()) - debugger("you must lock a ServerWindow object before calling ::Hide()\n"); if(fWinBorder->IsHidden()) return; @@ -297,10 +293,10 @@ bool ServerWindow::IsHidden(void) const //------------------------------------------------------------------------------ void ServerWindow::Minimize(bool status) { + // NOTE: if you do something else, other than sending a port message, PLEASE lock // This function doesn't need much -- check to make sure that we should and // send the message to the client. According to the BeBook, the BWindow hook function // does all the heavy lifting for us. :) - bool sendMessages = false; if (status) @@ -334,6 +330,7 @@ void ServerWindow::Minimize(bool status) // Sends a message to the client to perform a Zoom void ServerWindow::Zoom(void) { + // NOTE: if you do something else, other than sending a port message, PLEASE lock BMessage msg; msg.what=B_ZOOM; SendMessageToClient(&msg); diff --git a/src/servers/app/server/WinBorder.cpp b/src/servers/app/server/WinBorder.cpp index d41e8d9966..2db690af78 100644 --- a/src/servers/app/server/WinBorder.cpp +++ b/src/servers/app/server/WinBorder.cpp @@ -163,79 +163,74 @@ click_type WinBorder::TellWhat(PointerEvent& evt) const */ void WinBorder::MouseDown(PointerEvent& evt, bool sendMessage) { - if (!(Window()->IsLocked())) - debugger("you must lock the attached ServerWindow object\n\t before calling WinBorder::MouseDown()\n"); + // user clicked on WinBorder's full visible region, + // find out if the user clicked the decorator. - // this is important to determine how much we should resize or move the Layer(WinBorder)(window) + click_type action; - // user clicked on WinBorder's visible region, which is in fact decorator's. - // so, if true, we find out if the user clicked the decorator. - - Layer *target = LayerAt(evt.where); - if (target == this) + // find out where user clicked in Decorator + action = fDecorator->Clicked(evt.where, evt.buttons, evt.modifiers); + switch(action) { - click_type action; - - // find out where user clicked in Decorator - action = fDecorator->Clicked(evt.where, evt.buttons, evt.modifiers); - switch(action) + case DEC_CLOSE: { - case DEC_CLOSE: + fIsClosing = true; + fDecorator->SetClose(true); + fDecorator->DrawClose(); + STRACE_CLICK(("===> DEC_CLOSE\n")); + break; + } + case DEC_ZOOM: + { + fIsZooming = true; + fDecorator->SetZoom(true); + fDecorator->DrawZoom(); + STRACE_CLICK(("===> DEC_ZOOM\n")); + break; + } + case DEC_MINIMIZE: + { + fIsMinimizing = true; + fDecorator->SetMinimize(true); + fDecorator->DrawMinimize(); + STRACE_CLICK(("===> DEC_MINIMIZE\n")); + break; + } + case DEC_RESIZE: + case DEC_DRAG: + case DEC_MOVETOBACK: + { + // do nothing - RootLayer takes care of that + STRACE_CLICK(("===> DEC_RESIZE || DEC_DRAG || DEC_MOVETOBACK \n")); + break; + } + case DEC_NONE: + { + Window()->Lock(); + // TODO: you can improve performance by doing this search client-side! + Layer *target = LayerAt(evt.where); + if (sendMessage && target && target != fTopLayer) { - fIsClosing = true; - fDecorator->SetClose(true); - fDecorator->DrawClose(); - STRACE_CLICK(("===> DEC_CLOSE\n")); - break; - } - case DEC_ZOOM: - { - fIsZooming = true; - fDecorator->SetZoom(true); - fDecorator->DrawZoom(); - STRACE_CLICK(("===> DEC_ZOOM\n")); - break; - } - case DEC_MINIMIZE: - { - fIsMinimizing = true; - fDecorator->SetMinimize(true); - fDecorator->DrawMinimize(); - STRACE_CLICK(("===> DEC_MINIMIZE\n")); - break; - } - case DEC_RESIZE: - case DEC_DRAG: - case DEC_MOVETOBACK: - { - // do nothing - RootLayer takes care of that - break; - } - case DEC_NONE: - { - debugger("WinBorder::MouseDown - Decorator should NOT return DEC_NONE\n"); - break; - } - default: - { - debugger("WinBorder::MouseDown - Decorator returned UNKNOWN code\n"); - break; + BMessage msg; + msg.what = B_MOUSE_DOWN; + msg.AddInt64("when", evt.when); + msg.AddPoint("where", evt.where); + msg.AddInt32("modifiers", evt.modifiers); + msg.AddInt32("buttons", evt.buttons); + msg.AddInt32("clicks", evt.clicks); + + Window()->SendMessageToClient(&msg, target->fViewToken, false); } + Window()->Unlock(); + break; + } + default: + { + debugger("WinBorder::MouseDown - Decorator returned UNKNOWN code\n"); + break; } } - else if (sendMessage && target && target != fTopLayer) - { - BMessage msg; - msg.what = B_MOUSE_DOWN; - msg.AddInt64("when", evt.when); - msg.AddPoint("where", evt.where); - msg.AddInt32("modifiers", evt.modifiers); - msg.AddInt32("buttons", evt.buttons); - msg.AddInt32("clicks", evt.clicks); - Window()->SendMessageToClient(&msg, target->fViewToken, false); - } - fLastMousePosition = evt.where; } @@ -249,9 +244,6 @@ void WinBorder::MouseDown(PointerEvent& evt, bool sendMessage) */ void WinBorder::MouseMoved(PointerEvent& evt) { - if (!(Window()->IsLocked())) - debugger("you must lock the attached ServerWindow object\n\t before calling WinBorder::MouseMoved()\n"); - // Do a click test only if we have to, which would be now. :) click_type location=fDecorator->Clicked(evt.where, evt.buttons,fKeyModifiers); @@ -275,12 +267,19 @@ void WinBorder::MouseMoved(PointerEvent& evt) if (fTopLayer->fFullVisible.Contains(evt.where)) { - BMessage movemsg(B_MOUSE_MOVED); - movemsg.AddInt64("when",evt.when); - movemsg.AddPoint("where",evt.where); - movemsg.AddInt32("buttons",evt.buttons); + Window()->Lock(); + // TODO: you can improve performance by doing this search client-side! + Layer *target = LayerAt(evt.where); + if (target) + { + BMessage movemsg(B_MOUSE_MOVED); + movemsg.AddInt64("when",evt.when); + movemsg.AddPoint("where",evt.where); + movemsg.AddInt32("buttons",evt.buttons); - Window()->SendMessageToClient(&movemsg); + Window()->SendMessageToClient(&movemsg); + } + Window()->Unlock(); } fLastMousePosition = evt.where; @@ -296,14 +295,11 @@ void WinBorder::MouseMoved(PointerEvent& evt) */ void WinBorder::MouseUp(PointerEvent& evt) { - if (!(Window()->IsLocked())) - debugger("you must lock the attached ServerWindow object\n\t before calling WinBorder::MouseUp()\n"); - click_type action; // find out where user clicked in Decorator action = fDecorator->Clicked(evt.where, evt.buttons, evt.modifiers); - + if (fIsZooming) { fIsZooming = false; @@ -333,15 +329,21 @@ void WinBorder::MouseUp(PointerEvent& evt) return; } - Layer *target = LayerAt(evt.where); - if (target && target != fTopLayer) + if (action == DEC_NONE) { - BMessage upmsg(B_MOUSE_UP); - upmsg.AddInt64("when",evt.when); - upmsg.AddPoint("where",evt.where); - upmsg.AddInt32("modifiers",evt.modifiers); + Window()->Lock(); + // TODO: you can improve performance by doing this search client-side! + Layer *target = LayerAt(evt.where); + if (target && target != fTopLayer) + { + BMessage upmsg(B_MOUSE_UP); + upmsg.AddInt64("when",evt.when); + upmsg.AddPoint("where",evt.where); + upmsg.AddInt32("modifiers",evt.modifiers); - Window()->SendMessageToClient(&upmsg, target->fViewToken, false); + Window()->SendMessageToClient(&upmsg, target->fViewToken, false); + } + Window()->Unlock(); } } @@ -349,12 +351,19 @@ void WinBorder::MouseWheel(PointerEvent& evt, BPoint& ptWhere) { if (fTopLayer->fFullVisible.Contains(ptWhere)) { - BMessage wheelmsg(B_MOUSE_WHEEL_CHANGED); - wheelmsg.AddInt64("when",evt.when); - wheelmsg.AddFloat("be:wheel_delta_x",evt.wheel_delta_x); - wheelmsg.AddFloat("be:wheel_delta_y",evt.wheel_delta_y); + Window()->Lock(); + // TODO: you can improve performance by doing this search client-side! + Layer *target = LayerAt(evt.where); + if (target && target != fTopLayer) + { + BMessage wheelmsg(B_MOUSE_WHEEL_CHANGED); + wheelmsg.AddInt64("when",evt.when); + wheelmsg.AddFloat("be:wheel_delta_x",evt.wheel_delta_x); + wheelmsg.AddFloat("be:wheel_delta_y",evt.wheel_delta_y); - Window()->SendMessageToClient(&wheelmsg); + Window()->SendMessageToClient(&wheelmsg); + } + Window()->Unlock(); } }