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 ...]