Applied Stack & Tile patch by Hong Yul Yang, formely by Christof Lutteroth.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33814 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Philippe Houdoin
2009-10-28 18:46:23 +00:00
parent 4b0f176d9c
commit ef831a1dc3
11 changed files with 2486 additions and 20 deletions
+23
View File
@@ -44,6 +44,10 @@ Decorator::Decorator(DesktopSettings& settings, BRect rect, window_look look,
fFrame(rect),
fResizeRect(),
fBorderRect(),
fTabHighlighted(false),
fBordersHighlighted(false),
fWindow(NULL),
fClosePressed(false),
fZoomPressed(false),
@@ -580,3 +584,22 @@ void
Decorator::_SetFocus()
{
}
void
Decorator::HighlightTab(bool active, BRegion* dirty)
{
}
void
Decorator::HighlightBorders(bool active, BRegion* dirty)
{
}
void
Decorator::SetWindow(Window* window)
{
fWindow = window;
}
+18
View File
@@ -21,6 +21,7 @@ class DesktopSettings;
class DrawingEngine;
class ServerFont;
class BRegion;
class Window;
enum click_type {
@@ -44,6 +45,8 @@ enum click_type {
CLICK_RESIZE_RB
};
#include "Window.h"
class Decorator {
public:
Decorator(DesktopSettings& settings, BRect rect,
@@ -68,6 +71,14 @@ public:
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 @@ public:
rgb_color UIColor(color_which which);
void SetWindow(Window* window);
protected:
int32 _TitleWidth() const
{ return fTitle.CountChars(); }
@@ -151,6 +164,11 @@ protected:
BRect fResizeRect;
BRect fBorderRect;
bool fTabHighlighted;
bool fBordersHighlighted;
Window* fWindow;
private:
bool fClosePressed : 1;
bool fZoomPressed : 1;
+307 -10
View File
@@ -32,13 +32,22 @@
#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 @@ DefaultDecorator::DefaultDecorator(DesktopSettings& settings, BRect rect,
{
_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 @@ DefaultDecorator::SetTabLocation(float location, BRegion* updateRegion)
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 @@ DefaultDecorator::GetSettings(BMessage* settings) const
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 @@ DefaultDecorator::_GetBitmapForButton(int32 item, bool down, bool focus,
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;
}
+16 -3
View File
@@ -10,10 +10,9 @@
#define DEFAULT_DECORATOR_H
#include <Region.h>
#include "Decorator.h"
#include "Desktop.h"
#include <Region.h>
class Desktop;
class ServerBitmap;
@@ -58,6 +57,9 @@ public:
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 @@ private:
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 @@ private:
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 @@ private:
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
+186 -2
View File
@@ -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 @@ KeyboardFilter::Filter(BMessage* message, EventTarget** _target,
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 @@ KeyboardFilter::Filter(BMessage* message, EventTarget** _target,
|| 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 @@ Desktop::Desktop(uid_t userID, const char* targetScreen)
:
MessageLooper("desktop"),
fIsStackingAndSnapping(false),
fStackAndTileSpec(new LinearSpec()),
fUserID(userID),
fTargetScreen(strdup(targetScreen)),
fSettings(NULL),
@@ -348,6 +400,7 @@ Desktop::Desktop(uid_t userID, const char* targetScreen)
Desktop::~Desktop()
{
delete fStackAndTileSpec;
delete fSettings;
delete_area(fSharedReadOnlyArea);
@@ -937,7 +990,7 @@ Desktop::ActivateWindow(Window* window)
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 @@ Desktop::ActivateWindow(Window* window)
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 @@ Desktop::ActivateWindow(Window* window)
}
}
_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 @@ Desktop::_SetWorkspace(int32 index)
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;
}
+13
View File
@@ -34,6 +34,7 @@
#include <Region.h>
#include <Window.h>
#include "LinearSpec.h"
#define USE_MULTI_LOCKER 1
@@ -241,6 +242,15 @@ public:
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 @@ private:
void _SetCurrentWorkspaceConfiguration();
void _SetWorkspace(int32 index);
bool _AddWindowsByIdsToList(BList* windowIdsToAdd,
BList* windows);
private:
friend class DesktopSettings;
friend class LockedDesktopSettings;
+2 -1
View File
@@ -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 @@ Server app_server :
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
;
+6
View File
@@ -895,6 +895,9 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
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 @@ ServerWindow::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
} 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();
File diff suppressed because it is too large Load Diff
+131
View File
@@ -23,6 +23,8 @@
#include <Region.h>
#include <String.h>
#include "LinearSpec.h"
namespace BPrivate {
class PortLink;
};
@@ -43,6 +45,10 @@ enum {
UPDATE_EXPOSE = 0x02,
};
// Used for Stack & Tile
enum SnapOrientation {
SNAP_LEFT, SNAP_RIGHT, SNAP_TOP, SNAP_BOTTOM
};
class Window {
public:
@@ -244,6 +250,59 @@ public:
static uint32 ValidWindowFlags();
static uint32 ValidWindowFlags(window_feel feel);
bool HighlightTab(bool active, BRegion& dirty);
bool HighlightBorders(bool active, BRegion& dirty);
bool IsTabHighlighted();
bool IsBordersHighlighted();
void StackAndTile();
void StackWindowBefore(Window* window);
void FinishStackingAndSnapping();
BList* StackedWindows() const
{ return fStackedWindows; }
int32 WindowId();
void SetWindowId(int32 windowId);
BList* StackedWindowIds() const
{ return fStackedWindowIds; }
void InitStackedWindowIds();
Constraint* SnapToWindow(Window* otherWindow,
SnapOrientation thisSnap,
SnapOrientation otherSnap);
void AddToSnappingList(int32 windowId,
SnapOrientation thisSnapOrientation,
SnapOrientation otherSnapOrientation);
void AddToSnappingList(Window* window,
SnapOrientation thisSnapOrientation,
SnapOrientation otherSnapOrientation);
void RemoveFromSnappingList(int32 windowId,
SnapOrientation thisSnapOrientation,
SnapOrientation otherSnapOrientation);
BList* GetSnappingList(
SnapOrientation thisSnapOrientation,
SnapOrientation otherSnapOrientation,
bool createIfNull);
BList* Left2LeftSnappingWindowIds() const
{ return fLeft2LeftSnappingWindowIds; }
BList* Left2RightSnappingWindowIds() const
{ return fLeft2RightSnappingWindowIds; }
BList* Right2RightSnappingWindowIds() const
{ return fRight2RightSnappingWindowIds; }
BList* Right2LeftSnappingWindowIds() const
{ return fRight2LeftSnappingWindowIds; }
BList* Top2TopSnappingWindowIds() const
{ return fTop2TopSnappingWindowIds; }
BList* Top2BottomSnappingWindowIds() const
{ return fTop2BottomSnappingWindowIds; }
BList* Bottom2BottomSnappingWindowIds() const
{ return fBottom2BottomSnappingWindowIds; }
BList* Bottom2TopSnappingWindowIds() const
{ return fBottom2TopSnappingWindowIds; }
bool ForceActivate() { return fForceActivate; }
protected:
void _ShiftPartOfRegion(BRegion* region,
BRegion* regionToShift, int32 xOffset,
@@ -393,6 +452,78 @@ protected:
int32 fMaxHeight;
int32 fWorkspacesViewCount;
// Stack & Tile specific members
void _InitStackingAndSnapping();
void _RemoveStackingAndSnapping();
void _CheckIfReadyToStack();
void _StackWindow();
void _ArrangeStackedWindowTabs();
void _CheckIfReadyToSnap();
void _SnapWindow();
BRect _BoundingRectAndWindows(BList* windows,
Window** leftmostWindow,
Window** topmostWindow,
Window** rightmostWindow,
Window** bottommostWindow);
void _BoundWindowByWorkspace();
void _UnboundWindowByWorkspace();
void _RemoveStackingPersistently();
void _RemoveSnappingPersistently();
void _FreeUpSnappingList(SnapOrientation thisSnap,
SnapOrientation otherSnap,
bool deleteFromOtherWindowsList);
BList** _GetSnappingListRef(
SnapOrientation thisSnapOrientation,
SnapOrientation otherSnapOrientation,
bool createIfNull);
void _EnsureWindowWithinScreenBounds(Window* window, Window* detached);
Variable* fLeftVar;
Variable* fTopVar;
Variable* fRightVar;
Variable* fBottomVar;
Constraint* fLeftConstraint;
Constraint* fTopConstraint;
Constraint* fMinWidthConstraint;
Constraint* fMinHeightConstraint;
Constraint* fWidthConstraint;
Constraint* fHeightConstraint;
BList* fLeftAdjacentWindows;
BList* fTopAdjacentWindows;
BList* fRightAdjacentWindows;
BList* fBottomAdjacentWindows;
BList* fSnappingConstraints;
BList* fLeft2LeftSnappingWindowIds;
BList* fLeft2RightSnappingWindowIds;
BList* fRight2RightSnappingWindowIds;
BList* fRight2LeftSnappingWindowIds;
BList* fTop2TopSnappingWindowIds;
BList* fTop2BottomSnappingWindowIds;
BList* fBottom2BottomSnappingWindowIds;
BList* fBottom2TopSnappingWindowIds;
//True means activate this window even if it's already at the front
bool fForceActivate;
Window* fWindowUnder;
BList* fStackedWindows;
BList* fPrevStackedWindows;
Constraint* fLeftStackingConstraint;
Constraint* fTopStackingConstraint;
Constraint* fRightStackingConstraint;
Constraint* fBottomStackingConstraint;
int32 fId;
BList* fStackedWindowIds;
};
#endif // WINDOW_H
+4
View File
@@ -568,6 +568,10 @@ WorkspacesView::MouseMoved(BMessage* message, BPoint where)
if (fHasMoved) {
Window()->Desktop()->MoveWindowBy(fSelectedWindow, left - leftTop.x,
top - leftTop.y, fSelectedWorkspace);
//TODO Re-apply stack & tile constraints so that any other windows
//that are stacked/snapped against this window can be re-adjusted.
//Must smartly call stack and tile after workspace shifting has
//finalised. How?
}
}