diff --git a/src/servers/app/server/RootLayer.cpp b/src/servers/app/server/RootLayer.cpp index 285a06c2f6..f6e442803d 100644 --- a/src/servers/app/server/RootLayer.cpp +++ b/src/servers/app/server/RootLayer.cpp @@ -48,6 +48,7 @@ #include "FMWList.h" #include "DisplayDriver.h" #include "ServerProtocol.h" +#include "Decorator.h" //#define DEBUG_ROOTLAYER @@ -74,6 +75,8 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount, SetWorkspaceCount(workspaceCount); SetActiveWorkspace(0L); + fMovingWindow = false; + fResizingWindow = false; fMouseTarget = NULL; fDragMessage = NULL; fScreenShotIndex = 1; @@ -881,19 +884,52 @@ void RootLayer::MouseEventHandler(int32 code, BPortLink& msg) msg.Read(&evt.buttons); msg.Read(&evt.clicks); - // We'll need this so that GetMouse can query for which buttons - // are down. - fButtons=evt.buttons; - - // printf("MOUSE DOWN: at (%f, %f)\n", evt.where.x, evt.where.y); WinBorder *target = WinBorderAt(evt.where); if (target) { - target->Window()->Lock(); - target->MouseDown(evt, true); - target->Window()->Unlock(); + click_type action; + bool invalidate; + bool sendMessage = true; + + action = target->TellWhat(evt); + + if (action == DEC_MOVETOBACK) + invalidate = ActiveWorkspace()->MoveToBack(target); + else + invalidate = ActiveWorkspace()->MoveToFront(target); + + if (invalidate) + { + BRegion reg(target->fFull); + reg.Include(&target->fTopLayer->fFull); + invalidate_layer(this, reg); + + if (!(target->Window()->Flags() & B_WILL_ACCEPT_FIRST_CLICK)) + sendMessage = false; + } + + if (action == DEC_DRAG) + { + fMovingWindow = true; + } + else if (action == DEC_RESIZE) + { + fResizingWindow = true; + } + else + { + target->Window()->Lock(); + target->MouseDown(evt, sendMessage); + target->Window()->Unlock(); + } + fMouseTarget = target; } + + // We'll need this so that GetMouse can query for which buttons + // are down. + fButtons=evt.buttons; + break; } case B_MOUSE_UP: @@ -911,14 +947,18 @@ void RootLayer::MouseEventHandler(int32 code, BPortLink& msg) msg.Read(&evt.where.y); msg.Read(&evt.modifiers); - fMouseTarget = NULL; - WinBorder *target = WinBorderAt(evt.where); - if (target) + // currently mouse up goes to the same window which received mouse down + if (fMouseTarget) { - target->Window()->Lock(); - target->MouseUp(evt); - target->Window()->Unlock(); + fMouseTarget->Window()->Lock(); + fMouseTarget->MouseUp(evt); + fMouseTarget->Window()->Unlock(); + fMouseTarget = NULL; } + + fMovingWindow = false; + fResizingWindow = false; + STRACE(("MOUSE UP: at (%f, %f)\n", evt.where.x, evt.where.y)); break; @@ -940,13 +980,44 @@ void RootLayer::MouseEventHandler(int32 code, BPortLink& msg) GetDisplayDriver()->MoveCursorTo(evt.where.x, evt.where.y); - WinBorder *target = WinBorderAt(evt.where); - if (target) + if (fMouseTarget) { - target->Window()->Lock(); - target->MouseMoved(evt); - target->Window()->Unlock(); + BPoint pt = evt.where; + pt -= fLastMousePossition; + + if (fMovingWindow) + { + if(fMouseTarget->fDecorator) + fMouseTarget->fDecorator->MoveBy(pt.x, pt.y); + + fMouseTarget->move_layer(pt.x, pt.y); + } + else if (fResizingWindow) + { + if(fMouseTarget->fDecorator) + fMouseTarget->fDecorator->ResizeBy(pt.x, pt.y); + + fMouseTarget->resize_layer(pt.x, pt.y); + } + else + { + fMouseTarget->Window()->Lock(); + fMouseTarget->MouseMoved(evt); + fMouseTarget->Window()->Unlock(); + } } + else + { + WinBorder *target = WinBorderAt(evt.where); + if (target) + { + target->Window()->Lock(); + target->MouseMoved(evt); + target->Window()->Unlock(); + } + } + + fLastMousePossition = evt.where; break; } diff --git a/src/servers/app/server/RootLayer.h b/src/servers/app/server/RootLayer.h index afe3d55f40..fe012bc514 100644 --- a/src/servers/app/server/RootLayer.h +++ b/src/servers/app/server/RootLayer.h @@ -155,6 +155,9 @@ friend class Desktop; int32 fScreenYResolution; uint32 fColorSpace; int32 fButtons; + BPoint fLastMousePossition; + bool fMovingWindow; + bool fResizingWindow; int32 fActiveWksIndex; int32 fWsCount; diff --git a/src/servers/app/server/WinBorder.cpp b/src/servers/app/server/WinBorder.cpp index 8450aadb8b..d41e8d9966 100644 --- a/src/servers/app/server/WinBorder.cpp +++ b/src/servers/app/server/WinBorder.cpp @@ -93,8 +93,6 @@ WinBorder::WinBorder(const BRect &r, const char *name, const int32 look, const i fAdFlags = fAdFlags | B_LAYER_CHILDREN_DEPENDANT; fFlags = B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE; - fIsMoving = false; - fIsResizing = false; fIsClosing = false; fIsMinimizing = false; fIsZooming = false; @@ -144,6 +142,16 @@ void WinBorder::RebuildFullRegion(void) fDecorator->GetFootprint(&fFull); } +click_type WinBorder::TellWhat(PointerEvent& evt) const +{ + if (fTopLayer->fFullVisible.Contains(evt.where)) + return DEC_NONE; + else if (fDecorator) + return fDecorator->Clicked(evt.where, evt.buttons, evt.modifiers); + else + return DEC_NONE; +} + /*! \brief Handles B_MOUSE_DOWN events and takes appropriate actions \param evt PointerEvent object containing the info from the last B_MOUSE_DOWN message @@ -197,20 +205,10 @@ void WinBorder::MouseDown(PointerEvent& evt, bool sendMessage) break; } case DEC_RESIZE: - { - fIsResizing = true; - STRACE_CLICK(("===> DEC_RESIZE\n")); - break; - } case DEC_DRAG: - { - fIsMoving = true; - STRACE_CLICK(("===> DEC_DRAG\n")); - break; - } case DEC_MOVETOBACK: { - GetRootLayer()->ActiveWorkspace()->MoveToBack(this); + // do nothing - RootLayer takes care of that break; } case DEC_NONE: @@ -254,43 +252,25 @@ void WinBorder::MouseMoved(PointerEvent& evt) if (!(Window()->IsLocked())) debugger("you must lock the attached ServerWindow object\n\t before calling WinBorder::MouseMoved()\n"); - if (fIsMoving) - { - STRACE_CLICK(("===> Moving...\n")); - BPoint offset = evt.where; - offset -= fLastMousePosition; - MoveBy(offset.x, offset.y); - } - else - if (fIsResizing) - { - STRACE_CLICK(("===> Resizing...\n")); - BPoint offset = evt.where; - offset -= fLastMousePosition; - ResizeBy(offset.x, offset.y); - } - else - { - // Do a click test only if we have to, which would be now. :) - click_type location=fDecorator->Clicked(evt.where, evt.buttons,fKeyModifiers); + // Do a click test only if we have to, which would be now. :) + click_type location=fDecorator->Clicked(evt.where, evt.buttons,fKeyModifiers); - if (fIsZooming && location!=DEC_ZOOM) - { - fDecorator->SetZoom(false); - fDecorator->DrawZoom(); - } - else - if (fIsClosing && location!=DEC_CLOSE) - { - fDecorator->SetClose(false); - fDecorator->DrawClose(); - } - else - if(fIsMinimizing && location!=DEC_MINIMIZE) - { - fDecorator->SetMinimize(false); - fDecorator->DrawMinimize(); - } + if (fIsZooming && location!=DEC_ZOOM) + { + fDecorator->SetZoom(false); + fDecorator->DrawZoom(); + } + else + if (fIsClosing && location!=DEC_CLOSE) + { + fDecorator->SetClose(false); + fDecorator->DrawClose(); + } + else + if(fIsMinimizing && location!=DEC_MINIMIZE) + { + fDecorator->SetMinimize(false); + fDecorator->DrawMinimize(); } if (fTopLayer->fFullVisible.Contains(evt.where)) @@ -324,18 +304,6 @@ void WinBorder::MouseUp(PointerEvent& evt) // find out where user clicked in Decorator action = fDecorator->Clicked(evt.where, evt.buttons, evt.modifiers); - if(fIsMoving) - { - fIsMoving = false; - return; - } - - if (fIsResizing) - { - fIsResizing = false; - return; - } - if (fIsZooming) { fIsZooming = false; diff --git a/src/servers/app/server/WinBorder.h b/src/servers/app/server/WinBorder.h index 24234afdf2..403791b1d3 100644 --- a/src/servers/app/server/WinBorder.h +++ b/src/servers/app/server/WinBorder.h @@ -32,6 +32,7 @@ #include #include "Layer.h" #include "FMWList.h" +#include "Decorator.h" // these are used by window manager to properly place window. enum { @@ -80,6 +81,7 @@ public: void SetSizeLimits(float minwidth, float maxwidth, float minheight, float maxheight); + click_type TellWhat(PointerEvent& evt) const; void MouseDown(PointerEvent& evt, bool sendMessage); void MouseMoved(PointerEvent& evt); void MouseUp(PointerEvent& evt); @@ -114,8 +116,6 @@ protected: int32 fKeyModifiers; BPoint fLastMousePosition; - bool fIsMoving; - bool fIsResizing; bool fIsClosing; bool fIsMinimizing; bool fIsZooming;