[haiku-commits] r39602 - in haiku/trunk/src: add-ons/decorators/BeDecorator add-ons/decorators/MacDecorator add-ons/decorators/SATDecorator add-ons/decorators/WinDecorator servers/app

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 24 Nov 2010 03:09:51 +0100 (CET)

Author: bonefish
Date: 2010-11-24 03:09:50 +0100 (Wed, 24 Nov 2010)
New Revision: 39602
Changeset: http://dev.haiku-os.org/changeset/39602
Ticket: http://dev.haiku-os.org/ticket/6868

Modified:
   haiku/trunk/src/add-ons/decorators/BeDecorator/BeDecorator.cpp
   haiku/trunk/src/add-ons/decorators/MacDecorator/MacDecorator.cpp
   haiku/trunk/src/add-ons/decorators/MacDecorator/MacDecorator.h
   haiku/trunk/src/add-ons/decorators/SATDecorator/StackAndTile.cpp
   haiku/trunk/src/add-ons/decorators/WinDecorator/WinDecorator.cpp
   haiku/trunk/src/add-ons/decorators/WinDecorator/WinDecorator.h
   haiku/trunk/src/servers/app/Decorator.cpp
   haiku/trunk/src/servers/app/Decorator.h
   haiku/trunk/src/servers/app/DefaultDecorator.cpp
   haiku/trunk/src/servers/app/DefaultDecorator.h
   haiku/trunk/src/servers/app/DefaultWindowBehaviour.cpp
   haiku/trunk/src/servers/app/DefaultWindowBehaviour.h
Log:
* Decorator: Replaced the MouseAction() method with a new RegionAt().
  RegionAt() just gets a point and returns which region was hit. This is in
  order to move behavioral code to [Default]WindowBehaviour. I'm not happy
  with this solution either, but to do it properly one would have to break the
  Decorator interface into separate look and feel interfaces and reorganize the
  interaction with WindowBehaviour. A task for the so-inclined reader. :-)
* Adjusted the Decorators implementations, but really tested only the default
  one.
* DefaultWindowBehaviour:
  - Replaced _ActionFor() method by a _RegionFor() which interprets the region
    returned by Decorator::RegionAt() and converts it to a "functional" region,
    i.e. combines cases we handle the same way.
  - MouseDown():
    - Handle the click region cases more in detail, disentangling the mouse
      button cases. With the following effects:
      - The middle mouse button has no effect anymore.
      - Left and right mouse buttons no longer share common behavior. A right
        click on a decorator button will send the window to the back.
    - The window key window management modifier combo does now have precedence,
      i.e. Cmd-Ctrl-click on the decorator buttons will have the same effect as
      clicking anywhere in the window.
    - When modifiers change between the clicks, reset the click count. Prevents
      a standard click in the window followed by a Cmd-Ctrl-click from being
      recognized as a double-click.
  - Mouse*(): Introduced a fMinimizeCheckOnMouseUp which works similar to
    fActivateOnMouseUp, just for double-clicks. The decision whether a
    double-click minimizes the window is postponed until releasing the mouse
    button. After moving the mouse sufficiently far or waiting half a second
    without moving the mouse the window will no longer be minimized. Fixes
    #6868.
  - MouseUp(): Moved the primary mouse button check without the
    "decorator != NULL" block. I suppose this fixes issues with the Cmd-Ctrl
    actions and decoratorless windows (if those actually exist).

I can't wait to hear what things I've broken. :-)


Modified: haiku/trunk/src/add-ons/decorators/BeDecorator/BeDecorator.cpp
===================================================================
--- haiku/trunk/src/add-ons/decorators/BeDecorator/BeDecorator.cpp      
2010-11-24 02:02:00 UTC (rev 39601)
+++ haiku/trunk/src/add-ons/decorators/BeDecorator/BeDecorator.cpp      
2010-11-24 02:09:50 UTC (rev 39602)
@@ -89,7 +89,7 @@
        :
        DecorAddOn(id, name)
 {
-       
+
 }
 
 
@@ -214,76 +214,47 @@
 }
 
 
