Work in progress for the new input handling stuff...

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14191 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Adi Oanca 2005-09-16 05:10:21 +00:00
parent a59bd8b8bc
commit 8b94d5ecdd
8 changed files with 262 additions and 20 deletions

View File

@ -1100,7 +1100,7 @@ Layer::ScrollBy(float x, float y)
void void
Layer::MouseDown(const PointerEvent& evt) Layer::MouseDown(const PointerEvent& evt)
{ {
if (Window()) { if (Window() && !IsTopLayer()) {
BMessage msg; BMessage msg;
msg.what = B_MOUSE_DOWN; msg.what = B_MOUSE_DOWN;
msg.AddInt64("when", evt.when); msg.AddInt64("when", evt.when);
@ -1116,7 +1116,7 @@ Layer::MouseDown(const PointerEvent& evt)
void void
Layer::MouseUp(const PointerEvent& evt) Layer::MouseUp(const PointerEvent& evt)
{ {
if (Window()) { if (Window() && !IsTopLayer()) {
BMessage upmsg(B_MOUSE_UP); BMessage upmsg(B_MOUSE_UP);
upmsg.AddInt64("when",evt.when); upmsg.AddInt64("when",evt.when);
upmsg.AddPoint("where",evt.where); upmsg.AddPoint("where",evt.where);
@ -1129,7 +1129,7 @@ Layer::MouseUp(const PointerEvent& evt)
void void
Layer::MouseMoved(const PointerEvent& evt, uint32 transit) Layer::MouseMoved(const PointerEvent& evt, uint32 transit)
{ {
if (Window()) { if (Window() && !IsTopLayer()) {
BMessage movemsg(B_MOUSE_MOVED); BMessage movemsg(B_MOUSE_MOVED);
movemsg.AddInt64("when", evt.when); movemsg.AddInt64("when", evt.when);
movemsg.AddPoint("where", evt.where); movemsg.AddPoint("where", evt.where);

View File

@ -199,9 +199,11 @@ class Layer {
ServerApp* App() const ServerApp* App() const
{ return fServerWin? fServerWin->App(): NULL; } { return fServerWin? fServerWin->App(): NULL; }
inline WinBorder* Owner() const
{ return fOwner; }
virtual bool HasClient() virtual bool HasClient()
{ return true; } { return true; }
// bool IsServerLayer() const;
uint32 EventMask() const uint32 EventMask() const
{ return fEventMask; } { return fEventMask; }
@ -250,6 +252,9 @@ class Layer {
void CopyBits(BRect& src, BRect& dst, void CopyBits(BRect& src, BRect& dst,
int32 xOffset, int32 yOffset); int32 xOffset, int32 yOffset);
inline const BRegion& VisibleRegion() const { return fVisible; }
inline const BRegion& FullVisible() const { return fFullVisible; }
#ifdef NEW_CLIPPING #ifdef NEW_CLIPPING
inline const BRegion& VisibleRegion() const { return fVisible2; } inline const BRegion& VisibleRegion() const { return fVisible2; }
inline const BRegion& FullVisible() const { return fFullVisible2; } inline const BRegion& FullVisible() const { return fFullVisible2; }

View File

@ -1033,9 +1033,6 @@ RootLayer::WinBorderAt(const BPoint& pt) const
void void
RootLayer::_ProcessMouseMovedEvent(PointerEvent &evt) RootLayer::_ProcessMouseMovedEvent(PointerEvent &evt)
{ {
// move cursor on screen
GetHWInterface()->MoveCursorTo(evt.where.x, evt.where.y);
Layer* target = LayerAt(evt.where); Layer* target = LayerAt(evt.where);
if (target == NULL) { if (target == NULL) {
CRITICAL("RootLayer::_ProcessMouseMovedEvent() 'target' can't be null.\n"); CRITICAL("RootLayer::_ProcessMouseMovedEvent() 'target' can't be null.\n");
@ -1120,6 +1117,9 @@ RootLayer::MouseEventHandler(int32 code, BPrivate::PortLink& msg)
if (fLastMousePosition != evt.where) { if (fLastMousePosition != evt.where) {
#ifdef NEW_INPUT_HANDLING #ifdef NEW_INPUT_HANDLING
// move cursor on screen
GetHWInterface()->MoveCursorTo(evt.where.x, evt.where.y);
_ProcessMouseMovedEvent(evt); _ProcessMouseMovedEvent(evt);
#else #else
@ -1146,6 +1146,65 @@ RootLayer::MouseEventHandler(int32 code, BPrivate::PortLink& msg)
if (fLastLayerUnderMouse == this) if (fLastLayerUnderMouse == this)
break; break;
#ifdef NEW_INPUT_HANDLING #ifdef NEW_INPUT_HANDLING
WinBorder* winBorderUnderMouse = fLastLayerUnderMouse->Owner() ?
fLastLayerUnderMouse->fOwner :
(WinBorder*)fLastLayerUnderMouse;
DesktopSettings ds(gDesktop);
Workspace::State oldState, newState;
click_type action = winBorderUnderMouse->ActionFor(evt);
ActiveWorkspace()->GetState(&oldState);
if (action == DEC_MOVETOBACK) {
ActiveWorkspace()->AttemptToMoveToBack(winBorderUnderMouse);
}
// in FFM, only bring in front if clicking on WinBorder's(decorator's) area
else if (dynamic_cast<WinBorder*>(fLastLayerUnderMouse) || ds.MouseMode() == B_NORMAL_MOUSE) {
ActiveWorkspace()->AttemptToSetFront(winBorderUnderMouse);
}
ActiveWorkspace()->AttemptToSetFocus(winBorderUnderMouse);
ActiveWorkspace()->GetState(&newState);
// send window activation messages
// NOTE !!! ATM we're sending B_WINDOW_ACTIVATED to front windows only!
// This means floating windows do not have their BWindow::WindowActivated()
// hook function called.
if (oldState.Front != newState.Front) {
if (oldState.Front && oldState.Front->Window()) {
BMessage msg(B_WINDOW_ACTIVATED);
msg.AddBool("active", false);
oldState.Front->Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false);
}
if (newState.Front && newState.Front->Window()) {
BMessage msg(B_WINDOW_ACTIVATED);
msg.AddBool("active", true);
newState.Front->Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false);
}
}
// calculate the region that must be invalidated/redrawn
// first, if the focus window changed, make sure the decorators reflect this state.
BRegion dirtyRegion;
if (oldState.Focus != newState.Focus) {
dirtyRegion.Include(&oldState.Focus->VisibleRegion());
dirtyRegion.Include(&newState.Focus->VisibleRegion());
}
#ifndef NEW_CLIPPING
invalidate_layer(this, dirtyRegion);
#else
do_Invalidate(dirtyRegion);
#endif
#ifndef NEW_CLIPPING
invalidate_layer(this, fFull);
#else
do_Invalidate(Bounds());
#endif
// TODO: DO NOT ALWAYS SEND THE FIRST MOUSE DOWN!!!
// TODO: if B_WILL_ACCEPT_FIRST_CLICK, DO NOT ACTIVATE THE CLICKED WINDOW!!!
fLastLayerUnderMouse->MouseDown(evt); fLastLayerUnderMouse->MouseDown(evt);
#else #else
// we are clicking a WinBorder // we are clicking a WinBorder
@ -1235,16 +1294,13 @@ RootLayer::MouseEventHandler(int32 code, BPrivate::PortLink& msg)
evt.where.ConstrainTo(fFrame); evt.where.ConstrainTo(fFrame);
#ifdef NEW_INPUT_HANDLING
ClearNotifyLayer();
#endif
if (fLastLayerUnderMouse == NULL) {
CRITICAL("RootLayer::MouseEventHandler(B_MOUSE_UP) fLastLayerUnderMouse is null!\n");
break;
}
if (fLastMousePosition != evt.where) { if (fLastMousePosition != evt.where) {
#ifdef NEW_INPUT_HANDLING
// move cursor on screen
GetHWInterface()->MoveCursorTo(evt.where.x, evt.where.y);
_ProcessMouseMovedEvent(evt);
#else
// TODO: a B_MOUSE_MOVED message might have to be generated in order to // TODO: a B_MOUSE_MOVED message might have to be generated in order to
// correctly trigger entered/exited view transits. // correctly trigger entered/exited view transits.
fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_MOUSE_MOVED (%.1f, %.1f)!\n", fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_MOUSE_MOVED (%.1f, %.1f)!\n",
@ -1252,6 +1308,20 @@ fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_M
// update on screen mouse pos // update on screen mouse pos
GetHWInterface()->MoveCursorTo(evt.where.x, evt.where.y); GetHWInterface()->MoveCursorTo(evt.where.x, evt.where.y);
fLastMousePosition = evt.where; fLastMousePosition = evt.where;
#endif
}
#ifdef NEW_INPUT_HANDLING
ClearNotifyLayer();
if (fLastLayerUnderMouse == NULL) {
CRITICAL("RootLayer::MouseEventHandler(B_MOUSE_UP) fLastLayerUnderMouse is null!\n");
break;
}
fLastLayerUnderMouse->MouseUp(evt);
#else
if (fLastLayerUnderMouse == NULL) {
CRITICAL("RootLayer::MouseEventHandler(B_MOUSE_UP) fLastLayerUnderMouse is null!\n");
break;
} }
// TODO: what if 'fNotifyLayer' is deleted in the mean time. // TODO: what if 'fNotifyLayer' is deleted in the mean time.
@ -1296,7 +1366,7 @@ fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_M
} }
STRACE(("MOUSE UP: at (%f, %f)\n", evt.where.x, evt.where.y)); STRACE(("MOUSE UP: at (%f, %f)\n", evt.where.x, evt.where.y));
#endif
// TODO: This is a quick fix to avoid the endless loop with windows created // TODO: This is a quick fix to avoid the endless loop with windows created
// with the B_ASYNCHRONOUS_CONTROLS flag, but please someone have a look into this. // with the B_ASYNCHRONOUS_CONTROLS flag, but please someone have a look into this.
fButtons = 0; fButtons = 0;
@ -1320,6 +1390,9 @@ fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_M
evt.where.ConstrainTo(fFrame); evt.where.ConstrainTo(fFrame);
#ifdef NEW_INPUT_HANDLING #ifdef NEW_INPUT_HANDLING
// move cursor on screen
GetHWInterface()->MoveCursorTo(evt.where.x, evt.where.y);
_ProcessMouseMovedEvent(evt); _ProcessMouseMovedEvent(evt);
#else #else
GetHWInterface()->MoveCursorTo(evt.where.x, evt.where.y); GetHWInterface()->MoveCursorTo(evt.where.x, evt.where.y);
@ -1871,10 +1944,10 @@ RootLayer::SetNotifyLayer(Layer *lay, uint32 mask, uint32 options)
Lock(); Lock();
#if 0 // to be removed when the new "event" stuff is ready #if NEW_INPUT_HANDLING // to be removed when the new "event" stuff is ready
fNotifyLayer = lay; fNotifyLayer = lay;
fSavedEventMask = lay->EventMask(); fSavedEventMask = lay->EventMask();
fSavedOptions = lay->EventOptions(); fSavedEventOptions = lay->EventOptions();
AddToInputNotificationLists(lay, mask, options); AddToInputNotificationLists(lay, mask, options);

View File

@ -142,7 +142,9 @@ public:
private: private:
friend class Desktop; friend class Desktop;
#ifdef NEW_INPUT_HANDLING
friend class WinBorder; // temporarily, I need invalidate_layer()
#endif
// these are meant for Desktop class only! // these are meant for Desktop class only!
void AddWinBorder(WinBorder* winBorder); void AddWinBorder(WinBorder* winBorder);
void RemoveWinBorder(WinBorder* winBorder); void RemoveWinBorder(WinBorder* winBorder);

View File

@ -450,16 +450,134 @@ WinBorder::GetSizeLimits(float* minWidth, float* maxWidth,
void void
WinBorder::MouseDown(const PointerEvent& event) WinBorder::MouseDown(const PointerEvent& event)
{ {
if (fDecorator) {
click_type action = _ActionFor(event);
// find out where user clicked in Decorator
switch(action) {
case DEC_CLOSE:
fIsClosing = true;
fDecorator->SetClose(true);
STRACE_CLICK(("===> DEC_CLOSE\n"));
break;
case DEC_ZOOM:
fIsZooming = true;
fDecorator->SetZoom(true);
STRACE_CLICK(("===> DEC_ZOOM\n"));
break;
case DEC_MINIMIZE:
fIsMinimizing = true;
fDecorator->SetMinimize(true);
STRACE_CLICK(("===> DEC_MINIMIZE\n"));
break;
case DEC_DRAG:
fIsDragging = true;
#ifdef NEW_INPUT_HANDLING
GetRootLayer()->SetNotifyLayer(this, B_POINTER_EVENTS, 0UL);
#endif
fLastMousePosition = event.where;
STRACE_CLICK(("===> DEC_DRAG\n"));
break;
case DEC_RESIZE:
fIsResizing = true;
fLastMousePosition = event.where;
STRACE_CLICK(("===> DEC_RESIZE\n"));
break;
case DEC_SLIDETAB:
fIsSlidingTab = true;
fLastMousePosition = event.where;
STRACE_CLICK(("===> DEC_SLIDETAB\n"));
break;
default:
break;
}
}
// TODO: set dirty regions!
#ifndef NEW_CLIPPING
GetRootLayer()->invalidate_layer(this, VisibleRegion());
#else
do_Invalidate(VisibleRegion());
#endif
} }
void void
WinBorder::MouseUp(const PointerEvent& event) WinBorder::MouseUp(const PointerEvent& event)
{ {
if (fDecorator) {
click_type action = _ActionFor(event);
if (fIsZooming) {
fIsZooming = false;
fDecorator->SetZoom(false);
if (action == DEC_ZOOM)
Window()->NotifyZoom();
return;
}
if (fIsClosing) {
fIsClosing = false;
fDecorator->SetClose(false);
if (action == DEC_CLOSE)
Window()->NotifyQuitRequested();
return;
}
if (fIsMinimizing) {
fIsMinimizing = false;
fDecorator->SetMinimize(false);
if (action == DEC_MINIMIZE)
Window()->NotifyMinimize(true);
return;
}
}
fIsDragging = false;
fIsResizing = false;
fIsSlidingTab = false;
// TODO: set dirty regions!
#ifndef NEW_CLIPPING
GetRootLayer()->invalidate_layer(this, VisibleRegion());
#else
do_Invalidate(VisibleRegion());
#endif
} }
void void
WinBorder::MouseMoved(const PointerEvent& event, uint32 transit) WinBorder::MouseMoved(const PointerEvent& event, uint32 transit)
{ {
if (fDecorator) {
if (fIsZooming) {
fDecorator->SetZoom(_ActionFor(event) == DEC_ZOOM);
} else if (fIsClosing) {
fDecorator->SetClose(_ActionFor(event) == DEC_CLOSE);
} else if (fIsMinimizing) {
fDecorator->SetMinimize(_ActionFor(event) == DEC_MINIMIZE);
}
}
if (fIsDragging) {
BPoint delta = event.where - fLastMousePosition;
#ifndef NEW_CLIPPING
MoveBy(delta.x, delta.y);
#else
do_MoveBy(delta.x, delta.y);
#endif
}
if (fIsResizing) {
BPoint delta = event.where - fLastMousePosition;
#ifndef NEW_CLIPPING
ResizeBy(delta.x, delta.y);
#else
do_ResizeBy(delta.x, delta.y);
#endif
}
if (fIsSlidingTab) {
// TODO: implement
}
fLastMousePosition = event.where;
} }
#else #else
@ -745,6 +863,7 @@ WinBorder::QuietlySetFeel(int32 feel)
click_type click_type
WinBorder::_ActionFor(const PointerEvent& event) const WinBorder::_ActionFor(const PointerEvent& event) const
{ {
#ifndef NEW_INPUT_HANDING
#ifndef NEW_CLIPPING #ifndef NEW_CLIPPING
if (fTopLayer->fFullVisible.Contains(event.where)) if (fTopLayer->fFullVisible.Contains(event.where))
return DEC_NONE; return DEC_NONE;
@ -753,6 +872,7 @@ WinBorder::_ActionFor(const PointerEvent& event) const
if (fTopLayer->fFullVisible2.Contains(event.where)) if (fTopLayer->fFullVisible2.Contains(event.where))
return DEC_NONE; return DEC_NONE;
else else
#endif
#endif #endif
if (fDecorator) if (fDecorator)
return fDecorator->Clicked(event.where, event.buttons, event.modifiers); return fDecorator->Clicked(event.where, event.buttons, event.modifiers);

View File

@ -85,6 +85,8 @@ class WinBorder : public Layer {
virtual void MouseDown(const PointerEvent& evt); virtual void MouseDown(const PointerEvent& evt);
virtual void MouseUp(const PointerEvent& evt); virtual void MouseUp(const PointerEvent& evt);
virtual void MouseMoved(const PointerEvent& evt, uint32 transit); virtual void MouseMoved(const PointerEvent& evt, uint32 transit);
click_type ActionFor(const PointerEvent& evt)
{ return _ActionFor(evt); }
#else #else
click_type MouseDown(const PointerEvent& evt); click_type MouseDown(const PointerEvent& evt);
void MouseMoved(const PointerEvent& evt); void MouseMoved(const PointerEvent& evt);

View File

@ -219,7 +219,36 @@ Workspace::Active() const
//return fActiveItem ? fActiveItem->layerPtr: NULL; //return fActiveItem ? fActiveItem->layerPtr: NULL;
} }
void
Workspace::GetState(Workspace::State *state) const
{
state->Front = Front();
state->Focus = Focus();
ListData *cursor = fBottomItem;
while (cursor) {
if (!cursor->layerPtr->IsHidden())
state->WindowList.AddItem(cursor->layerPtr);
cursor = cursor->upperItem;
}
}
bool
Workspace::AttemptToSetFront(WinBorder *newFront)
{
return MoveToFront(newFront);
}
bool
Workspace::AttemptToSetFocus(WinBorder *newFocus)
{
return SetFocus(newFocus);
}
bool
Workspace::AttemptToMoveToBack(WinBorder *newBack)
{
return MoveToBack(newBack);
}
/* /*
\brief This method provides you the list of visible windows in this workspace. \brief This method provides you the list of visible windows in this workspace.
\param list The list of visible WinBorders found in this workspace. \param list The list of visible WinBorders found in this workspace.

View File

@ -49,6 +49,13 @@ struct ListData
class Workspace { class Workspace {
public: public:
class State {
public:
State() : Front(NULL), Focus(NULL), WindowList(40) { }
WinBorder* Front;
WinBorder* Focus;
BList WindowList;
};
Workspace( const int32 ID, Workspace( const int32 ID,
const uint32 colorspace, const uint32 colorspace,
const RGBColor& BGColor); const RGBColor& BGColor);
@ -63,6 +70,10 @@ class Workspace {
WinBorder* Focus() const; WinBorder* Focus() const;
WinBorder* Front() const; WinBorder* Front() const;
WinBorder* Active() const; WinBorder* Active() const;
void GetState(Workspace::State *state) const;
bool AttemptToSetFront(WinBorder *newFront);
bool AttemptToSetFocus(WinBorder *newFocus);
bool AttemptToMoveToBack(WinBorder *newBack);
bool GetWinBorderList(void **list, int32 *itemCount ) const; bool GetWinBorderList(void **list, int32 *itemCount ) const;