[haiku-commits] r33814 - haiku/trunk/src/servers/app

  • From: philippe.houdoin@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 28 Oct 2009 19:46:23 +0100 (CET)

Author: phoudoin
Date: 2009-10-28 19:46:23 +0100 (Wed, 28 Oct 2009)
New Revision: 33814
Changeset: http://dev.haiku-os.org/changeset/33814/haiku

Modified:
   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/Desktop.cpp
   haiku/trunk/src/servers/app/Desktop.h
   haiku/trunk/src/servers/app/Jamfile
   haiku/trunk/src/servers/app/ServerWindow.cpp
   haiku/trunk/src/servers/app/Window.cpp
   haiku/trunk/src/servers/app/Window.h
   haiku/trunk/src/servers/app/WorkspacesView.cpp
Log:
Applied Stack & Tile patch by Hong Yul Yang, formely by Christof Lutteroth.


Modified: haiku/trunk/src/servers/app/Decorator.cpp
===================================================================
--- haiku/trunk/src/servers/app/Decorator.cpp   2009-10-28 17:39:02 UTC (rev 
33813)
+++ haiku/trunk/src/servers/app/Decorator.cpp   2009-10-28 18:46:23 UTC (rev 
33814)
@@ -44,7 +44,11 @@
        fFrame(rect),
        fResizeRect(),
        fBorderRect(),
+       fTabHighlighted(false),
+       fBordersHighlighted(false),
 
+       fWindow(NULL),
+
        fClosePressed(false),
        fZoomPressed(false),
        fMinimizePressed(false),
@@ -580,3 +584,22 @@
 Decorator::_SetFocus()
 {
 }
+
+
+void
+Decorator::HighlightTab(bool active, BRegion* dirty)
+{
+}
+
+
+void
+Decorator::HighlightBorders(bool active, BRegion* dirty)
+{
+}
+
+
+void
+Decorator::SetWindow(Window* window)
+{
+       fWindow = window;
+}

Modified: haiku/trunk/src/servers/app/Decorator.h
===================================================================
--- haiku/trunk/src/servers/app/Decorator.h     2009-10-28 17:39:02 UTC (rev 
33813)
+++ haiku/trunk/src/servers/app/Decorator.h     2009-10-28 18:46:23 UTC (rev 
33814)
@@ -21,6 +21,7 @@
 class DrawingEngine;
 class ServerFont;
 class BRegion;
+class Window;
 
 
 enum click_type {
@@ -44,6 +45,8 @@
        CLICK_RESIZE_RB
 };
 