-click_type
-BeDecorator::MouseAction(const BMessage* message, BPoint point, int32 buttons,
-       int32 modifiers)
+Decorator::Region
+BeDecorator::RegionAt(BPoint where) const
 {
-#ifdef DEBUG_DECORATOR
-       printf("BeDecorator: Clicked\n");
-       printf("\tPoint: (%.1f,%.1f)\n", point.x, point.y);
-       printf("\tButtons: %ld, Modifiers: 0x%lx\n", buttons, modifiers);
-#endif // DEBUG_DECORATOR
+       // Let the base class version identify hits of the buttons and the tab.
+       Region region = Decorator::RegionAt(where);
+       if (region != REGION_NONE)
+               return region;
 
-       if (buttons != 0)
-               fWasDoubleClick = message->FindInt32("clicks") == 2;
+       // check the resize corner
+       if (fLook == B_DOCUMENT_WINDOW_LOOK && fResizeRect.Contains(where))
+               return REGION_RIGHT_BOTTOM_CORNER;
 
-       // In checking for hit test stuff, we start with the smallest rectangles
-       // the user might be clicking on and gradually work our way out into 
larger
-       // rectangles.
-       if (!(fFlags & B_NOT_CLOSABLE) && fCloseRect.Contains(point))
-               return CLICK_CLOSE;
+       // hit-test the borders
+       if (fLeftBorder.Contains(where))
+               return REGION_LEFT_BORDER;
+       if (fTopBorder.Contains(where))
+               return REGION_TOP_BORDER;
 
-       if (!(fFlags & B_NOT_ZOOMABLE) && fZoomRect.Contains(point))
-               return CLICK_ZOOM;
+       // Part of the bottom and right borders may be a resize-region, so we 
have
+       // to check explicitly, if it has been it.
+       if (fRightBorder.Contains(where))
+               region = REGION_RIGHT_BORDER;
+       else if (fBottomBorder.Contains(where))
+               region = REGION_BOTTOM_BORDER;
+       else
+               return REGION_NONE;
 
-       if (fLook == B_DOCUMENT_WINDOW_LOOK && fResizeRect.Contains(point))
-               return CLICK_RESIZE;
-
-       bool clicked = false;
-
-       // Clicking in the tab?
-       if (fTabRect.Contains(point)) {
-               // tab sliding in any case if either shift key is held down
-               // except sliding up-down by moving mouse left-right would look 
strange
-               if ((modifiers & B_SHIFT_KEY) && (fLook != 
kLeftTitledWindowLook))
-                       return CLICK_SLIDE_TAB;
-
-               clicked = true;
-       } else if (fLeftBorder.Contains(point) || fRightBorder.Contains(point)
-               || fTopBorder.Contains(point) || fBottomBorder.Contains(point)) 
{
-               // Clicked on border
-
-               // check resize area
-               if (!(fFlags & B_NOT_RESIZABLE)
-                       && (fLook == B_TITLED_WINDOW_LOOK
-                               || fLook == B_FLOATING_WINDOW_LOOK
-                               || fLook == B_MODAL_WINDOW_LOOK
-                               || fLook == kLeftTitledWindowLook)) {
-                       BRect resizeRect(BPoint(fBottomBorder.right - 
kBorderResizeLength,
-                               fBottomBorder.bottom - kBorderResizeLength),
-                               fBottomBorder.RightBottom());
-                       if (resizeRect.Contains(point))
-                               return CLICK_RESIZE;
-               }
-
-               clicked = true;
+       // check resize area
+       if ((fFlags & B_NOT_RESIZABLE) == 0
+               && (fLook == B_TITLED_WINDOW_LOOK
+                       || fLook == B_FLOATING_WINDOW_LOOK
+                       || fLook == B_MODAL_WINDOW_LOOK
+                       || fLook == kLeftTitledWindowLook)) {
+               BRect resizeRect(BPoint(fBottomBorder.right - 
kBorderResizeLength,
+                       fBottomBorder.bottom - kBorderResizeLength),
+                       fBottomBorder.RightBottom());
+               if (resizeRect.Contains(where))
+                       return REGION_RIGHT_BOTTOM_CORNER;
        }
 
-       if (clicked) {
-               // NOTE: On R5, windows are not moved to back if clicked inside 
the
-               // resize area with the second mouse button. So we check this 
after
-               // the check above
-               if ((buttons & B_SECONDARY_MOUSE_BUTTON) != 0)
-                       return CLICK_MOVE_TO_BACK;
-
-               if (fWasDoubleClick && !(fFlags & B_NOT_MINIMIZABLE))
-                       return CLICK_MINIMIZE;
-
-               return CLICK_DRAG;
-       }
-
-       // Guess user didn't click anything
-       return CLICK_NONE;
+       return region;
 }
 
 

Modified: haiku/trunk/src/add-ons/decorators/MacDecorator/MacDecorator.cpp
===================================================================
--- haiku/trunk/src/add-ons/decorators/MacDecorator/MacDecorator.cpp    
2010-11-24 02:02:00 UTC (rev 39601)
+++ haiku/trunk/src/add-ons/decorators/MacDecorator/MacDecorator.cpp    
2010-11-24 02:09:50 UTC (rev 39602)
@@ -34,7 +34,7 @@
        :
        DecorAddOn(id, name)
 {
-       
+
 }
 
 
@@ -64,7 +64,7 @@
        frame_midcol = (rgb_color){ 216, 216, 216, 255 };
        frame_lowcol = (rgb_color){ 110, 110, 110, 255 };
        frame_lowercol = (rgb_color){ 0, 0, 0, 255 };
-       
+
        fButtonHighColor = (rgb_color){ 232, 232, 232, 255 };
        fButtonLowColor = (rgb_color){ 128, 128, 128, 255 };
 
@@ -72,7 +72,7 @@
        fNonFocusTextColor = settings.UIColor(B_WINDOW_INACTIVE_TEXT_COLOR);
 
        _DoLayout();
-       
+
        textoffset=5;
 
        STRACE(("MacDecorator()\n"));
@@ -117,43 +117,29 @@
 // TODO : add GetSizeLimits
 
 
-click_type
-MacDecorator::MouseAction(const BMessage* message, BPoint point, int32 buttons,
-       int32 modifiers)
+Decorator::Region
+MacDecorator::RegionAt(BPoint where) const
 {
-       if (!(fFlags & B_NOT_CLOSABLE) && fCloseRect.Contains(point)) {
-               STRACE(("MacDecorator():Clicked() - Close\n"));
-               return CLICK_CLOSE;
-       }
+       // Let the base class version identify hits of the buttons and the tab.
+       Region region = Decorator::RegionAt(where);
+       if (region != REGION_NONE)
+               return region;
 
-       if (!(fFlags & B_NOT_ZOOMABLE) && fZoomRect.Contains(point)) {
-               STRACE(("MacDecorator():Clicked() - Zoom\n"));
-               return CLICK_ZOOM;
-       }
-       
-       // Clicking in the tab?
-       if (fTabRect.Contains(point)) {
-               // Here's part of our window management stuff
-               /* TODO: This is missing CLICK_MOVETOFRONT
-               if(buttons == B_PRIMARY_MOUSE_BUTTON && !IsFocus())
-                       return CLICK_MOVETOFRONT;
-               */
-               return CLICK_DRAG;
-       }
+       // check the resize corner
+       if (fLook == B_DOCUMENT_WINDOW_LOOK && fResizeRect.Contains(where))
+               return REGION_RIGHT_BOTTOM_CORNER;
 
-       // We got this far, so user is clicking on the border?
+       // hit-test the borders
        if (!(fFlags & B_NOT_RESIZABLE)
                && (fLook == B_TITLED_WINDOW_LOOK
                        || fLook == B_FLOATING_WINDOW_LOOK
                        || fLook == B_MODAL_WINDOW_LOOK)
-               && fBorderRect.Contains(point) && !fFrame.Contains(point)) {
-               STRACE(("MacDecorator():Clicked() - Resize\n"));
-               return CLICK_RESIZE;
+               && fBorderRect.Contains(where) && !fFrame.Contains(where)) {
+               return REGION_BOTTOM_BORDER;
+                       // TODO: Determine the actual border!
        }
 
-       // Guess user didn't click anything
-       STRACE(("MacDecorator():Clicked()\n"));
-       return CLICK_NONE;
+       return REGION_NONE;
 }
 
 
@@ -215,7 +201,7 @@
                fMinimizeRect=fZoomRect;
 
                fCloseRect.OffsetTo(fTabRect.left+4,fTabRect.top+4);
-       
+
                fZoomRect.OffsetBy(0-(fZoomRect.Width()+4),0);
                if (Title() && fDrawingEngine) {
                        
titlepixelwidth=fDrawingEngine->StringWidth(Title(),strlen(Title()));
@@ -468,7 +454,7 @@
                        }
                }
 
-               // Draw the buttons if we're supposed to        
+               // Draw the buttons if we're supposed to
                if (!(fFlags & B_NOT_CLOSABLE))
                        _DrawClose(fCloseRect);
                if (!(fFlags & B_NOT_ZOOMABLE))
@@ -776,7 +762,7 @@
 
        if (fLook == B_NO_BORDER_WINDOW_LOOK)
                return;
-       
+
        region->Set(fBorderRect);
        region->Exclude(fFrame);
 

Modified: haiku/trunk/src/add-ons/decorators/MacDecorator/MacDecorator.h
===================================================================
--- haiku/trunk/src/add-ons/decorators/MacDecorator/MacDecorator.h      
2010-11-24 02:02:00 UTC (rev 39601)
+++ haiku/trunk/src/add-ons/decorators/MacDecorator/MacDecorator.h      
2010-11-24 02:09:50 UTC (rev 39602)
@@ -32,9 +32,7 @@
                        void                            Draw(BRect updateRect);
                        void                            Draw();
 
-       click_type                                      MouseAction(const 
BMessage* message,
-                                                                       BPoint 
point, int32 buttons,
-                                                                       int32 
modifiers);
+       virtual Region                          RegionAt(BPoint where) const;
 
 protected:
                        void                            _DoLayout();
@@ -57,7 +55,7 @@
                                                                        
BRegion* updateRegion = NULL);
                        void                            _SetFlags(uint32 flags,
                                                                        
BRegion* updateRegion = NULL);
-       
+
                        void                            _SetColors();
 
                        void                            _MoveBy(BPoint offset);

Modified: haiku/trunk/src/add-ons/decorators/SATDecorator/StackAndTile.cpp
===================================================================
--- haiku/trunk/src/add-ons/decorators/SATDecorator/StackAndTile.cpp    
2010-11-24 02:02:00 UTC (rev 39601)
+++ haiku/trunk/src/add-ons/decorators/SATDecorator/StackAndTile.cpp    
2010-11-24 02:09:50 UTC (rev 39602)
@@ -140,13 +140,23 @@
        // we are only interested in single clicks
        if (message->FindInt32("clicks") == 2)
                return;
-       int32 modifiers = message->FindInt32("modifiers");
-       int32 buttons = message->FindInt32("buttons");
-       click_type clickArea = satWindow->GetDecorator()->MouseAction(message,
-               where, buttons, modifiers);
-       if (clickArea != CLICK_DRAG && clickArea < CLICK_RESIZE)
-               return;
 
+       switch (satWindow->GetDecorator()->RegionAt(where)) {
+               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_LEFT_TOP_CORNER:
+               case Decorator::REGION_LEFT_BOTTOM_CORNER:
+               case Decorator::REGION_RIGHT_TOP_CORNER:
+               case Decorator::REGION_RIGHT_BOTTOM_CORNER:
+                       break;
+
+               default:
+                       return;
+       }
+
        ASSERT(fCurrentSATWindow == NULL);
        fCurrentSATWindow = satWindow;
 
@@ -330,7 +340,7 @@
        SATGroup* group = satWindow->GetGroup();
        if (!group)
                return;
-       group->RemoveWindow(satWindow); 
+       group->RemoveWindow(satWindow);
 }
 
 
@@ -617,5 +627,5 @@
 
 SATSnappingBehaviour::~SATSnappingBehaviour()
 {
-       
+
 }

Modified: haiku/trunk/src/add-ons/decorators/WinDecorator/WinDecorator.cpp
===================================================================
--- haiku/trunk/src/add-ons/decorators/WinDecorator/WinDecorator.cpp    
2010-11-24 02:02:00 UTC (rev 39601)
+++ haiku/trunk/src/add-ons/decorators/WinDecorator/WinDecorator.cpp    
2010-11-24 02:09:50 UTC (rev 39602)
@@ -77,7 +77,7 @@
 
        // Do initial decorator setup
        _DoLayout();
-       
+
        textoffset=5;
 
        STRACE(("WinDecorator()\n"));
@@ -119,40 +119,29 @@
 // TODO : add GetSizeLimits
 
 
-click_type
-WinDecorator::MouseAction(const BMessage* message, BPoint where, int32 buttons,
-       int32 modifiers)
+Decorator::Region
+WinDecorator::RegionAt(BPoint where) const
 {
-       if (!(fFlags & B_NOT_CLOSABLE) && fCloseRect.Contains(where))
-               return CLICK_CLOSE;
+       // Let the base class version identify hits of the buttons and the tab.
+       Region region = Decorator::RegionAt(where);
+       if (region != REGION_NONE)
+               return region;
 
-       if (!(fFlags & B_NOT_ZOOMABLE) && fZoomRect.Contains(where))
-               return CLICK_ZOOM;
-       
-       // Clicking in the tab?
-       if (fTabRect.Contains(where)) {
-               // Here's part of our window management stuff
-               /* TODO: This is missing CLICK_MOVETOFRONT
-               if(buttons == B_PRIMARY_MOUSE_BUTTON && !IsFocus())
-                       return CLICK_MOVETOFRONT;
-               */
-               return CLICK_DRAG;
-       }
+       // check the resize corner
+       if (fLook == B_DOCUMENT_WINDOW_LOOK && fResizeRect.Contains(where))
+               return REGION_RIGHT_BOTTOM_CORNER;
 
-       // We got this far, so user is clicking on the border?
-       if (fBorderRect.Contains(where) && !fFrame.Contains(where)) {
-               STRACE(("WinDecorator():Clicked() - Resize\n"));
-               if (!(fFlags & B_NOT_RESIZABLE)
-                       && (fLook == B_TITLED_WINDOW_LOOK
-                               || fLook == B_FLOATING_WINDOW_LOOK
-                               || fLook == B_MODAL_WINDOW_LOOK)) {
-                                       return CLICK_RESIZE;
-               }
+       // hit-test the borders
+       if (!(fFlags & B_NOT_RESIZABLE)
+               && (fLook == B_TITLED_WINDOW_LOOK
+                       || fLook == B_FLOATING_WINDOW_LOOK
+                       || fLook == B_MODAL_WINDOW_LOOK)
+               && fBorderRect.Contains(where) && !fFrame.Contains(where)) {
+               return REGION_BOTTOM_BORDER;
+                       // TODO: Determine the actual border!
        }
 
-       // Guess user didn't click anything
-       STRACE(("WinDecorator():Clicked()\n"));
-       return CLICK_NONE;
+       return REGION_NONE;
 }
 
 
@@ -162,7 +151,7 @@
        STRACE(("WinDecorator()::_DoLayout()\n"));
 
        bool hasTab = false;
-       
+
        fBorderRect=fFrame;
        fTabRect=fFrame;
 
@@ -224,13 +213,13 @@
                return;
 
        BRect r = fBorderRect;
-       
+
        fDrawingEngine->SetHighColor(frame_lowercol);
        fDrawingEngine->StrokeRect(r);
 
        if (fLook == B_BORDERED_WINDOW_LOOK)
                return;
-       
+
        BPoint pt;
 
        pt=r.RightTop();
@@ -242,7 +231,7 @@
 
        fDrawingEngine->StrokeLine(r.RightTop(),r.RightBottom(),frame_lowercol);
        
fDrawingEngine->StrokeLine(r.LeftBottom(),r.RightBottom(),frame_lowercol);
-       
+
        r.InsetBy(1,1);
        pt=r.RightTop();
        pt.x--;
@@ -253,7 +242,7 @@
 
        fDrawingEngine->StrokeLine(r.RightTop(),r.RightBottom(),frame_lowcol);
        fDrawingEngine->StrokeLine(r.LeftBottom(),r.RightBottom(),frame_lowcol);
-       
+
        r.InsetBy(1,1);
        fDrawingEngine->StrokeRect(r,frame_midcol);
        r.InsetBy(1,1);
@@ -273,7 +262,7 @@
 
        _DrawTitle(fTabRect);
 
-       // Draw the buttons if we're supposed to        
+       // Draw the buttons if we're supposed to
        // TODO : we should still draw the buttons if they are disabled, but 
grey them out
        if (!(fFlags & B_NOT_CLOSABLE) && invalid.Intersects(fCloseRect))
                _DrawClose(fCloseRect);
@@ -287,14 +276,14 @@
 {
        // Just like DrawZoom, but for a close button
        _DrawBeveledRect(r,GetClose());
-       
+
        // Draw the X
 
        BRect rect(r);
        rect.InsetBy(4,4);
        rect.right--;
        rect.top--;
-       
+
        if (GetClose())
                rect.OffsetBy(1,1);
 
@@ -333,7 +322,7 @@
 WinDecorator::_DrawZoom(BRect r)
 {
        _DrawBeveledRect(r,GetZoom());
-       
+
        // Draw the Zoom box
 
        BRect rect(r);
@@ -341,7 +330,7 @@
        rect.InsetBy(1,0);
        rect.bottom--;
        rect.right--;
-       
+
        if (GetZoom())
                rect.OffsetBy(1,1);
 
@@ -363,7 +352,7 @@
        BRect rect(r.left+5,r.bottom-4,r.right-5,r.bottom-3);
        if(GetMinimize())
                rect.OffsetBy(1,1);
-       
+
        fDrawingEngine->SetHighColor(RGBColor(0,0,0));
        fDrawingEngine->StrokeRect(rect);
 }
@@ -523,7 +512,7 @@
 
        if (fLook == B_NO_BORDER_WINDOW_LOOK)
                return;
-       
+
        region->Set(fBorderRect);
        region->Include(fTabRect);
        region->Exclude(fFrame);
@@ -553,7 +542,7 @@
        RGBColor mid;
        RGBColor low;
        RGBColor lower;
-       
+
        if (down) {
                lower.SetColor(255,255,255);
                low.SetColor(216,216,216);
@@ -582,7 +571,7 @@
        pt=rect.RightTop();
        pt.y++;
        fDrawingEngine->StrokeLine(pt,rect.RightBottom(),lower);
-       
+
        // Bottom shading
        pt=rect.LeftBottom();
        pt.x++;
@@ -600,12 +589,12 @@
        pt=rect.RightTop();
        pt.y++;
        fDrawingEngine->StrokeLine(pt,rect.RightBottom(),lower);
-       
+
        // Bottom inside shading
        pt=rect.LeftBottom();
        pt.x++;
        fDrawingEngine->StrokeLine(pt,rect.RightBottom(),lower);
-       
+
        rect.InsetBy(1,1);
 
        fDrawingEngine->FillRect(rect,mid);

Modified: haiku/trunk/src/add-ons/decorators/WinDecorator/WinDecorator.h
===================================================================
--- haiku/trunk/src/add-ons/decorators/WinDecorator/WinDecorator.h      
2010-11-24 02:02:00 UTC (rev 39601)
+++ haiku/trunk/src/add-ons/decorators/WinDecorator/WinDecorator.h      
2010-11-24 02:09:50 UTC (rev 39602)
@@ -32,9 +32,7 @@
                        void                            Draw(BRect r);
                        void                            Draw();
 
-                       click_type                      MouseAction(const 
BMessage* message,
-                                                                       BPoint 
point, int32 buttons,
-                                                                       int32 
modifiers);
+       virtual Region                          RegionAt(BPoint where) const;
 
 protected:
                        void                            _DoLayout();
@@ -57,7 +55,7 @@
                                                                        
BRegion* updateRegion = NULL);
                        void                            _SetFlags(uint32 flags,
                                                                        
BRegion* updateRegion = NULL);
-       
+
                        void                            _SetColors();
 
                        void                            _MoveBy(BPoint pt);
@@ -72,7 +70,7 @@
 
 private:
                        uint32 taboffset;
-               
+
                        rgb_color tab_highcol;
                        rgb_color tab_lowcol;
                        rgb_color frame_highcol;
@@ -85,10 +83,10 @@
                        rgb_color                       fFocusTextColor;
                        rgb_color                       fNonFocusTextColor;
                        uint64 solidhigh, solidlow;
-               
+
                        BString                         fTruncatedTitle;
                        int32                           fTruncatedTitleLength;
-               
+
                        bool slidetab;
                        int textoffset;
 };

Modified: haiku/trunk/src/servers/app/Decorator.cpp
===================================================================
--- haiku/trunk/src/servers/app/Decorator.cpp   2010-11-24 02:02:00 UTC (rev 
39601)
+++ haiku/trunk/src/servers/app/Decorator.cpp   2010-11-24 02:09:50 UTC (rev 
39602)
@@ -6,6 +6,7 @@
  *             DarkWyrm <bpmagic@xxxxxxxxxxxxxxx>
  *             Stephan Aßmus <superstippi@xxxxxx>
  *             Clemens Zeidler <haiku@xxxxxxxxxxxxxxxxxx>
+ *             Ingo Weinhold <ingo_weinhold@xxxxxx>
  */
 
 
@@ -314,44 +315,39 @@
 }
 
 
-/*!    \brief Performs hit-testing for the decorator
+/*!    \brief Performs hit-testing for the decorator.
 
-       Clicked is called whenever it has been determined that the window has
-       received a mouse click. The default version returns CLICK_NONE. A 
subclass
-       may use any or all of them.
+       The base class provides a basic implementation, recognizing only button 
and
+       tab hits. Derived classes must override/enhance it to handle borders and
+       corners correctly.
 
-       Click type : Action taken by the server
-
-       - \c CLICK_NONE: Do nothing
-       - \c CLICK_ZOOM: Handles the zoom button (setting states, etc)
-       - \c CLICK_CLOSE: Handles the close button (setting states, etc)
-       - \c CLICK_MINIMIZE: Handles the minimize button (setting states, etc)
-       - \c CLICK_TAB: Currently unused
-       - \c CLICK_DRAG: Moves the window to the front and prepares to move the
-               window
-       - \c CLICK_MOVE_TO_BACK: Moves the window to the back of the stack
-       - \c CLICK_MOVE_TO_FRONT: Moves the window to the front of the stack
-       - \c CLICK_SLIDE_TAB: Initiates tab-sliding
-
-       - \c CLICK_RESIZE: Handle window resizing as appropriate
-       - \c CLICK_RESIZE_L
-       - \c CLICK_RESIZE_T
-       - \c CLICK_RESIZE_R
-       - \c CLICK_RESIZE_B
-       - \c CLICK_RESIZE_LT
-       - \c CLICK_RESIZE_RT
-       - \c CLICK_RESIZE_LB
-       - \c CLICK_RESIZE_RB
-
-       This function is required by all subclasses.
-
-       \return The type of area clicked
+       \param where The point to be tested.
+       \return Either of the following, depending on what was hit:
+               - \c REGION_NONE: None of the decorator regions.
+               - \c REGION_TAB: The window tab (but none of the buttons 
embedded).
+               - \c REGION_CLOSE_BUTTON: The close button.
+               - \c REGION_ZOOM_BUTTON: The zoom button.
+               - \c REGION_MINIMIZE_BUTTON: The minimize button.
+               - \c REGION_LEFT_BORDER: The left border.
+               - \c REGION_RIGHT_BORDER: The right border.
+               - \c REGION_TOP_BORDER: The top border.
+               - \c REGION_BOTTOM_BORDER: The bottom border.
+               - \c REGION_LEFT_TOP_CORNER: The left-top corner.
+               - \c REGION_LEFT_BOTTOM_CORNER: The left-bottom corner.
+               - \c REGION_RIGHT_TOP_CORNER: The right-top corner.
+               - \c REGION_RIGHT_BOTTOM_CORNER The right-bottom corner.
 */
-click_type
-Decorator::MouseAction(const BMessage* message, BPoint point, int32 buttons,
-       int32 modifiers)
+Decorator::Region
+Decorator::RegionAt(BPoint where) const
 {
-       return CLICK_NONE;
+       if (fCloseRect.Contains(where))
+               return REGION_CLOSE_BUTTON;
+       if (fZoomRect.Contains(where))
+               return REGION_ZOOM_BUTTON;
+       if (fTabRect.Contains(where))
+               return REGION_TAB;
+
+       return REGION_NONE;
 }
 
 

Modified: haiku/trunk/src/servers/app/Decorator.h
===================================================================
--- haiku/trunk/src/servers/app/Decorator.h     2010-11-24 02:02:00 UTC (rev 
39601)
+++ haiku/trunk/src/servers/app/Decorator.h     2010-11-24 02:09:50 UTC (rev 
39602)
@@ -6,6 +6,7 @@
  *             DarkWyrm <bpmagic@xxxxxxxxxxxxxxx>
  *             Stephan Aßmus <superstippi@xxxxxx>
  *             Clemens Zeidler <haiku@xxxxxxxxxxxxxxxxxx>
+ *             Ingo Weinhold <ingo_weinhold@xxxxxx>
  */
 #ifndef DECORATOR_H
 #define DECORATOR_H
@@ -48,6 +49,27 @@
 
 class Decorator {
 public:
+                       enum Region {
+                               REGION_NONE,
+
+                               REGION_TAB,
+
+                               REGION_CLOSE_BUTTON,
+                               REGION_ZOOM_BUTTON,
+                               REGION_MINIMIZE_BUTTON,
+
+                               REGION_LEFT_BORDER,
+                               REGION_RIGHT_BORDER,
+                               REGION_TOP_BORDER,
+                               REGION_BOTTOM_BORDER,
+
+                               REGION_LEFT_TOP_CORNER,
+                               REGION_LEFT_BOTTOM_CORNER,
+                               REGION_RIGHT_TOP_CORNER,
+                               REGION_RIGHT_BOTTOM_CORNER
+                       };
+
+public:
                                                        
Decorator(DesktopSettings& settings, BRect rect,
                                                                window_look 
look, uint32 flags);
        virtual                                 ~Decorator();
@@ -91,8 +113,7 @@
 
                        const BRegion&  GetFootprint();
 
-       virtual click_type              MouseAction(const BMessage* message, 
BPoint where,
-                                                               int32 buttons, 
int32 modifiers);
+       virtual Region                  RegionAt(BPoint where) const;
 
                        void                    MoveBy(float x, float y);
                        void                    MoveBy(BPoint offset);

Modified: haiku/trunk/src/servers/app/DefaultDecorator.cpp
===================================================================
--- haiku/trunk/src/servers/app/DefaultDecorator.cpp    2010-11-24 02:02:00 UTC 
(rev 39601)
+++ haiku/trunk/src/servers/app/DefaultDecorator.cpp    2010-11-24 02:09:50 UTC 
(rev 39602)
@@ -8,6 +8,7 @@
  *             Philippe Saint-Pierre, stpere@xxxxxxxxx
  *             Ryan Leavengood <leavengood@xxxxxxxxx>
  *             Clemens Zeidler <haiku@xxxxxxxxxxxxxxxxxx>
+ *             Ingo Weinhold <ingo_weinhold@xxxxxx>
  */
 
 
@@ -70,8 +71,7 @@
                window_look look, uint32 flags)
        : Decorator(settings, rect, look, flags),
        fTabOffset(0),
-       fTabLocation(0.0),
-       fWasDoubleClick(false)
+       fTabLocation(0.0)
 {
        _UpdateFont(settings);
 
@@ -180,70 +180,47 @@
 }
 
 
-click_type
-DefaultDecorator::MouseAction(const BMessage* message, BPoint point,
-       int32 buttons, int32 modifiers)
+Decorator::Region
+DefaultDecorator::RegionAt(BPoint where) const
 {
-#ifdef DEBUG_DECORATOR
-       printf("DefaultDecorator: Clicked\n");
-       printf("\tPoint: (%.1f,%.1f)\n", point.x, point.y);
-       printf("\tButtons: %ld, Modifiers: 0x%lx\n", buttons, modifiers);
-#endif // DEBUG_DECORATOR
+       // Let the base class version identify hits of the buttons and the tab.
+       Region region = Decorator::RegionAt(where);
+       if (region != REGION_NONE)
+               return region;
 
-       click_type action = CLICK_NONE;
+       // check the resize corner
+       if (fLook == B_DOCUMENT_WINDOW_LOOK && fResizeRect.Contains(where))
+               return REGION_RIGHT_BOTTOM_CORNER;
 
-       // We start with the smallest rectangles the user might be clicking
-       // on and gradually work our way out into larger rectangles.
-       if (!(fFlags & B_NOT_CLOSABLE) && fCloseRect.Contains(point))
-               action = CLICK_CLOSE;
-       else if (!(fFlags & B_NOT_ZOOMABLE) && fZoomRect.Contains(point))
-               action = CLICK_ZOOM;
-       else if ((buttons & B_SECONDARY_MOUSE_BUTTON) != 0)
-               action = CLICK_MOVE_TO_BACK;
-       else if (fLook == B_DOCUMENT_WINDOW_LOOK && fResizeRect.Contains(point))
-               action = CLICK_RESIZE;
-       else if (fTabRect.Contains(point)) {
-               // Clicked in the tab
+       // hit-test the borders
+       if (fLeftBorder.Contains(where))
+               return REGION_LEFT_BORDER;
+       if (fTopBorder.Contains(where))
+               return REGION_TOP_BORDER;
 
-               // tab sliding in any case if either shift key is held down
-               // except sliding up-down by moving mouse left-right would look 
strange
-               if ((modifiers & B_SHIFT_KEY) != 0 && fLook != 
kLeftTitledWindowLook)
-                       action = CLICK_SLIDE_TAB;
-               else
-                       action = CLICK_DRAG;
-       } else if (fLeftBorder.Contains(point) || fRightBorder.Contains(point)
-               || fTopBorder.Contains(point) || fBottomBorder.Contains(point)) 
{
-               // Clicked on border
+       // Part of the bottom and right borders may be a resize-region, so we 
have
+       // to check explicitly, if it has been it.
+       if (fRightBorder.Contains(where))
+               region = REGION_RIGHT_BORDER;
+       else if (fBottomBorder.Contains(where))
+               region = REGION_BOTTOM_BORDER;
+       else
+               return REGION_NONE;
 
-               // check resize area
-               if (!(fFlags & B_NOT_RESIZABLE)
-                       && (fLook == B_TITLED_WINDOW_LOOK
-                               || fLook == B_FLOATING_WINDOW_LOOK
-                               || fLook == B_MODAL_WINDOW_LOOK
-                               || fLook == kLeftTitledWindowLook)) {
-                       BRect resizeRect(BPoint(fBottomBorder.right - 
kBorderResizeLength,
-                               fBottomBorder.bottom - kBorderResizeLength),
-                               fBottomBorder.RightBottom());
-                       if (resizeRect.Contains(point))
-                               action = CLICK_RESIZE;
-               } else
-                       action = CLICK_DRAG;
+       // check resize area
+       if ((fFlags & B_NOT_RESIZABLE) == 0
+               && (fLook == B_TITLED_WINDOW_LOOK
+                       || fLook == B_FLOATING_WINDOW_LOOK
+                       || fLook == B_MODAL_WINDOW_LOOK
+                       || fLook == kLeftTitledWindowLook)) {
+               BRect resizeRect(BPoint(fBottomBorder.right - 
kBorderResizeLength,
+                       fBottomBorder.bottom - kBorderResizeLength),
+                       fBottomBorder.RightBottom());
+               if (resizeRect.Contains(where))
+                       return REGION_RIGHT_BOTTOM_CORNER;
        }
 
-       if (buttons != 0) {
-               fWasDoubleClick = message->FindInt32("clicks") == 2
-                       && fLastAction == action;
-       }
-
-       // Transform double clicks on the border to minimize, if allowed
-       if (action == CLICK_DRAG && fWasDoubleClick
-               && (fFlags & B_NOT_MINIMIZABLE) == 0)
-               action = CLICK_MINIMIZE;
-
-       if (message->what == B_MOUSE_DOWN)
-               fLastAction = action;
-
-       return action;
+       return region;
 }
 
 

Modified: haiku/trunk/src/servers/app/DefaultDecorator.h
===================================================================
--- haiku/trunk/src/servers/app/DefaultDecorator.h      2010-11-24 02:02:00 UTC 
(rev 39601)
+++ haiku/trunk/src/servers/app/DefaultDecorator.h      2010-11-24 02:09:50 UTC 
(rev 39602)
@@ -37,9 +37,7 @@
        virtual void                            GetSizeLimits(int32* minWidth, 
int32* minHeight,
                                                                        int32* 
maxWidth, int32* maxHeight) const;
 
-       virtual click_type                      MouseAction(const BMessage* 
message,
-                                                                       BPoint 
point, int32 buttons,
-                                                                       int32 
modifiers);
+       virtual Region                          RegionAt(BPoint where) const;
 
                        float                           BorderWidth();
                        float                           TabHeight();
@@ -134,10 +132,6 @@
                        float                           fMaxTabSize;
                        BString                         fTruncatedTitle;
                        int32                           fTruncatedTitleLength;
-
-private:
-                       click_type                      fLastAction;
-                       bool                            fWasDoubleClick;
 };
 
 

Modified: haiku/trunk/src/servers/app/DefaultWindowBehaviour.cpp
===================================================================
--- haiku/trunk/src/servers/app/DefaultWindowBehaviour.cpp      2010-11-24 
02:02:00 UTC (rev 39601)
+++ haiku/trunk/src/servers/app/DefaultWindowBehaviour.cpp      2010-11-24 
02:09:50 UTC (rev 39602)
@@ -9,11 +9,14 @@
  *             Axel Dörfler <axeld@xxxxxxxxxxxxxxxx>
  *             Brecht Machiels <brecht@xxxxxxxxxxx>
  *             Clemens Zeidler <haiku@xxxxxxxxxxxxxxxxxx>
+ *             Ingo Weinhold <ingo_weinhold@xxxxxx>
  */
 
 
 #include "DefaultWindowBehaviour.h"
 
+#include <WindowPrivate.h>
+
 #include "Desktop.h"
 #include "DrawingEngine.h"
 #include "Window.h"
@@ -27,6 +30,7 @@
 #endif
 
 
+// The span between mouse down
 static const bigtime_t kWindowActivationTimeout = 500000LL;
 
 
@@ -39,11 +43,14 @@
        fIsZooming(false),
        fIsSlidingTab(false),
        fActivateOnMouseUp(false),
+       fMinimizeCheckOnMouseUp(false),
 
        fLastMousePosition(0.0f, 0.0f),
        fMouseMoveDistance(0.0f),
        fLastMoveTime(0),
-       fLastSnapTime(0)
+       fLastSnapTime(0),
+       fLastModifiers(0),
+       fResetClickCount(0)
 {
        fDesktop = fWindow->Desktop();
 }
@@ -65,33 +72,106 @@
 
        int32 modifiers = message->FindInt32("modifiers");
        bool windowModifier = _IsWindowModifier(modifiers);
+
+       // Get the click count and reset it, if the modifiers changed in the
+       // meantime.
+       // TODO: This should be done in a better place (e.g. the input server). 
It
+       // should also reset clicks after mouse movement (which we don't do here
+       // either -- though that's probably acceptable).
+       int32 clickCount = message->FindInt32("clicks");
+       if (clickCount <= 1) {
+               fResetClickCount = 0;
+       } else if (modifiers != fLastModifiers
+               || clickCount - fResetClickCount < 1) {
+               fResetClickCount = clickCount - 1;
+               clickCount = 1;
+       } else
+               clickCount -= fResetClickCount;
+       fLastModifiers = modifiers;
+
+       Region hitRegion = REGION_NONE;
        click_type action = CLICK_NONE;
 
        if (windowModifier || inBorderRegion) {
-               // Click on the window border or we have the window modifier 
keys held
+               // click on the window decorator or we have the window modifier 
keys
+               // held
+
+               // get the functional hit region
+               if (windowModifier) {
+                       // click with window modifier keys -- let the whole 
window behave
+                       // like the border
+                       hitRegion = REGION_BORDER;
+               } else {
+                       // click on the decorator -- get the exact region
+                       hitRegion = _RegionFor(message);
+               }
+
+               // translate the region into an action
                int32 buttons = message->FindInt32("buttons");
+               bool leftButton = (buttons & B_PRIMARY_MOUSE_BUTTON) != 0;
+               bool rightButton = (buttons & B_SECONDARY_MOUSE_BUTTON) != 0;
+               uint32 flags = fWindow->Flags();
 
-               if (inBorderRegion)
-                       action = _ActionFor(message, buttons, modifiers);
-               else {
-                       if ((buttons & B_SECONDARY_MOUSE_BUTTON) != 0)
-                               action = CLICK_MOVE_TO_BACK;
-                       else if ((fWindow->Flags() & B_NOT_MINIMIZABLE) == 0
-                               && message->FindInt32("clicks") == 2)
-                               action = CLICK_MINIMIZE;
-                       else if ((fWindow->Flags() & B_NOT_MOVABLE) == 0
-                               && decorator != NULL)
-                               action = CLICK_DRAG;
-                       else {
-                               // pass click on to the application
-                               windowModifier = false;
-                       }
+               switch (hitRegion) {
+                       case REGION_NONE:
+                               break;
+
+                       case REGION_TAB:
+                               // tab sliding in any case if either shift key 
is held down
+                               // except sliding up-down by moving mouse 
left-right would look
+                               // strange
+                               if (leftButton && (modifiers & B_SHIFT_KEY) != 0
+                                       && fWindow->Look() != 
kLeftTitledWindowLook) {
+                                       action = CLICK_SLIDE_TAB;
+                                       break;
+                               }
+                               // otherwise fall through -- same handling as 
for the border...
+
+                       case REGION_BORDER:
+                               if (leftButton)
+                                       action = CLICK_DRAG;
+                               else if (rightButton)
+                                       action = CLICK_MOVE_TO_BACK;
+                               break;
+
+                       case REGION_CLOSE_BUTTON:
+                               if (leftButton) {
+                                       action = (flags & B_NOT_CLOSABLE) == 0
+                                               ? CLICK_CLOSE : CLICK_DRAG;
+                               } else if (rightButton)
+                                       action = CLICK_MOVE_TO_BACK;

[... truncated: 331 lines follow ...]

Other related posts: