Improved locking. A bit. :-)

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@11879 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Adi Oanca 2005-03-17 17:41:00 +00:00
parent 211de495df
commit ddf57545a2
4 changed files with 112 additions and 129 deletions

View File

@ -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)
{

View File

@ -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:

View File

@ -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);

View File

@ -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();
}
}