+#include "Window.h"
+
 class Decorator {
 public:
                                                        
Decorator(DesktopSettings& settings, BRect rect,
@@ -68,6 +71,14 @@
        virtual void                    SetTitle(const char* string,
                                                                BRegion* 
updateRegion = NULL);
 
+       virtual void                    HighlightTab(bool active, BRegion* 
dirty);
+       virtual void                    HighlightBorders(bool active, BRegion* 
dirty);
+                       bool                    IsTabHighlighted()
+                                                               { return 
fTabHighlighted; }
+                       bool                    IsBordersHighlighted()
+                                                               { return 
fBordersHighlighted; }
+
+
                        window_look             Look() const;
                        uint32                  Flags() const;
 
@@ -121,6 +132,8 @@
 
                        rgb_color               UIColor(color_which which);
 
+                       void                    SetWindow(Window* window);
+
 protected:
                        int32                   _TitleWidth() const
                                                                { return 
fTitle.CountChars(); }
@@ -151,6 +164,11 @@
                        BRect                   fResizeRect;
                        BRect                   fBorderRect;
 
+                       bool                    fTabHighlighted;
+                       bool                    fBordersHighlighted;
+
+                       Window*                 fWindow;
+
 private:
                        bool                    fClosePressed : 1;
                        bool                    fZoomPressed : 1;

Modified: haiku/trunk/src/servers/app/DefaultDecorator.cpp
===================================================================
--- haiku/trunk/src/servers/app/DefaultDecorator.cpp    2009-10-28 17:39:02 UTC 
(rev 33813)
+++ haiku/trunk/src/servers/app/DefaultDecorator.cpp    2009-10-28 18:46:23 UTC 
(rev 33814)
@@ -32,14 +32,23 @@
 #include "ServerBitmap.h"
 
 
+// Toggle debug output
 //#define DEBUG_DECORATOR
+//#define DEBUG_STACK_AND_TILE
+
 #ifdef DEBUG_DECORATOR
 #      define STRACE(x) printf x
 #else
 #      define STRACE(x) ;
 #endif
 
+#ifdef DEBUG_STACK_AND_TILE
+#      define STRACE_SAT(x) debug_printf x
+#else
+#      define STRACE_SAT(x) ;
+#endif
 
+
 static inline uint8
 blend_color_value(uint8 a, uint8 b, float position)
 {
@@ -69,22 +78,35 @@
 {
        _UpdateFont(settings);
 
-       // common colors to both focus and non focus state
-       fFrameColors[0] = (rgb_color){ 152, 152, 152, 255 };
-       fFrameColors[1] = (rgb_color){ 240, 240, 240, 255 };
-       fFrameColors[4] = (rgb_color){ 152, 152, 152, 255 };
-       fFrameColors[5] = (rgb_color){ 108, 108, 108, 255 };
+       // all colors are state based
+       fNonHighlightFrameColors[0] = (rgb_color){ 152, 152, 152, 255 };
+       fNonHighlightFrameColors[1] = (rgb_color){ 240, 240, 240, 255 };
+       fNonHighlightFrameColors[2] = (rgb_color){ 152, 152, 152, 255 };
+       fNonHighlightFrameColors[3] = (rgb_color){ 108, 108, 108, 255 };
 
-       // state based colors
        fFocusFrameColors[0] = (rgb_color){ 224, 224, 224, 255 };
        fFocusFrameColors[1] = (rgb_color){ 208, 208, 208, 255 };
        fNonFocusFrameColors[0] = (rgb_color){ 232, 232, 232, 255 };
        fNonFocusFrameColors[1] = (rgb_color){ 216, 216, 216, 255 };
        fNonFocusFrameColors[1] = fNonFocusFrameColors[0];
 
+       fHighlightFrameColors[0] = (rgb_color){ 152, 0, 0, 255 };
+       fHighlightFrameColors[1] = (rgb_color){ 240, 0, 0, 255 };
+       fHighlightFrameColors[2] = (rgb_color){ 224, 0, 0, 255 };
+       fHighlightFrameColors[3] = (rgb_color){ 208, 0, 0, 255 };
+       fHighlightFrameColors[4] = (rgb_color){ 152, 0, 0, 255 };
+       fHighlightFrameColors[5] = (rgb_color){ 108, 0, 0, 255 };
+
+       // initial colors
+       fFrameColors[0] = fNonHighlightFrameColors[0];
+       fFrameColors[1] = fNonHighlightFrameColors[1];
+       fFrameColors[4] = fNonHighlightFrameColors[2];
+       fFrameColors[5] = fNonHighlightFrameColors[3];
+
        fFocusTabColor = settings.UIColor(B_WINDOW_TAB_COLOR);
        fFocusTextColor = settings.UIColor(B_WINDOW_TEXT_COLOR);
        fNonFocusTabColor = settings.UIColor(B_WINDOW_INACTIVE_TAB_COLOR);
+       fHighlightTabColor = (rgb_color){ 255, 0, 0, 255 };
        fNonFocusTextColor = settings.UIColor(B_WINDOW_INACTIVE_TEXT_COLOR);
 
        fCloseBitmaps[0] = fCloseBitmaps[1] = fCloseBitmaps[2] = 
fCloseBitmaps[3]
@@ -413,17 +435,190 @@
 bool
 DefaultDecorator::SetSettings(const BMessage& settings, BRegion* updateRegion)
 {
+       STRACE_SAT(("DefaultDecorator::SetSettings() on %s\n", 
fWindow->Title()));
+
        float tabLocation;
        if (settings.FindFloat("tab location", &tabLocation) == B_OK)
-               return SetTabLocation(tabLocation, updateRegion);
+               SetTabLocation(tabLocation, updateRegion);
 
-       return false;
+       int32 windowId = 0;
+       if (settings.FindInt32("window id", &windowId) != B_OK)
+               return false;
+       fWindow->SetWindowId(windowId);
+
+       STRACE_SAT(("\twindow id = %x\n", windowId));
+
+       // find id's of stacked windows and do the stacking
+       type_code typeFound;
+       int32 countFound;
+       settings.GetInfo("window id", &typeFound, &countFound);
+       settings.GetInfo("stacked windows", &typeFound, &countFound);
+
+       // if stacked window ids are found, then use them to stack this window
+       if (typeFound == B_INT32_TYPE && countFound > 0) {
+               Window* windowToStackUnder = NULL;
+
+               //This list contains all window id's that are supposed to be
+               //stacked with current window but aren't open
+               BList* persistentIdsToAdd = new BList();
+
+               for (int i = 0; i < countFound; i++) {
+                       int32 id;
+                       settings.FindInt32("stacked windows", i, &id);
+
+                       bool persist = true;
+
+                       // find a window (W) from the stack with an id from the 
list.
+                       // if it is not this window itself, then stack it with 
this window
+                       // UNLESS the W's stacking list doesn't contain this 
window,
+                       // which implies W's been unstacked while this window 
was hidden
+                       Window* window = fWindow->Desktop()->FindWindow(id);
+                       if (window && window != fWindow && 
window->StackedWindowIds()) {
+                               bool idExists = false;
+                               for (int j = 0; !idExists &&
+                                               j < 
window->StackedWindowIds()->CountItems(); j++) {
+                                       int32* stackedId =
+                                               
static_cast<int32*>(window->StackedWindowIds()->ItemAt(j));
+                                       idExists = windowId == *stackedId;
+                               }
+                               if (idExists) {
+                                       if (!windowToStackUnder) {
+                                               //note this will execute only 
once during loop
+                                               windowToStackUnder = window;
+                                       }
+                               }
+                               else {
+                                       persist = false;
+                               }
+                       }
+
+                       if (persist) {
+                               int32* idRef = 
static_cast<int32*>(malloc(sizeof(int32)));
+                               *idRef = id;
+                               persistentIdsToAdd->AddItem(idRef);
+                       }
+               }
+
+               if (windowToStackUnder) {
+                       fWindow->StackWindowBefore(windowToStackUnder);
+                       windowToStackUnder->StackAndTile();
+               }
+               else {
+                       fWindow->InitStackedWindowIds();
+               }
+
+               for (int i = 0; i < fWindow->StackedWindowIds()->CountItems(); 
i++) {
+                       int32* stackedId =
+                               
static_cast<int32*>(fWindow->StackedWindowIds()->ItemAt(i));
+                       STRACE_SAT(("\tstackedWindowIds[%d]=%x\n", i, 
*stackedId));
+               }
+
+               //Add the remaining window id's to the persistent stacking list
+               //These are the ones that belong to currently unopened windows
+               for (int i = 0; i < persistentIdsToAdd->CountItems(); i++) {
+                       int32* idRef =
+                               
static_cast<int32*>(persistentIdsToAdd->ItemAt(i));
+                       bool idExists = false;
+                       for (int j = 0; !idExists &&
+                                       j < 
fWindow->StackedWindowIds()->CountItems(); j++) {
+                               int32* stackedId =
+                                       
static_cast<int32*>(fWindow->StackedWindowIds()->ItemAt(j));
+                               idExists = *idRef == *stackedId;
+                       }
+                       if (!idExists) {
+                               STRACE_SAT(("\t** window %x isn't open - but 
stacked\n",
+                                               *idRef));
+                               fWindow->StackedWindowIds()->AddItem(idRef);
+                       }
+               }
+       }
+
+       _SnapWindowFromSettings("snap left2left", SNAP_LEFT, SNAP_LEFT,
+               &settings);
+       _SnapWindowFromSettings("snap left2right", SNAP_LEFT, SNAP_RIGHT,
+               &settings);
+       _SnapWindowFromSettings("snap right2left", SNAP_RIGHT, SNAP_LEFT,
+               &settings);
+       _SnapWindowFromSettings("snap right2right", SNAP_RIGHT, SNAP_RIGHT,
+               &settings);
+       _SnapWindowFromSettings("snap top2top", SNAP_TOP, SNAP_TOP, &settings);
+       _SnapWindowFromSettings("snap top2bottom", SNAP_TOP, SNAP_BOTTOM,
+               &settings);
+       _SnapWindowFromSettings("snap bottom2top", SNAP_BOTTOM, SNAP_TOP,
+               &settings);
+       _SnapWindowFromSettings("snap bottom2bottom", SNAP_BOTTOM, SNAP_BOTTOM,
+               &settings);
+
+       fWindow->StackAndTile();
+
+       STRACE_SAT(("Finished DefaultDecorator::SetSettings() on %s\n",
+               fWindow->Title()));
+       return true;
 }
 
 
+void
+DefaultDecorator::_SnapWindowFromSettings(const char* label,
+               SnapOrientation thisSnapOrientation,
+               SnapOrientation otherSnapOrientation,
+               const BMessage* settings)
+{
+       type_code typeFound;
+       int32 countFound;
+       settings->GetInfo(label, &typeFound, &countFound);
+       if (typeFound == B_INT32_TYPE && countFound > 0) {
+               for (int i = 0; i < countFound; i++) {
+                       int32 id;
+                       settings->FindInt32(label, i, &id);
+
+                       Window* window = fWindow->Desktop()->FindWindow(id);
+                       if (window == fWindow) {
+                               continue;
+                       }
+
+                       char* debug_suffix = "... NOT!";
+
+                       if (window) {
+                               //There can be cases where the other window to 
which this
+                               //window's snapped doesn't contain a reference 
to this window
+                               //in its snapping list. This would happen when 
the other window
+                               //was de-snapped while this window was hidden. 
So only add the
+                               //other window to this window's snapping list 
when such is not
+                               //the case.
+                               BList* otherList = 
window->GetSnappingList(otherSnapOrientation,
+                                               thisSnapOrientation, false);
+                               if (!otherList) {
+                                       debug_suffix = "\n";
+                                       continue;
+                               }
+                               for (int i = 0; i < otherList->CountItems(); 
i++) {
+                                       int32* snappedId = 
static_cast<int32*>(otherList->ItemAt(i));
+                                       if (*snappedId == fWindow->WindowId()) {
+                                               fWindow->SnapToWindow(window, 
thisSnapOrientation,
+                                                               
otherSnapOrientation);
+                                               debug_suffix = "";
+                                               break;
+                                       }
+                               }
+                       }
+                       else { //window isn't open - still retain snap id
+                               fWindow->AddToSnappingList(id, 
thisSnapOrientation,
+                                       otherSnapOrientation);
+                               debug_suffix = "... ?";
+                       }
+
+                       STRACE_SAT(("\t%s[%d]=%x", label, i, id));
+                       STRACE_SAT(("%s\n", debug_suffix));
+               }
+       }
+}
+
+
 bool
 DefaultDecorator::GetSettings(BMessage* settings) const
 {
+       STRACE_SAT(("DefaultDecorator::GetSettings() on %s\n", 
fWindow->Title()));
+
        if (!fTabRect.IsValid())
                return false;
 
@@ -433,13 +628,67 @@
        if (settings->AddFloat("border width", fBorderWidth) != B_OK)
                return false;
 
-       return settings->AddFloat("tab location", (float)fTabOffset) == B_OK;
+       if (settings->AddFloat("tab location", (float)fTabOffset) != B_OK)
+               return false;
+
+       if (settings->AddInt32("window id", fWindow->WindowId()) != B_OK)
+               return false;
+
+       // store id's of stacked windows
+       if (!_StoreIntsInSettings("stacked windows", 
fWindow->StackedWindowIds(),
+                       settings))
+               return false;
+
+       // store id's of snapped windows
+       if (!_StoreIntsInSettings("snap left2left",
+                       fWindow->Left2LeftSnappingWindowIds(), settings))
+               return false;
+       if (!_StoreIntsInSettings("snap left2right",
+                       fWindow->Left2RightSnappingWindowIds(), settings))
+               return false;
+       if (!_StoreIntsInSettings("snap right2right",
+                       fWindow->Right2RightSnappingWindowIds(), settings))
+               return false;
+       if (!_StoreIntsInSettings("snap right2left",
+                       fWindow->Right2LeftSnappingWindowIds(), settings))
+               return false;
+       if (!_StoreIntsInSettings("snap top2top",
+                       fWindow->Top2TopSnappingWindowIds(), settings))
+               return false;
+       if (!_StoreIntsInSettings("snap top2bottom",
+                       fWindow->Top2BottomSnappingWindowIds(), settings))
+               return false;
+       if (!_StoreIntsInSettings("snap bottom2top",
+                       fWindow->Bottom2TopSnappingWindowIds(), settings))
+               return false;
+       if (!_StoreIntsInSettings("snap bottom2bottom",
+                       fWindow->Bottom2BottomSnappingWindowIds(), settings))
+               return false;
+
+       STRACE_SAT(("Finished DefaultDecorator::GetSettings() on %s\n",
+               fWindow->Title()));
+       return true;
 }
 
 
+bool
+DefaultDecorator::_StoreIntsInSettings(const char* label,
+       BList* ids, BMessage* settings) const
+{
+       if (ids) {
+               for (int i = 0; i < ids->CountItems(); i++) {
+                       int32* id = static_cast<int32*>(ids->ItemAt(i));
+                       if (settings->AddInt32(label, *id) != B_OK)
+                               return false;
+                       STRACE_SAT(("\t%s[%d]=%x\n", label, i, *id));
+               }
+       }
+       return true;
+}
+
+
 // #pragma mark -
 
-
 void
 DefaultDecorator::Draw(BRect update)
 {
@@ -1372,3 +1621,51 @@
        sBitmapList = entry;
        return bitmap;
 }
+
+
+void
+DefaultDecorator::HighlightTab(bool active, BRegion* dirty)
+{
+       if (active)
+               fTabColor = fHighlightTabColor;
+       else if (IsFocus())
+               fTabColor = fFocusTabColor;
+       else
+               fTabColor = fNonFocusTabColor;
+       dirty->Include(fTabRect);
+       fTabHighlighted = active;
+}
+
+
+void
+DefaultDecorator::HighlightBorders(bool active, BRegion* dirty)
+{
+       if (active) {
+               fFrameColors[0] = fHighlightFrameColors[0];
+               fFrameColors[1] = fHighlightFrameColors[1];
+               fFrameColors[2] = fHighlightFrameColors[2];
+               fFrameColors[3] = fHighlightFrameColors[3];
+               fFrameColors[4] = fHighlightFrameColors[4];
+               fFrameColors[5] = fHighlightFrameColors[5];
+       } else if (IsFocus()) {
+               fFrameColors[0] = fNonHighlightFrameColors[0];
+               fFrameColors[1] = fNonHighlightFrameColors[1];
+               fFrameColors[2] = fFocusFrameColors[0];
+               fFrameColors[3] = fFocusFrameColors[1];
+               fFrameColors[4] = fNonHighlightFrameColors[2];
+               fFrameColors[5] = fNonHighlightFrameColors[3];
+       } else {
+               fFrameColors[0] = fNonHighlightFrameColors[0];
+               fFrameColors[1] = fNonHighlightFrameColors[1];
+               fFrameColors[2] = fNonFocusFrameColors[0];
+               fFrameColors[3] = fNonFocusFrameColors[1];
+               fFrameColors[4] = fNonHighlightFrameColors[2];
+               fFrameColors[5] = fNonHighlightFrameColors[3];
+       }
+       dirty->Include(fLeftBorder);
+       dirty->Include(fRightBorder);
+       dirty->Include(fTopBorder);
+       dirty->Include(fBottomBorder);
+       dirty->Include(fResizeRect);
+       fBordersHighlighted = active;
+}

Modified: haiku/trunk/src/servers/app/DefaultDecorator.h
===================================================================
--- haiku/trunk/src/servers/app/DefaultDecorator.h      2009-10-28 17:39:02 UTC 
(rev 33813)
+++ haiku/trunk/src/servers/app/DefaultDecorator.h      2009-10-28 18:46:23 UTC 
(rev 33814)
@@ -10,11 +10,10 @@
 #define DEFAULT_DECORATOR_H
 
 
+#include "Decorator.h"
+#include "Desktop.h"
 #include <Region.h>
 
-#include "Decorator.h"
-
-
 class Desktop;
 class ServerBitmap;
 
@@ -58,6 +57,9 @@
        virtual click_type                      Clicked(BPoint pt, int32 
buttons,
                                                                        int32 
modifiers);
 
+       virtual void                            HighlightTab(bool active, 
BRegion* dirty);
+       virtual void                            HighlightBorders(bool active, 
BRegion* dirty);
+
 protected:
        virtual void                            _DoLayout();
 
@@ -92,6 +94,7 @@
                        rgb_color                       fTabColor;
                        rgb_color                       fFocusTabColor;
                        rgb_color                       fNonFocusTabColor;
+                       rgb_color                       fHighlightTabColor;
                        rgb_color                       fTextColor;
                        rgb_color                       fFocusTextColor;
                        rgb_color                       fNonFocusTextColor;
@@ -103,6 +106,8 @@
                        rgb_color                       fFrameColors[6];
                        rgb_color                       fFocusFrameColors[2];
                        rgb_color                       fNonFocusFrameColors[2];
+                       rgb_color                       
fNonHighlightFrameColors[4];
+                       rgb_color                       
fHighlightFrameColors[6];
 
                        bool                            fButtonFocus;
                        ServerBitmap*           fCloseBitmaps[4];
@@ -128,6 +133,14 @@
 
                        bigtime_t                       fLastClicked;
                        bool                            fWasDoubleClick;
+
+                       //Stack & Tile specific private methods
+                       bool                            
_StoreIntsInSettings(const char* label,
+                                                                       BList* 
ids, BMessage* settings) const;
+                       void                            
_SnapWindowFromSettings(const char* label,
+                                                                       
SnapOrientation thisSnapOrientation,
+                                                                       
SnapOrientation otherSnapOrientation,
+                                                                       const 
BMessage* settings);
 };
 
 #endif // DEFAULT_DECORATOR_H

Modified: haiku/trunk/src/servers/app/Desktop.cpp
===================================================================
--- haiku/trunk/src/servers/app/Desktop.cpp     2009-10-28 17:39:02 UTC (rev 
33813)
+++ haiku/trunk/src/servers/app/Desktop.cpp     2009-10-28 18:46:23 UTC (rev 
33814)
@@ -50,6 +50,22 @@
 #include "Workspace.h"
 #include "WorkspacesView.h"
 
+#include <ViewPrivate.h>
+#include <WindowInfo.h>
+#include <ServerProtocol.h>
+
+#include <Debug.h>
+#include <DirectWindow.h>
+#include <Entry.h>
+#include <Message.h>
+#include <MessageFilter.h>
+#include <Region.h>
+#include <Roster.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+
 #if TEST_MODE
 #      include "EventStream.h"
 #endif
@@ -186,6 +202,30 @@
                        fDesktop->SetWorkspaceAsync(-1);
                        return B_SKIP_MESSAGE;
                }
+
+               // switch between stacked windows
+               if (modifiers & B_OPTION_KEY) {
+                       BList* stackedWindows = 
fDesktop->FocusWindow()->StackedWindows();
+                       if (key == 0x61 && stackedWindows) {
+                               int32 oldIndex =
+                                       
stackedWindows->IndexOf(fDesktop->FocusWindow());
+                               int32 newIndex =
+                                       (oldIndex - 1 >= 0)?
+                                       oldIndex - 1 : 
stackedWindows->CountItems() - 1;
+                               fDesktop->ActivateWindow(
+                                       
static_cast<Window*>(stackedWindows->ItemAt(newIndex)));
+                               return B_SKIP_MESSAGE;
+                       } else if (key == 0x63 && stackedWindows) {
+                               int32 oldIndex =
+                                       
stackedWindows->IndexOf(fDesktop->FocusWindow());
+                               int32 newIndex =
+                                       (oldIndex + 1 < 
stackedWindows->CountItems())?
+                                       oldIndex + 1 : 0;
+                               fDesktop->ActivateWindow(
+                                       
static_cast<Window*>(stackedWindows->ItemAt(newIndex)));
+                               return B_SKIP_MESSAGE;
+                       }
+               }
        }
 
        if (message->what == B_KEY_DOWN
@@ -194,6 +234,15 @@
                || message->what == B_INPUT_METHOD_EVENT)
                _UpdateFocus(key, modifiers, _target);
 
+       // switch to and from stacking and snapping mode
+       if (message->what == B_MODIFIERS_CHANGED
+               && message->FindInt32("modifiers", &modifiers) == B_OK) {
+               // disable highlights if the stacking and snapping mode was 
just left
+               if (fDesktop->fIsStackingAndSnapping && !(modifiers & 
B_OPTION_KEY))
+                       fDesktop->FinishStackingAndSnapping();
+               fDesktop->fIsStackingAndSnapping = modifiers & B_OPTION_KEY;
+       }
+
        return B_DISPATCH_MESSAGE;
 }
 
@@ -305,6 +354,9 @@
        :
        MessageLooper("desktop"),
 
+       fIsStackingAndSnapping(false),
+       fStackAndTileSpec(new LinearSpec()),
+
        fUserID(userID),
        fTargetScreen(strdup(targetScreen)),
        fSettings(NULL),
@@ -348,6 +400,7 @@
 
 Desktop::~Desktop()
 {
+       delete fStackAndTileSpec;
        delete fSettings;
 
        delete_area(fSharedReadOnlyArea);
@@ -937,7 +990,7 @@
                ShowWindow(window);
        }
 
-       if (window == FrontWindow()) {
+       if (window == FrontWindow() && !window->ForceActivate()) {
                // see if there is a normal B_AVOID_FRONT window still in front 
of us
                Window* avoidsFront = window->NextWindow(fCurrentWorkspace);
                while (avoidsFront && avoidsFront->IsNormal()
@@ -961,6 +1014,55 @@
 
        Window* frontmost = window->Frontmost();
 
+       BList* stackedAndTiledWindows = new BList();
+
+       //Prepare to move tiled windows to the front as well
+       _AddWindowsByIdsToList(window->Left2LeftSnappingWindowIds(),
+               stackedAndTiledWindows);
+       _AddWindowsByIdsToList(window->Left2RightSnappingWindowIds(),
+               stackedAndTiledWindows);
+       _AddWindowsByIdsToList(window->Right2RightSnappingWindowIds(),
+               stackedAndTiledWindows);
+       _AddWindowsByIdsToList(window->Right2LeftSnappingWindowIds(),
+               stackedAndTiledWindows);
+       _AddWindowsByIdsToList(window->Top2TopSnappingWindowIds(),
+               stackedAndTiledWindows);
+       _AddWindowsByIdsToList(window->Top2BottomSnappingWindowIds(),
+               stackedAndTiledWindows);
+       _AddWindowsByIdsToList(window->Bottom2TopSnappingWindowIds(),
+               stackedAndTiledWindows);
+       _AddWindowsByIdsToList(window->Bottom2BottomSnappingWindowIds(),
+               stackedAndTiledWindows);
+
+       bool forceDirty = false;
+
+       //And then prepare to move stacked windows to the front
+       BList* stackedWindows = window->StackedWindows();
+       if (stackedWindows) {
+               for (int i = 0; i < stackedWindows->CountItems(); i++) {
+                       Window* stackedWindow =
+                               static_cast<Window*>(stackedWindows->ItemAt(i));
+                       if (stackedWindow != window
+                               && 
!stackedAndTiledWindows->HasItem(stackedWindow)) {
+                               stackedAndTiledWindows->AddItem(stackedWindow);
+
+                               //Basically if there are any stacked windows 
associated with
+                               //this window, then designate this window as 
"dirty" so it is
+                               //forced to repaint
+                               forceDirty = true;
+                       }
+               }
+       }
+
+       //Do the actual moving here
+       for (int i = 0; i < stackedAndTiledWindows->CountItems(); i ++) {
+               Window* win = 
static_cast<Window*>(stackedAndTiledWindows->ItemAt(i));
+               _CurrentWindows().RemoveWindow(win);
+               windows.AddWindow(win);
+       }
+
+       delete stackedAndTiledWindows;
+
        _CurrentWindows().RemoveWindow(window);
        windows.AddWindow(window);
 
@@ -984,13 +1086,29 @@
                }
        }
 
-       _BringWindowsToFront(windows, kWorkingList, true);
+       _BringWindowsToFront(windows, kWorkingList, !forceDirty);
 
        if ((window->Flags() & B_AVOID_FOCUS) == 0)
                SetFocusWindow(window);
 }
 
 
+bool
+Desktop::_AddWindowsByIdsToList(BList* windowIdsToAdd, BList* windows)
+{
+       if (!windowIdsToAdd || !windows)
+               return false;
+       bool added = false;
+       for (int i = 0; i < windowIdsToAdd->CountItems(); i++) {
+               int32* id = static_cast<int32*>(windowIdsToAdd->ItemAt(i));
+               Window* windowToAdd = FindWindow(*id);
+               if (windowToAdd && !windows->HasItem(windowToAdd))
+                       windows->AddItem(windowToAdd);
+       }
+       return added;
+}
+
+
 void
 Desktop::SendWindowBehind(Window* window, Window* behindOf)
 {
@@ -3257,3 +3375,69 @@
        if (previousColor != fWorkspaces[fCurrentWorkspace].Color())
                RedrawBackground();
 }
+
+
+WindowList&
+Desktop::GetWindows()
+{
+       return _CurrentWindows();
+}
+
+
+bool
+Desktop::HighlightTab(Window* window, bool active)
+{
+       AutoWriteLocker _(fWindowLock);
+
+       if (window->IsTabHighlighted() == active)
+               return false;
+
+       BRegion dirty;
+       bool changed = window->HighlightTab(active, dirty);
+       if (changed)
+               _RebuildAndRedrawAfterWindowChange(window, dirty);
+
+       return changed;
+}
+
+
+bool
+Desktop::HighlightBorders(Window* window, bool active)
+{
+       AutoWriteLocker _(fWindowLock);
+
+       if (window->IsBordersHighlighted() == active)
+               return false;
+
+       BRegion dirty;
+       bool changed = window->HighlightBorders(active, dirty);
+       if (changed)
+               _RebuildAndRedrawAfterWindowChange(window, dirty);
+
+       return changed;
+}
+
+
+void
+Desktop::FinishStackingAndSnapping()
+{
+       for (Window* window = _CurrentWindows().LastWindow(); window != NULL;
+               window = window->PreviousWindow(fCurrentWorkspace)) {
+               HighlightTab(window, false);
+               HighlightBorders(window, false);
+               window->FinishStackingAndSnapping();
+       }
+       fIsStackingAndSnapping = false;
+}
+
+
+Window*
+Desktop::FindWindow(int32 windowId)
+{
+       for (Window* window = _CurrentWindows().LastWindow(); window != NULL;
+               window = window->PreviousWindow(fCurrentWorkspace)) {
+               if (window->WindowId() == windowId)
+                       return window;
+       }
+       return NULL;
+}
\ No newline at end of file

Modified: haiku/trunk/src/servers/app/Desktop.h
===================================================================
--- haiku/trunk/src/servers/app/Desktop.h       2009-10-28 17:39:02 UTC (rev 
33813)
+++ haiku/trunk/src/servers/app/Desktop.h       2009-10-28 18:46:23 UTC (rev 
33814)
@@ -34,6 +34,7 @@
 #include <Region.h>
 #include <Window.h>
 
+#include "LinearSpec.h"
 
 #define USE_MULTI_LOCKER 1
 
@@ -241,6 +242,15 @@
                        void                            WriteWindowOrder(int32 
workspace,
                                                                        
BPrivate::LinkSender& sender);
 
+                       WindowList&                             GetWindows();
+                       bool                                    
HighlightTab(Window* window, bool active);
+                       bool                                    
HighlightBorders(Window* window, bool active);
+                       void                                    
FinishStackingAndSnapping();
+                       Window*                                 
FindWindow(int32 windowId);
+
+                       bool                                    
fIsStackingAndSnapping;
+                       LinearSpec*                             
fStackAndTileSpec;
+
 private:
                        void                            _LaunchInputServer();
                        void                            _GetLooperName(char* 
name, size_t size);
@@ -294,6 +304,9 @@
                        void                            
_SetCurrentWorkspaceConfiguration();
                        void                            _SetWorkspace(int32 
index);
 
+                       bool                            
_AddWindowsByIdsToList(BList* windowIdsToAdd,
+                                                                       BList* 
windows);
+
 private:
        friend class DesktopSettings;
        friend class LockedDesktopSettings;

Modified: haiku/trunk/src/servers/app/Jamfile
===================================================================
--- haiku/trunk/src/servers/app/Jamfile 2009-10-28 17:39:02 UTC (rev 33813)
+++ haiku/trunk/src/servers/app/Jamfile 2009-10-28 18:46:23 UTC (rev 33814)
@@ -1,6 +1,6 @@
 SubDir HAIKU_TOP src servers app ;
 
-UseLibraryHeaders agg ;
+UseLibraryHeaders agg lp_solve linprog ;
 UsePrivateHeaders app graphics input interface kernel shared storage ;
 
 UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing ] ;
@@ -66,6 +66,7 @@
        libtranslation.so libbe.so libbnetapi.so
        libasdrawing.a libasremote.a libpainter.a libagg.a libfreetype.so
        libtextencoding.so libshared.a $(TARGET_LIBSTDC++)
+       liblpsolve55.so liblinprog.so
 
        : app_server.rdef
 ;

Modified: haiku/trunk/src/servers/app/ServerWindow.cpp
===================================================================
--- haiku/trunk/src/servers/app/ServerWindow.cpp        2009-10-28 17:39:02 UTC 
(rev 33813)
+++ haiku/trunk/src/servers/app/ServerWindow.cpp        2009-10-28 18:46:23 UTC 
(rev 33814)
@@ -895,6 +895,9 @@
                                fDesktop->ResizeWindowBy(fWindow,
                                        xResizeTo - fWindow->Frame().Width(),
                                        yResizeTo - fWindow->Frame().Height());
+                               //Re-apply stack & tile constraints so that any 
other windows
+                               //that are stacked/snapped against this window 
can be re-adjusted
+                               fWindow->StackAndTile();
                                fLink.StartMessage(B_OK);
 //                     }
                        fLink.Flush();
@@ -919,6 +922,9 @@
                        } else {
                                fDesktop->MoveWindowBy(fWindow, xMoveTo - 
fWindow->Frame().left,
                                        yMoveTo - fWindow->Frame().top);
+                               //Re-apply stack & tile constraints so that any 
other windows
+                               //that are stacked/snapped against this window 
can be re-adjusted
+                               fWindow->StackAndTile();
                                fLink.StartMessage(B_OK);
                        }
                        fLink.Flush();

Modified: haiku/trunk/src/servers/app/Window.cpp
===================================================================
--- haiku/trunk/src/servers/app/Window.cpp      2009-10-28 17:39:02 UTC (rev 
33813)
+++ haiku/trunk/src/servers/app/Window.cpp      2009-10-28 18:46:23 UTC (rev 
33814)
@@ -40,6 +40,7 @@
 // Toggle debug output
 //#define DEBUG_WINDOW
 //#define DEBUG_WINDOW_CLICK
+//#define DEBUG_STACK_AND_TILE
 
 #ifdef DEBUG_WINDOW
 #      define STRACE(x) printf x
@@ -53,6 +54,12 @@
 #      define STRACE_CLICK(x) ;
 #endif
 
+#ifdef DEBUG_STACK_AND_TILE
+#      define STRACE_SAT(x) debug_printf x
+#else
+#      define STRACE_SAT(x) ;
+#endif
+
 // IMPORTANT: nested LockSingleWindow()s are not supported (by MultiLocker)
 
 using std::nothrow;
@@ -136,7 +143,43 @@
        fMinHeight(1),
        fMaxHeight(32768),
 
-       fWorkspacesViewCount(0)
+       fWorkspacesViewCount(0),
+
+       fLeftVar(NULL),
+       fTopVar(NULL),
+       fRightVar(NULL),
+       fBottomVar(NULL),
+       fLeftConstraint(NULL),
+       fTopConstraint(NULL),
+       fMinWidthConstraint(NULL),
+       fMinHeightConstraint(NULL),
+       fWidthConstraint(NULL),
+       fHeightConstraint(NULL),
+
+       fLeftAdjacentWindows(NULL),
+       fTopAdjacentWindows(NULL),
+       fRightAdjacentWindows(NULL),
+       fBottomAdjacentWindows(NULL),
+       fSnappingConstraints(NULL),
+
+       fLeft2LeftSnappingWindowIds(NULL),
+       fLeft2RightSnappingWindowIds(NULL),
+       fRight2RightSnappingWindowIds(NULL),
+       fRight2LeftSnappingWindowIds(NULL),
+       fTop2TopSnappingWindowIds(NULL),
+       fTop2BottomSnappingWindowIds(NULL),
+       fBottom2BottomSnappingWindowIds(NULL),
+       fBottom2TopSnappingWindowIds(NULL),
+
+       fWindowUnder(NULL),
+       fStackedWindows(NULL),
+       fPrevStackedWindows(NULL),
+       fLeftStackingConstraint(NULL),
+       fTopStackingConstraint(NULL),
+       fRightStackingConstraint(NULL),
+       fBottomStackingConstraint(NULL),
+       fId(0),
+       fStackedWindowIds(NULL)
 {
        // make sure our arguments are valid
        if (!IsValidLook(fLook))
@@ -182,6 +225,34 @@
 
 Window::~Window()
 {
+       // if the window still has stackedWindowIds but is not stacked anymore,
+       // clean up the stackedWindowIds (they are not used by other windows
+       // anymore)
+       if (fStackedWindowIds
+               && (!fStackedWindows  || fStackedWindows->CountItems()==1)) {
+               for (int i = 0; i < fStackedWindowIds->CountItems(); i++) {
+                       int32* id = 
static_cast<int32*>(fStackedWindowIds->ItemAt(i));
+                       free(id);
+               }
+               delete fStackedWindowIds;
+               fStackedWindowIds = NULL;
+       }
+
+       // clean up the entries in the snapping lists for each combo of
+       // snapping orientations
+       _FreeUpSnappingList(SNAP_LEFT, SNAP_LEFT, false);
+       _FreeUpSnappingList(SNAP_LEFT, SNAP_RIGHT, false);
+       _FreeUpSnappingList(SNAP_RIGHT, SNAP_LEFT, false);
+       _FreeUpSnappingList(SNAP_RIGHT, SNAP_RIGHT, false);
+       _FreeUpSnappingList(SNAP_TOP, SNAP_TOP, false);
+       _FreeUpSnappingList(SNAP_TOP, SNAP_BOTTOM, false);
+       _FreeUpSnappingList(SNAP_BOTTOM, SNAP_TOP, false);
+       _FreeUpSnappingList(SNAP_BOTTOM, SNAP_BOTTOM, false);
+
+       // clean up all other stacking and snapping
+       _RemoveStackingAndSnapping();
+       FinishStackingAndSnapping();
+
        if (fTopView) {
                fTopView->DetachedFromWindow();
                delete fTopView;
@@ -749,6 +820,7 @@
        }
 }
 
+

[... truncated: 1955 lines follow ...]

Other related posts: