[haiku-commits] haiku: hrev45197 - src/servers/app/decorator

  • From: jscipione@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 25 Jan 2013 06:00:22 +0100 (CET)

hrev45197 adds 1 changeset to branch 'master'
old head: e5de7e2102c59d0f6464378522d46dab0bb3f5b2
new head: 3071859cc6842d96fa086771c9463085ea0f2246
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=3071859+%5Ee5de7e2

----------------------------------------------------------------------------

3071859: Update ctrl+alt window management functionality.
  
  * Use double-headed resize arrows instead of single headed.
  * Remove border highlighting, it is replaced by mouse cursor.
  * Don't enter drag state if window is not movable.
  * Make Ctrl+LMB resize window border like RMB.
  * Define other 3 corners in default decorator and resize by them
    as well
  * Update mouse cursor to show arrows when over borders and control
    is held.
  * Set the move cursor on ctrl+alt if the window is movable.
  * Set cursor to not allowed on ctrl+alt if window is not movable.
  * Set the cursor to appropriate resize arrow on ctrl+alt+RMB.
  * Set the cursor to not allowed on ctrl+alt+RMB if not resizable.
  * Make window go to back when you right-click or ctrl+click
    on the tab. It doesn't lose focus though unlike BeOS R5.

                                     [ John Scipione <jscipione@xxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev45197
Commit:      3071859cc6842d96fa086771c9463085ea0f2246
URL:         http://cgit.haiku-os.org/haiku/commit/?id=3071859
Author:      John Scipione <jscipione@xxxxxxxxx>
Date:        Thu Jan 17 00:58:25 2013 UTC

----------------------------------------------------------------------------

3 files changed, 383 insertions(+), 208 deletions(-)
src/servers/app/decorator/DefaultDecorator.cpp   |  28 +-
.../app/decorator/DefaultWindowBehaviour.cpp     | 551 ++++++++++++-------
.../app/decorator/DefaultWindowBehaviour.h       |  12 +-

----------------------------------------------------------------------------

diff --git a/src/servers/app/decorator/DefaultDecorator.cpp 
b/src/servers/app/decorator/DefaultDecorator.cpp
index 4e1b245..c669b3e 100644
--- a/src/servers/app/decorator/DefaultDecorator.cpp
+++ b/src/servers/app/decorator/DefaultDecorator.cpp
@@ -218,7 +218,33 @@ DefaultDecorator::RegionAt(BPoint where, int32& tab) const
        if (region != REGION_NONE)
                return region;
 
-       // check the resize corner
+       // check the left top corner
+       BRect leftTopLeft(fLeftBorder.left, fLeftBorder.top,
+               fLeftBorder.right, fLeftBorder.top + kBorderResizeLength);
+       BRect leftTopTop(fTopBorder.left, fTopBorder.top,
+               fTopBorder.left + kBorderResizeLength, fTopBorder.bottom);
+       if (leftTopLeft.Contains(where) || leftTopTop.Contains(where))
+               return REGION_LEFT_TOP_CORNER;
+
+       // check the left bottom corner
+       BRect leftBottomLeft(fLeftBorder.left,
+               fLeftBorder.bottom - kBorderResizeLength,
+               fLeftBorder.right, fLeftBorder.bottom);
+       BRect leftBottomBottom(fBottomBorder.left,
+               fBottomBorder.top, fBottomBorder.left + kBorderResizeLength,
+               fBottomBorder.bottom);
+       if (leftBottomLeft.Contains(where) || leftBottomBottom.Contains(where))
+               return REGION_LEFT_BOTTOM_CORNER;
+
+       // check the right top corner
+       BRect rightTopRight(fRightBorder.left, fRightBorder.top,
+               fRightBorder.right, fRightBorder.top + kBorderResizeLength);
+       BRect rightTopTop(fTopBorder.right - kBorderResizeLength, 
fTopBorder.top,
+               fTopBorder.right, fTopBorder.bottom);
+       if (rightTopRight.Contains(where) || rightTopTop.Contains(where))
+               return REGION_RIGHT_TOP_CORNER;
+
+       // check the right bottom resize corner
        if (fTopTab->look == B_DOCUMENT_WINDOW_LOOK && 
fResizeRect.Contains(where))
                return REGION_RIGHT_BOTTOM_CORNER;
 
diff --git a/src/servers/app/decorator/DefaultWindowBehaviour.cpp 
b/src/servers/app/decorator/DefaultWindowBehaviour.cpp
index d6650d0..585d305 100644
--- a/src/servers/app/decorator/DefaultWindowBehaviour.cpp
+++ b/src/servers/app/decorator/DefaultWindowBehaviour.cpp
@@ -86,6 +86,31 @@ protected:
 };
 
 
+// #pragma mark - ManageWindowState Definition
+
+
+struct DefaultWindowBehaviour::ManageWindowState : State {
+                                       
ManageWindowState(DefaultWindowBehaviour& behavior,
+                                               BPoint where);
+                                       
ManageWindowState(DefaultWindowBehaviour& behavior,
+                                               BPoint where, int8 horizontal, 
int8 vertical);
+       virtual void    EnterState(State* previousState);
+       virtual void    ExitState(State* nextState);
+       virtual bool    MouseDown(BMessage* message, BPoint where,
+                                               bool& _unhandled);
+       virtual void    MouseMoved(BMessage* message, BPoint where, bool 
isFake);
+       virtual void    ModifiersChanged(BPoint where, int32 modifiers);
+
+private:
+                       void    _UpdateResizeArrows(BPoint where);
+
+private:
+                       BPoint  fLastMousePosition;
+                       int8    fHorizontal;
+                       int8    fVertical;
+};
+
+
 // #pragma mark - MouseTrackingState
 
 
@@ -215,6 +240,14 @@ struct DefaultWindowBehaviour::DragState : 
MouseTrackingState {
        {
        }
 
+       virtual void EnterState(State* previousState)
+       {
+       }
+
+       virtual void ExitState(State* nextState)
+       {
+       }
+
        virtual bool MouseDown(BMessage* message, BPoint where, bool& 
_unhandled)
        {
                // right-click while dragging shall bring the window to front
@@ -230,6 +263,25 @@ struct DefaultWindowBehaviour::DragState : 
MouseTrackingState {
                return MouseTrackingState::MouseDown(message, where, 
_unhandled);
        }
 
+       virtual void MouseUp(BMessage* message, BPoint where)
+       {
+               if 
(fBehavior._IsWindowModifier(message->FindInt32("modifiers"))) {
+                       // If the window modifiers are held return to the window
+                       // management state.
+                       fBehavior._NextState(new(std::nothrow) 
ManageWindowState(
+                               fBehavior, where));
+               } else
+                       fBehavior._NextState(NULL);
+       }
+
+       virtual void ModifiersChanged(BPoint where, int32 modifiers)
+       {
+               // Exit if user lifted window management modifiers
+               fBehavior.fLastModifiers = modifiers;
+               if (!fBehavior._IsWindowModifier(modifiers))
+                       fBehavior._NextState(NULL);
+       }
+
        virtual void MouseMovedAction(BPoint& delta, bigtime_t now)
        {
                if (!(fWindow->Flags() & B_NOT_MOVABLE)) {
@@ -356,7 +408,8 @@ struct DefaultWindowBehaviour::ResizeBorderState : 
MouseTrackingState {
        {
                switch (region) {
                        case Decorator::REGION_TAB:
-                               // TODO: Handle like the border it is attached 
to (top/left)?
+                               fHorizontal = NONE;
+                               fVertical = NONE;
                                break;
                        case Decorator::REGION_LEFT_BORDER:
                                fHorizontal = LEFT;
@@ -403,21 +456,30 @@ struct DefaultWindowBehaviour::ResizeBorderState : 
MouseTrackingState {
 
        virtual void EnterState(State* previousState)
        {
-               if ((fWindow->Flags() & B_NOT_RESIZABLE) != 0)
-                       fHorizontal = fVertical = NONE;
-               else {
-                       if ((fWindow->Flags() & B_NOT_H_RESIZABLE) != 0)
-                               fHorizontal = NONE;
-
-                       if ((fWindow->Flags() & B_NOT_V_RESIZABLE) != 0)
-                               fVertical = NONE;
-               }
                fBehavior._SetResizeCursor(fHorizontal, fVertical);
        }
 
        virtual void ExitState(State* nextState)
        {
-               fBehavior._ResetResizeCursor();
+       }
+
+       virtual void MouseUp(BMessage* message, BPoint where)
+       {
+               if 
(fBehavior._IsWindowModifier(message->FindInt32("modifiers"))) {
+                       // If the window modifiers are still held return to 
window
+                       // management state.
+                       fBehavior._NextState(new(std::nothrow) 
ManageWindowState(
+                               fBehavior, where, fHorizontal, fVertical));
+               } else
+                       fBehavior._NextState(NULL);
+       }
+
+       virtual void ModifiersChanged(BPoint where, int32 modifiers)
+       {
+               // Exit if user lifted window management modifiers
+               fBehavior.fLastModifiers = modifiers;
+               if (!fBehavior._IsWindowModifier(modifiers))
+                       fBehavior._NextState(NULL);
        }
 
        virtual void MouseMovedAction(BPoint& delta, bigtime_t now)
@@ -580,100 +642,138 @@ protected:
 // #pragma mark - ManageWindowState
 
 
-struct DefaultWindowBehaviour::ManageWindowState : State {
-       ManageWindowState(DefaultWindowBehaviour& behavior, BPoint where)
-               :
-               State(behavior),
-               fLastMousePosition(where),
-               fHorizontal(NONE),
-               fVertical(NONE)
-       {
-       }
+DefaultWindowBehaviour::ManageWindowState::ManageWindowState(
+       DefaultWindowBehaviour& behavior, BPoint where)
+       :
+       State(behavior),
+       fLastMousePosition(where),
+       fHorizontal(NONE),
+       fVertical(NONE)
+{
+}
 
-       virtual void EnterState(State* previousState)
-       {
-               _UpdateBorders(fLastMousePosition);
-       }
 
-       virtual void ExitState(State* nextState)
-       {
-               fBehavior._SetBorderHighlights(fHorizontal, fVertical, false);
-       }
+DefaultWindowBehaviour::ManageWindowState::ManageWindowState(
+       DefaultWindowBehaviour& behavior, BPoint where, int8 horizontal,
+       int8 vertical)
+       :
+       State(behavior),
+       fLastMousePosition(where),
+       fHorizontal(horizontal),
+       fVertical(vertical)
+{
+}
 
-       virtual bool MouseDown(BMessage* message, BPoint where, bool& 
_unhandled)
-       {
-               // We're only interested, if the secondary mouse button was 
pressed.
-               // Othewise let the our caller handle the event.
-               int32 buttons = message->FindInt32("buttons");
-               if ((buttons & B_SECONDARY_MOUSE_BUTTON) == 0) {
-                       _unhandled = true;
-                       return true;
-               }
 
-               fBehavior._NextState(new (std::nothrow) 
ResizeBorderState(fBehavior,
-                       where, fHorizontal, fVertical));
-               return true;
-       }
+void
+DefaultWindowBehaviour::ManageWindowState::EnterState(State* previousState)
+{
+       // Update the mouse cursor
+       if ((fWindow->Flags() & B_NOT_MOVABLE) == 0)
+               fBehavior._SetMoveCursor();
+       else
+               fBehavior._SetNowAllowedCursor();
 
-       virtual void MouseMoved(BMessage* message, BPoint where, bool isFake)
-       {
-               // If the mouse is still over our window, update the borders. 
Otherwise
-               // leave the state.
-               if (fDesktop->WindowAt(where) == fWindow) {
-                       fLastMousePosition = where;
-                       _UpdateBorders(fLastMousePosition);
+       _UpdateResizeArrows(fLastMousePosition);
+}
+
+
+void
+DefaultWindowBehaviour::ManageWindowState::ExitState(State* nextState)
+{
+}
+
+
+bool
+DefaultWindowBehaviour::ManageWindowState::MouseDown(BMessage* message,
+       BPoint where, bool& _unhandled)
+{
+       int32 buttons = message->FindInt32("buttons");
+       if ((buttons & B_PRIMARY_MOUSE_BUTTON) != 0) {
+               if ((fWindow->Flags() & B_NOT_MOVABLE) == 0) {
+                       fBehavior._SetMoveCursor();
+                       fBehavior._NextState(new (std::nothrow) 
DragState(fBehavior,
+                               where, false, false));
+               }
+       } else if ((buttons & B_SECONDARY_MOUSE_BUTTON) != 0) {
+               if ((fWindow->Flags() & B_NOT_RESIZABLE) == 0) {
+                       fBehavior._NextState(new (std::nothrow) 
ResizeBorderState(
+                               fBehavior, where, fHorizontal, fVertical));
                } else
-                       fBehavior._NextState(NULL);
+                       fBehavior._SetNowAllowedCursor();
        }
 
-       virtual void ModifiersChanged(BPoint where, int32 modifiers)
-       {
-               if (!fBehavior._IsWindowModifier(modifiers))
-                       fBehavior._NextState(NULL);
-       }
+       return true;
+}
 
-private:
-       void _UpdateBorders(BPoint where)
-       {
-               if ((fWindow->Flags() & B_NOT_RESIZABLE) != 0)
-                       return;
 
-               // Compute the window center relative location of where. We 
divide by
-               // the width respective the height, so we compensate for the 
window's
-               // aspect ratio.
-               BRect frame(fWindow->Frame());
-               if (frame.Width() + 1 == 0 || frame.Height() + 1 == 0)
-                       return;
+void
+DefaultWindowBehaviour::ManageWindowState::MouseMoved(BMessage* message,
+       BPoint where, bool isFake)
+{
+       // Update the mouse cursor
+       if ((fDesktop->WindowAt(where)->Flags() & B_NOT_RESIZABLE) != 0
+               && (message->FindInt32("buttons") & B_SECONDARY_MOUSE_BUTTON) 
!= 0) {
+               fBehavior._SetNowAllowedCursor();
+       } else if ((fDesktop->WindowAt(where)->Flags() & B_NOT_MOVABLE) == 0)
+               fBehavior._SetMoveCursor();
+       else
+               fBehavior._SetNowAllowedCursor();
+
+       // If the cursor is still over our window, update the borders.
+       // Otherwise leave the state.
+       if (fDesktop->WindowAt(where) == fWindow) {
+               fLastMousePosition = where;
+               _UpdateResizeArrows(fLastMousePosition);
+       } else
+               fBehavior._NextState(NULL);
+}
 
-               float x = (where.x - (frame.left + frame.right) / 2)
-                       / (frame.Width() + 1);
-               float y = (where.y - (frame.top + frame.bottom) / 2)
-                       / (frame.Height() + 1);
-
-               // compute the resize direction
-               int8 horizontal;
-               int8 vertical;
-               _ComputeResizeDirection(x, y, horizontal, vertical);
-
-               if ((fWindow->Flags() & B_NOT_H_RESIZABLE) != 0)
-                       horizontal = NONE;
-               if ((fWindow->Flags() & B_NOT_V_RESIZABLE) != 0)
-                       vertical = NONE;
-
-               // update the highlight, if necessary
-               if (horizontal != fHorizontal || vertical != fVertical) {
-                       fBehavior._SetBorderHighlights(fHorizontal, fVertical, 
false);
-                       fHorizontal = horizontal;
-                       fVertical = vertical;
-                       fBehavior._SetBorderHighlights(fHorizontal, fVertical, 
true);
-               }
+
+void
+DefaultWindowBehaviour::ManageWindowState::ModifiersChanged(BPoint where,
+       int32 modifiers)
+{
+       fBehavior.fLastModifiers = modifiers;
+       if (!fBehavior._IsWindowModifier(modifiers)) {
+               if ((fWindow->Flags() & B_NOT_RESIZABLE) == 0
+                       && fBehavior._IsControlModifier(modifiers)) {
+                       fBehavior._SetBorderResizeCursor(where);
+               } else
+                       fBehavior._ResetCursor();
+
+               fBehavior._NextState(NULL);
        }
+}
 
-private:
-       BPoint  fLastMousePosition;
-       int8    fHorizontal;
-       int8    fVertical;
-};
+
+void
+DefaultWindowBehaviour::ManageWindowState::_UpdateResizeArrows(BPoint where)
+{
+       if ((fWindow->Flags() & B_NOT_RESIZABLE) != 0)
+               return;
+
+       // Compute the window center relative location of where. We divide by
+       // the width respective the height, so we compensate for the window's
+       // aspect ratio.
+       BRect frame(fWindow->Frame());
+       if (frame.Width() + 1 == 0 || frame.Height() + 1 == 0)
+               return;
+
+       float x = (where.x - (frame.left + frame.right) / 2)
+               / (frame.Width() + 1);
+       float y = (where.y - (frame.top + frame.bottom) / 2)
+               / (frame.Height() + 1);
+
+       // compute the resize direction
+       _ComputeResizeDirection(x, y, fHorizontal, fVertical);
+
+       // set resize direction to NONE if not resizable
+       if ((fWindow->Flags() & B_NOT_H_RESIZABLE) != 0)
+               fHorizontal = NONE;
+       if ((fWindow->Flags() & B_NOT_V_RESIZABLE) != 0)
+               fVertical = NONE;
+}
 
 
 // #pragma mark - DefaultWindowBehaviour
@@ -742,7 +842,34 @@ DefaultWindowBehaviour::MouseDown(BMessage* message, 
BPoint where,
                // translate the region into an action
                uint32 flags = fWindow->Flags();
 
-               if ((buttons & B_PRIMARY_MOUSE_BUTTON) != 0) {
+               if ((buttons & B_SECONDARY_MOUSE_BUTTON) != 0
+                       || _IsControlModifier(fLastModifiers)
+                               && (buttons & B_PRIMARY_MOUSE_BUTTON) != 0) {
+                       // right mouse button or control + left mouse button
+                       switch (hitRegion) {
+                               case Decorator::REGION_TAB:
+                               case Decorator::REGION_CLOSE_BUTTON:
+                               case Decorator::REGION_ZOOM_BUTTON:
+                               case Decorator::REGION_MINIMIZE_BUTTON:
+                                       // Right clicking on the window tab 
sends it behind
+                                       fDesktop->SendWindowBehind(fWindow);
+                                       break;
+                               case Decorator::REGION_LEFT_BORDER:
+                               case Decorator::REGION_RIGHT_BORDER:
+                               case Decorator::REGION_TOP_BORDER:
+                               case Decorator::REGION_BOTTOM_BORDER:
+                               case Decorator::REGION_LEFT_TOP_CORNER:
+                               case Decorator::REGION_LEFT_BOTTOM_CORNER:
+                               case Decorator::REGION_RIGHT_TOP_CORNER:
+                               case Decorator::REGION_RIGHT_BOTTOM_CORNER:
+                                       action = (flags & B_NOT_RESIZABLE) == 0
+                                               ? ACTION_RESIZE_BORDER : 
ACTION_DRAG;
+                                       break;
+
+                               default:
+                                       break;
+                       }
+               } else if ((buttons & B_PRIMARY_MOUSE_BUTTON) != 0) {
                        // left mouse button
                        switch (hitRegion) {
                                case Decorator::REGION_TAB: {
@@ -795,27 +922,6 @@ DefaultWindowBehaviour::MouseDown(BMessage* message, 
BPoint where,
                                default:
                                        break;
                        }
-               } else if ((buttons & B_SECONDARY_MOUSE_BUTTON) != 0) {
-                       // right mouse button
-                       switch (hitRegion) {
-                               case Decorator::REGION_TAB:
-                               case Decorator::REGION_LEFT_BORDER:
-                               case Decorator::REGION_RIGHT_BORDER:
-                               case Decorator::REGION_TOP_BORDER:
-                               case Decorator::REGION_BOTTOM_BORDER:
-                               case Decorator::REGION_CLOSE_BUTTON:
-                               case Decorator::REGION_ZOOM_BUTTON:
-                               case Decorator::REGION_MINIMIZE_BUTTON:
-                               case Decorator::REGION_LEFT_TOP_CORNER:
-                               case Decorator::REGION_LEFT_BOTTOM_CORNER:
-                               case Decorator::REGION_RIGHT_TOP_CORNER:
-                               case Decorator::REGION_RIGHT_BOTTOM_CORNER:
-                                       action = ACTION_RESIZE_BORDER;
-                                       break;
-
-                               default:
-                                       break;
-                       }
                }
        }
 
@@ -894,22 +1000,20 @@ DefaultWindowBehaviour::MouseDown(BMessage* message, 
BPoint where,
 
 
 void
-DefaultWindowBehaviour::MouseUp(BMessage* message, BPoint where)
-{
-       if (fState != NULL)
-               fState->MouseUp(message, where);
-}
-
-
-void
-DefaultWindowBehaviour::MouseMoved(BMessage* message, BPoint where, bool 
isFake)
+DefaultWindowBehaviour::MouseMoved(BMessage* message, BPoint where,
+       bool isFake)
 {
        if (fState != NULL) {
                fState->MouseMoved(message, where, isFake);
        } else {
-               // If the window modifiers are hold, enter the window 
management state.
-               if (_IsWindowModifier(message->FindInt32("modifiers")))
+               if (_IsWindowModifier(message->FindInt32("modifiers"))) {
+                       // Enter the window management state.
                        _NextState(new(std::nothrow) ManageWindowState(*this, 
where));
+               } else if ((fWindow->Flags() & B_NOT_RESIZABLE) == 0
+                       && _IsControlModifier(message->FindInt32("modifiers"))) 
{
+                       _SetBorderResizeCursor(where);
+               } else
+                       _ResetCursor();
        }
 
        // change focus in FFM mode
@@ -925,6 +1029,14 @@ DefaultWindowBehaviour::MouseMoved(BMessage* message, 
BPoint where, bool isFake)
 
 
 void
+DefaultWindowBehaviour::MouseUp(BMessage* message, BPoint where)
+{
+       if (fState != NULL)
+               fState->MouseUp(message, where);
+}
+
+
+void
 DefaultWindowBehaviour::ModifiersChanged(int32 modifiers)
 {
        BPoint where;
@@ -934,9 +1046,14 @@ DefaultWindowBehaviour::ModifiersChanged(int32 modifiers)
        if (fState != NULL) {
                fState->ModifiersChanged(where, modifiers);
        } else {
-               // If the window modifiers are hold, enter the window 
management state.
-               if (_IsWindowModifier(modifiers))
+               if (_IsWindowModifier(modifiers)) {
+                       // Enter the window management state.
                        _NextState(new(std::nothrow) ManageWindowState(*this, 
where));
+               } else if ((fWindow->Flags() & B_NOT_RESIZABLE) == 0
+                       && _IsControlModifier(modifiers)) {
+                       _SetBorderResizeCursor(where);
+               } else
+                       _ResetCursor();
        }
 }
 
@@ -954,7 +1071,16 @@ DefaultWindowBehaviour::_IsWindowModifier(int32 
modifiers) const
 {
        return (fWindow->Flags() & B_NO_SERVER_SIDE_WINDOW_MODIFIERS) == 0
                && (modifiers & (B_COMMAND_KEY | B_CONTROL_KEY | B_OPTION_KEY
-                               | B_SHIFT_KEY)) == (B_COMMAND_KEY | 
B_CONTROL_KEY);
+                       | B_SHIFT_KEY)) == (B_COMMAND_KEY | B_CONTROL_KEY);
+}
+
+
+bool
+DefaultWindowBehaviour::_IsControlModifier(int32 modifiers) const
+{
+       return (fWindow->Flags() & B_NO_SERVER_SIDE_WINDOW_MODIFIERS) == 0
+               && (modifiers & (B_COMMAND_KEY | B_CONTROL_KEY | B_OPTION_KEY
+                       | B_SHIFT_KEY)) == B_CONTROL_KEY;
 }
 
 
@@ -973,72 +1099,6 @@ DefaultWindowBehaviour::_RegionFor(const BMessage* 
message, int32& tab) const
 }
 
 
-void
-DefaultWindowBehaviour::_SetBorderHighlights(int8 horizontal, int8 vertical,
-       bool active)
-{
-       if (Decorator* decorator = fWindow->Decorator()) {
-               uint8 highlight = active
-                       ? Decorator::HIGHLIGHT_RESIZE_BORDER
-                       : Decorator::HIGHLIGHT_NONE;
-
-               // set the highlights for the borders
-               BRegion dirtyRegion;
-               switch (horizontal) {
-                       case LEFT:
-                               
decorator->SetRegionHighlight(Decorator::REGION_LEFT_BORDER,
-                                       highlight, &dirtyRegion);
-                               break;
-                       case RIGHT:
-                               decorator->SetRegionHighlight(
-                                       Decorator::REGION_RIGHT_BORDER, 
highlight,
-                                       &dirtyRegion);
-                               break;
-               }
-
-               switch (vertical) {
-                       case TOP:
-                               
decorator->SetRegionHighlight(Decorator::REGION_TOP_BORDER,
-                                       highlight, &dirtyRegion);
-                               break;
-                       case BOTTOM:
-                               decorator->SetRegionHighlight(
-                                       Decorator::REGION_BOTTOM_BORDER, 
highlight,
-                                       &dirtyRegion);
-                               break;
-               }
-
-               // set the highlights for the corners
-               if (horizontal != NONE && vertical != NONE) {
-                       if (horizontal == LEFT) {
-                               if (vertical == TOP) {
-                                       decorator->SetRegionHighlight(
-                                               
Decorator::REGION_LEFT_TOP_CORNER, highlight,
-                                               &dirtyRegion);
-                               } else {
-                                       decorator->SetRegionHighlight(
-                                               
Decorator::REGION_LEFT_BOTTOM_CORNER, highlight,
-                                               &dirtyRegion);
-                               }
-                       } else {
-                               if (vertical == TOP) {
-                                       decorator->SetRegionHighlight(
-                                               
Decorator::REGION_RIGHT_TOP_CORNER, highlight,
-                                               &dirtyRegion);
-                               } else {
-                                       decorator->SetRegionHighlight(
-                                               
Decorator::REGION_RIGHT_BOTTOM_CORNER, highlight,
-                                               &dirtyRegion);
-                               }
-                       }
-               }
-
-               // invalidate the affected regions
-               fWindow->ProcessDirtyRegion(dirtyRegion);
-       }
-}
-
-
 ServerCursor*
 DefaultWindowBehaviour::_ResizeCursorFor(int8 horizontal, int8 vertical)
 {
@@ -1047,23 +1107,23 @@ DefaultWindowBehaviour::_ResizeCursorFor(int8 
horizontal, int8 vertical)
 
        if (horizontal == LEFT) {
                if (vertical == TOP)
-                       cursorID = B_CURSOR_ID_RESIZE_NORTH_WEST;
+                       cursorID = B_CURSOR_ID_RESIZE_NORTH_WEST_SOUTH_EAST;
                else if (vertical == BOTTOM)
-                       cursorID = B_CURSOR_ID_RESIZE_SOUTH_WEST;
+                       cursorID = B_CURSOR_ID_RESIZE_NORTH_EAST_SOUTH_WEST;
                else
-                       cursorID = B_CURSOR_ID_RESIZE_WEST;
+                       cursorID = B_CURSOR_ID_RESIZE_EAST_WEST;
        } else if (horizontal == RIGHT) {
                if (vertical == TOP)
-                       cursorID = B_CURSOR_ID_RESIZE_NORTH_EAST;
+                       cursorID = B_CURSOR_ID_RESIZE_NORTH_EAST_SOUTH_WEST;
                else if (vertical == BOTTOM)
-                       cursorID = B_CURSOR_ID_RESIZE_SOUTH_EAST;
+                       cursorID = B_CURSOR_ID_RESIZE_NORTH_WEST_SOUTH_EAST;
                else
-                       cursorID = B_CURSOR_ID_RESIZE_EAST;
+                       cursorID = B_CURSOR_ID_RESIZE_EAST_WEST;
        } else {
                if (vertical == TOP)
-                       cursorID = B_CURSOR_ID_RESIZE_NORTH;
+                       cursorID = B_CURSOR_ID_RESIZE_NORTH_SOUTH;
                else if (vertical == BOTTOM)
-                       cursorID = B_CURSOR_ID_RESIZE_SOUTH;
+                       cursorID = B_CURSOR_ID_RESIZE_NORTH_SOUTH;
        }
 
        return fDesktop->GetCursorManager().GetCursor(cursorID);
@@ -1071,6 +1131,22 @@ DefaultWindowBehaviour::_ResizeCursorFor(int8 
horizontal, int8 vertical)
 
 
 void
+DefaultWindowBehaviour::_SetMoveCursor()
+{
+       fDesktop->SetManagementCursor(
+               fDesktop->GetCursorManager().GetCursor(B_CURSOR_ID_MOVE));
+}
+
+
+void
+DefaultWindowBehaviour::_SetNowAllowedCursor()
+{
+       fDesktop->SetManagementCursor(
+               
fDesktop->GetCursorManager().GetCursor(B_CURSOR_ID_NOT_ALLOWED));
+}
+
+
+void
 DefaultWindowBehaviour::_SetResizeCursor(int8 horizontal, int8 vertical)
 {
        fDesktop->SetManagementCursor(_ResizeCursorFor(horizontal, vertical));
@@ -1078,7 +1154,76 @@ DefaultWindowBehaviour::_SetResizeCursor(int8 
horizontal, int8 vertical)
 
 
 void
-DefaultWindowBehaviour::_ResetResizeCursor()
+DefaultWindowBehaviour::_SetBorderResizeCursor(BPoint where)
+{
+       Decorator* decorator = fWindow->Decorator();
+       if (!decorator->GetFootprint().Contains(where)) {
+               // not over window
+               _ResetCursor();
+               return;
+       }
+
+       Decorator::Region hitRegion = Decorator::REGION_NONE;
+       int32 tab = -1;
+
+       BMessage* message = new BMessage();
+       message->AddPoint("where", where);
+       hitRegion = _RegionFor(message, tab);
+       delete message;
+
+       int8 horizontal = NONE;
+       int8 vertical = NONE;
+
+       switch (hitRegion) {
+               case Decorator::REGION_TAB:
+                       break;
+               case Decorator::REGION_LEFT_BORDER:
+                       horizontal = LEFT;
+                       break;
+               case Decorator::REGION_RIGHT_BORDER:
+                       horizontal = RIGHT;
+                       break;
+               case Decorator::REGION_TOP_BORDER:
+                       vertical = TOP;
+                       break;
+               case Decorator::REGION_BOTTOM_BORDER:
+                       vertical = BOTTOM;
+                       break;
+               case Decorator::REGION_CLOSE_BUTTON:
+               case Decorator::REGION_ZOOM_BUTTON:
+               case Decorator::REGION_MINIMIZE_BUTTON:
+                       break;
+               case Decorator::REGION_LEFT_TOP_CORNER:
+                       horizontal = LEFT;
+                       vertical = TOP;
+                       break;
+               case Decorator::REGION_LEFT_BOTTOM_CORNER:
+                       horizontal = LEFT;
+                       vertical = BOTTOM;
+                       break;
+               case Decorator::REGION_RIGHT_TOP_CORNER:
+                       horizontal = RIGHT;
+                       vertical = TOP;
+                       break;
+               case Decorator::REGION_RIGHT_BOTTOM_CORNER:
+                       horizontal = RIGHT;
+                       vertical = BOTTOM;
+                       break;
+               default:
+                       break;
+       }
+
+       if ((fWindow->Flags() & B_NOT_H_RESIZABLE) != 0)
+               horizontal = NONE;
+       if ((fWindow->Flags() & B_NOT_V_RESIZABLE) != 0)
+               vertical = NONE;
+
+       _SetResizeCursor(horizontal, vertical);
+}
+
+
+void
+DefaultWindowBehaviour::_ResetCursor()
 {
        fDesktop->SetManagementCursor(NULL);
 }
diff --git a/src/servers/app/decorator/DefaultWindowBehaviour.h 
b/src/servers/app/decorator/DefaultWindowBehaviour.h
index 3ad3f9f..7021a0b 100644
--- a/src/servers/app/decorator/DefaultWindowBehaviour.h
+++ b/src/servers/app/decorator/DefaultWindowBehaviour.h
@@ -87,18 +87,22 @@ private:
                        friend struct ManageWindowState;
 
 private:
+                       bool                            
_IsControlModifier(int32 modifiers) const;
                        bool                            _IsWindowModifier(int32 
modifiers) const;
                        Decorator::Region       _RegionFor(const BMessage* 
message,
                                                                        int32& 
tab) const;
 
-                       void                            
_SetBorderHighlights(int8 horizontal,
-                                                                       int8 
vertical, bool active);
-
                        ServerCursor*           _ResizeCursorFor(int8 
horizontal,
                                                                        int8 
vertical);
+
+                       void                            _SetMoveCursor();
+                       void                            _SetNowAllowedCursor();
                        void                            _SetResizeCursor(int8 
horizontal,
                                                                        int8 
vertical);
-                       void                            _ResetResizeCursor();
+                       void                            
_SetBorderResizeCursor(BPoint where);
+                       void                            _ResetCursor();
+
+                       void                            
_UpdateResizeArrows(BPoint where);
        static  void                            _ComputeResizeDirection(float 
x, float y,
                                                                        int8& 
_horizontal, int8& _vertical);
 


Other related posts: