more work on the input handling. I let Layer/WinBorder handle the MouseDown/Moved/Up instead of doing this in RootLayer::MouseEventHandler(). I did this because I felt it's more clean and in the near future RootLayer may have other children than WinBorders, for example simple Layers representing tooltips/bubbles/etc.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14198 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
c5233d297e
commit
1b65556d66
@ -404,9 +404,20 @@ Layer::FindLayer(const int32 token)
|
||||
\return The layer containing the point or NULL if no layer found
|
||||
*/
|
||||
Layer*
|
||||
Layer::LayerAt(const BPoint &pt)
|
||||
Layer::LayerAt(const BPoint &pt, bool recursive)
|
||||
{
|
||||
//printf("%p:%s:LayerAt(x = %g, y = %g)\n", this, Name(), pt.x, pt.y);
|
||||
if (!recursive) {
|
||||
if (VisibleRegion().Contains(pt))
|
||||
return this;
|
||||
|
||||
for (Layer* child = LastChild(); child; child = PreviousChild())
|
||||
if (child->FullVisible().Contains(pt))
|
||||
return child;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef NEW_CLIPPING
|
||||
if (fVisible.Contains(pt))
|
||||
return this;
|
||||
|
@ -108,7 +108,7 @@ class Layer {
|
||||
|
||||
uint32 CountChildren() const;
|
||||
Layer* FindLayer(const int32 token);
|
||||
Layer* LayerAt(const BPoint &pt);
|
||||
Layer* LayerAt(const BPoint &pt, bool recursive = true);
|
||||
|
||||
virtual Layer* FirstChild() const;
|
||||
virtual Layer* NextChild() const;
|
||||
|
@ -1145,67 +1145,11 @@ RootLayer::MouseEventHandler(int32 code, BPrivate::PortLink& msg)
|
||||
|
||||
if (fLastLayerUnderMouse == this)
|
||||
break;
|
||||
|
||||
#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);
|
||||
// get the pointer for one of the first RootLayer's descendants
|
||||
Layer *primaryTarget = LayerAt(evt.where, false);
|
||||
primaryTarget->MouseDown(evt);
|
||||
#else
|
||||
// we are clicking a WinBorder
|
||||
|
||||
@ -2241,7 +2185,7 @@ RootLayer::draw_window_tab(WinBorder *exFocus)
|
||||
}
|
||||
|
||||
#ifndef NEW_CLIPPING
|
||||
inline void
|
||||
void
|
||||
RootLayer::empty_visible_regions(Layer *layer)
|
||||
{
|
||||
// TODO: optimize by avoiding recursion?
|
||||
@ -2257,7 +2201,7 @@ RootLayer::empty_visible_regions(Layer *layer)
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void
|
||||
void
|
||||
RootLayer::winborder_activation(WinBorder* exActive)
|
||||
{
|
||||
// ToDo: not sure if this is correct - do floating windows get WindowActivated() events?
|
||||
@ -2274,7 +2218,7 @@ RootLayer::winborder_activation(WinBorder* exActive)
|
||||
}
|
||||
|
||||
|
||||
inline void
|
||||
void
|
||||
RootLayer::show_final_scene(WinBorder *exFocus, WinBorder *exActive)
|
||||
{
|
||||
if (fHaveWinBorderList || get_workspace_windows()) {
|
||||
|
@ -218,7 +218,7 @@ fInUpdateRegion.OffsetBy(x, y);
|
||||
// ...and here we get really hacky...
|
||||
fTopLayer->fFrame.OffsetTo(0.0, 0.0);
|
||||
} else {
|
||||
move_layer(x, y);
|
||||
Layer::move_layer(x, y);
|
||||
}
|
||||
|
||||
if (Window()) {
|
||||
@ -448,62 +448,145 @@ WinBorder::GetSizeLimits(float* minWidth, float* maxWidth,
|
||||
#ifdef NEW_INPUT_HANDLING
|
||||
|
||||
void
|
||||
WinBorder::MouseDown(const PointerEvent& event)
|
||||
WinBorder::MouseDown(const PointerEvent& evt)
|
||||
{
|
||||
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;
|
||||
DesktopSettings desktopSettings(gDesktop);
|
||||
Workspace::State oldState, newState;
|
||||
|
||||
case DEC_DRAG:
|
||||
fIsDragging = true;
|
||||
#ifdef NEW_INPUT_HANDLING
|
||||
GetRootLayer()->SetNotifyLayer(this, B_POINTER_EVENTS, 0UL);
|
||||
GetRootLayer()->ActiveWorkspace()->GetState(&oldState);
|
||||
|
||||
// not in FFM mode?
|
||||
if (desktopSettings.MouseMode() == B_NORMAL_MOUSE) {
|
||||
// default action is to drag the WinBorder
|
||||
click_type action = DEC_DRAG;
|
||||
Layer *target = LayerAt(evt.where);
|
||||
// clicking a simple Layer.
|
||||
if (target != this) {
|
||||
if (GetRootLayer()->ActiveWorkspace()->Active() == this) {
|
||||
target->MouseDown(evt);
|
||||
}
|
||||
else {
|
||||
if (WindowFlags() & B_WILL_ACCEPT_FIRST_CLICK)
|
||||
target->MouseDown(evt);
|
||||
else
|
||||
goto activateWindow;
|
||||
}
|
||||
// TODO: send mouse down to event registered BViews!!!
|
||||
}
|
||||
// clicking WinBorder visible area
|
||||
else {
|
||||
winBorderAreaHandle:
|
||||
|
||||
if (fDecorator)
|
||||
action = _ActionFor(evt);
|
||||
|
||||
// set decorator internals
|
||||
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;
|
||||
fLastMousePosition = evt.where;
|
||||
STRACE_CLICK(("===> DEC_DRAG\n"));
|
||||
break;
|
||||
|
||||
case DEC_RESIZE:
|
||||
fIsResizing = true;
|
||||
fLastMousePosition = evt.where;
|
||||
STRACE_CLICK(("===> DEC_RESIZE\n"));
|
||||
break;
|
||||
|
||||
case DEC_SLIDETAB:
|
||||
fIsSlidingTab = true;
|
||||
fLastMousePosition = evt.where;
|
||||
STRACE_CLICK(("===> DEC_SLIDETAB\n"));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// based on what the Decorator returned, properly place this window.
|
||||
if (action == DEC_MOVETOBACK) {
|
||||
GetRootLayer()->ActiveWorkspace()->MoveToBack(this);
|
||||
}
|
||||
else if (action == DEC_DRAG) {
|
||||
GetRootLayer()->SetNotifyLayer(this, B_POINTER_EVENTS, 0UL);
|
||||
activateWindow:
|
||||
GetRootLayer()->ActiveWorkspace()->AttemptToActivate(this);
|
||||
}
|
||||
|
||||
GetRootLayer()->ActiveWorkspace()->GetState(&newState);
|
||||
//--------------------------
|
||||
// BOOKMARK!
|
||||
// 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
|
||||
GetRootLayer()->fRedrawReg.Include(&dirtyRegion);
|
||||
#else
|
||||
// TODO: code for new clipping engine!
|
||||
#endif
|
||||
fLastMousePosition = event.where;
|
||||
STRACE_CLICK(("===> DEC_DRAG\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
case DEC_RESIZE:
|
||||
fIsResizing = true;
|
||||
fLastMousePosition = event.where;
|
||||
STRACE_CLICK(("===> DEC_RESIZE\n"));
|
||||
break;
|
||||
#ifndef NEW_CLIPPING
|
||||
GetRootLayer()->invalidate_layer(this, fFull);
|
||||
#else
|
||||
GetRootLayer()->do_Invalidate(Bounds());
|
||||
#endif
|
||||
|
||||
case DEC_SLIDETAB:
|
||||
fIsSlidingTab = true;
|
||||
fLastMousePosition = event.where;
|
||||
STRACE_CLICK(("===> DEC_SLIDETAB\n"));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
// TODO: FINISH ABOVE.
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: set dirty regions!
|
||||
#ifndef NEW_CLIPPING
|
||||
GetRootLayer()->invalidate_layer(this, VisibleRegion());
|
||||
#else
|
||||
do_Invalidate(VisibleRegion());
|
||||
#endif
|
||||
// in FFM mode
|
||||
else {
|
||||
Layer *target = LayerAt(evt.where);
|
||||
// clicking a simple Layer; forward event.
|
||||
if (target != this)
|
||||
target->MouseDown(evt);
|
||||
// clicking inside our visible area.
|
||||
else
|
||||
goto winBorderAreaHandle;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -214,9 +214,16 @@ Workspace::Front() const
|
||||
WinBorder *
|
||||
Workspace::Active() const
|
||||
{
|
||||
// ToDo: for now!
|
||||
return Focus();
|
||||
//return fActiveItem ? fActiveItem->layerPtr: NULL;
|
||||
// in case of a normal or modal window
|
||||
if (fFrontItem && fFrontItem == fFocusItem)
|
||||
return fFrontItem->layerPtr;
|
||||
|
||||
// a floating window is considered active if it has focus.
|
||||
if (fFocusItem && (fFocusItem->layerPtr->Level() == B_FLOATING_APP ||
|
||||
fFocusItem->layerPtr->Level() == B_FLOATING_ALL))
|
||||
return fFocusItem->layerPtr;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
@ -249,6 +256,14 @@ Workspace::AttemptToMoveToBack(WinBorder *newBack)
|
||||
{
|
||||
return MoveToBack(newBack);
|
||||
}
|
||||
|
||||
bool
|
||||
Workspace::AttemptToActivate(WinBorder *toActivate)
|
||||
{
|
||||
MoveToFront(toActivate);
|
||||
SetFocus(toActivate);
|
||||
return Active() == toActivate;
|
||||
}
|
||||
/*
|
||||
\brief This method provides you the list of visible windows in this workspace.
|
||||
\param list The list of visible WinBorders found in this workspace.
|
||||
|
@ -74,6 +74,7 @@ class Workspace {
|
||||
bool AttemptToSetFront(WinBorder *newFront);
|
||||
bool AttemptToSetFocus(WinBorder *newFocus);
|
||||
bool AttemptToMoveToBack(WinBorder *newBack);
|
||||
bool AttemptToActivate(WinBorder *toActivate);
|
||||
|
||||
bool GetWinBorderList(void **list, int32 *itemCount ) const;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user