Tried to separate active WinBorder from front, but failed - it's now always

the focus border, and therefore, I probably broke floating windows (but that's
not that important right now).
Workspace::HideWinBorder() now sets focus to the next WinBorder, not always
the top one.
Workspace::MoveToFront() no longer changes focus, no longer calls ShowWinBorder()
when the window doesn't have to be moved (ie. for the desktop window).
Added Workspace::SetFocus() to change the focus explicetly.
Some other cleanup. This is an ugly patch, but refactoring/rewriting is coming
soon.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13509 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2005-07-06 20:19:22 +00:00
parent 9c910f9e80
commit 189ba7a9dc
4 changed files with 405 additions and 457 deletions
+54 -74
View File
@@ -290,7 +290,6 @@ RootLayer::WorkingThread(void *data)
}
case AS_ROOTLAYER_DO_INVALIDATE:
{
//printf("Adi: new message\n");
BRegion invalidRegion;
Layer *layer = NULL;
messageQueue.Read<Layer*>(&layer);
@@ -577,7 +576,9 @@ void RootLayer::AddWinBorder(WinBorder* winBorder)
winBorder->fParent = this;
}
void RootLayer::RemoveWinBorder(WinBorder* winBorder)
void
RootLayer::RemoveWinBorder(WinBorder* winBorder)
{
// Note: removing a subset window is also permited/performed.
@@ -601,7 +602,8 @@ void RootLayer::RemoveWinBorder(WinBorder* winBorder)
winBorder->fParent = NULL;
}
void RootLayer::AddSubsetWinBorder(WinBorder *winBorder, WinBorder *toWinBorder)
void
RootLayer::AddSubsetWinBorder(WinBorder *winBorder, WinBorder *toWinBorder)
{
// SUBSET windows _must_ have their workspaceIndex set to 0x0
if (winBorder->Workspaces() != 0UL)
@@ -624,8 +626,7 @@ void RootLayer::AddSubsetWinBorder(WinBorder *winBorder, WinBorder *toWinBorder)
// we try to add WinBorders to all workspaces. If they are not needed, nothing will be done.
// If they are needed, Workspace automaticaly allocates space and inserts them.
for (int32 i = 0; i < fWsCount; i++)
{
for (int32 i = 0; i < fWsCount; i++) {
invalid = false;
if (fWorkspace[i] && fWorkspace[i]->HasWinBorder(toWinBorder))
@@ -639,14 +640,14 @@ void RootLayer::AddSubsetWinBorder(WinBorder *winBorder, WinBorder *toWinBorder)
show_final_scene(exFocus, exActive);
}
void RootLayer::RemoveSubsetWinBorder(WinBorder *winBorder, WinBorder *fromWinBorder)
void
RootLayer::RemoveSubsetWinBorder(WinBorder *winBorder, WinBorder *fromWinBorder)
{
// there is no point in continuing - this subset window is not visible
// at least not visible from 'fromWinBorder's point of view.
if (winBorder->IsHidden() || fromWinBorder->IsHidden())
{
return;
}
bool invalidate = false;
bool invalid;
@@ -654,8 +655,7 @@ void RootLayer::RemoveSubsetWinBorder(WinBorder *winBorder, WinBorder *fromWinBo
WinBorder* exActive = ActiveWinBorder();
// we try to remove from all workspaces. If winBorder is not in there, nothing will be done.
for (int32 i = 0; i < fWsCount; i++)
{
for (int32 i = 0; i < fWsCount; i++) {
invalid = false;
if (fWorkspace[i] && fWorkspace[i]->HasWinBorder(fromWinBorder))
@@ -807,7 +807,9 @@ bool RootLayer::SetActiveWorkspace(int32 index)
return true;
}
void RootLayer::SetWinBorderWorskpaces(WinBorder *winBorder, uint32 oldWksIndex, uint32 newWksIndex)
void
RootLayer::SetWinBorderWorskpaces(WinBorder *winBorder, uint32 oldWksIndex, uint32 newWksIndex)
{
// you *cannot* set workspaces index for a window other than a normal one!
// Note: See ServerWindow class.
@@ -819,34 +821,25 @@ void RootLayer::SetWinBorderWorskpaces(WinBorder *winBorder, uint32 oldWksIndex,
WinBorder* exFocus = FocusWinBorder();
WinBorder* exActive = ActiveWinBorder();
for (int32 i = 0; i < 32; i++)
{
if (fWorkspace[i])
{
for (int32 i = 0; i < 32; i++) {
if (fWorkspace[i]) {
invalid = false;
if (fWorkspace[i]->HasWinBorder(winBorder)
&& !(newWksIndex & (0x00000001UL << i)))
{
if (!winBorder->IsHidden())
{
&& !(newWksIndex & (0x00000001UL << i))) {
if (!winBorder->IsHidden()) {
// a little trick to force Workspace to properly pick the next front.
winBorder->fHidden = true;
invalid = fWorkspace[i]->HideWinBorder(winBorder);
winBorder->fHidden = false;
}
fWorkspace[i]->RemoveWinBorder(winBorder);
}
else
if (newWksIndex & (0x00000001UL << i) &&
!(oldWksIndex & (0x00000001UL << i)))
{
} else if (newWksIndex & (0x00000001UL << i)
&& !(oldWksIndex & (0x00000001UL << i))) {
fWorkspace[i]->AddWinBorder(winBorder);
if (!winBorder->IsHidden())
invalid = fWorkspace[i]->ShowWinBorder(winBorder);
}
else
{
} else {
// do nothing. winBorder was, and it still is a member of this workspace
// OR, winBorder wasn't and it will not be in this workspace
}
@@ -857,13 +850,11 @@ void RootLayer::SetWinBorderWorskpaces(WinBorder *winBorder, uint32 oldWksIndex,
}
// TODO: look into this...
if (fEventMaskLayer)
{
if (fEventMaskLayer) {
WinBorder* wb = fEventMaskLayer->fOwner ?
fEventMaskLayer->fOwner:
(WinBorder*)fEventMaskLayer;
if (!fWorkspace[fActiveWksIndex]->HasWinBorder(wb))
{
fEventMaskLayer->fOwner : (WinBorder*)fEventMaskLayer;
if (!fWorkspace[fActiveWksIndex]->HasWinBorder(wb)) {
/* if (wb == fEventMaskLayer)
{
fMovingWindow = false;
@@ -885,6 +876,7 @@ void RootLayer::SetWinBorderWorskpaces(WinBorder *winBorder, uint32 oldWksIndex,
show_final_scene(exFocus, exActive);
}
void
RootLayer::SetWorkspaceCount(int32 wksCount)
{
@@ -901,14 +893,15 @@ RootLayer::SetWorkspaceCount(int32 wksCount)
fWsCount = wksCount;
}
void RootLayer::ReadWorkspaceData(const char *path)
void
RootLayer::ReadWorkspaceData(const char *path)
{
BMessage msg, settings;
BFile file(path,B_READ_ONLY);
char string[20];
if(file.InitCheck()==B_OK && msg.Unflatten(&file)==B_OK)
{
if (file.InitCheck() == B_OK && msg.Unflatten(&file) == B_OK) {
int32 count;
if (msg.FindInt32("workspace_count", &count)!=B_OK)
@@ -916,29 +909,23 @@ void RootLayer::ReadWorkspaceData(const char *path)
SetWorkspaceCount(count);
for(int32 i=0; i<count; i++)
{
for (int32 i = 0; i < count; i++) {
Workspace *ws=(Workspace*)fWorkspace[i];
if (!ws)
continue;
sprintf(string,"workspace %ld",i);
if(msg.FindMessage(string,&settings)==B_OK)
{
if (msg.FindMessage(string,&settings) == B_OK) {
ws->GetSettings(settings);
settings.MakeEmpty();
}
else
} else
ws->GetDefaultSettings();
}
}
else
{
} else {
SetWorkspaceCount(9);
for(int32 i=0; i<9; i++)
{
for (int32 i = 0; i < 9; i++) {
Workspace *ws=(Workspace*)fWorkspace[i];
if (!ws)
continue;
@@ -948,7 +935,9 @@ void RootLayer::ReadWorkspaceData(const char *path)
}
}
void RootLayer::SaveWorkspaceData(const char *path)
void
RootLayer::SaveWorkspaceData(const char *path)
{
BMessage msg,dummy;
BFile file(path,B_READ_WRITE | B_CREATE_FILE);
@@ -1103,6 +1092,7 @@ RootLayer::SetScreenMode(int32 width, int32 height, uint32 colorSpace, float fre
//---------------------------------------------------------------------------
// Input related methods
//---------------------------------------------------------------------------
void
RootLayer::MouseEventHandler(int32 code, BPrivate::PortLink& msg)
{
@@ -1158,8 +1148,10 @@ RootLayer::MouseEventHandler(int32 code, BPrivate::PortLink& msg)
click_type action = target->MouseDown(evt);
bool invalidate = ActiveWorkspace()->SetFocus(target);
// TODO: only move to front if *not* in Focus Follows Mouse mode!
bool invalidate = action == DEC_MOVETOBACK ? ActiveWorkspace()->MoveToBack(target)
invalidate |= action == DEC_MOVETOBACK ? ActiveWorkspace()->MoveToBack(target)
: ActiveWorkspace()->MoveToFront(target);
// Performance: MoveToFront() often returns true although it shouldn't do that.
@@ -1188,8 +1180,7 @@ RootLayer::MouseEventHandler(int32 code, BPrivate::PortLink& msg)
else if (exFocus != FocusWinBorder()
&& !(target->WindowFlags() & B_WILL_ACCEPT_FIRST_CLICK))
sendMessage = false;
if (target->Feel() == 1024)
sendMessage = true;
if (sendMessage && fLastMouseMoved != target->fTopLayer) {
BMessage msg;
msg.what = B_MOUSE_DOWN;
@@ -1202,9 +1193,8 @@ if (target->Feel() == 1024)
target->Window()->SendMessageToClient(&msg, fLastMouseMoved->fViewToken, false);
}
if (fLastMouseMoved->EventMask() & B_POINTER_EVENTS) {
if (fLastMouseMoved->EventMask() & B_POINTER_EVENTS)
fEventMaskLayer = fLastMouseMoved;
}
break;
}
@@ -1216,7 +1206,6 @@ if (target->Feel() == 1024)
fMouseTargetWinBorder = target;
break;
}
break;
}
case B_MOUSE_UP: {
@@ -1344,18 +1333,13 @@ fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_M
// fEventMaskLayer is always != this
if (fEventMaskLayer) {
if (fEventMaskLayer == target) {
if (target == fLastMouseMoved)
fViewAction = B_INSIDE_VIEW;
else
fViewAction = B_ENTERED_VIEW;
} else if (fEventMaskLayer == fLastMouseMoved) {
fViewAction = B_EXITED_VIEW;
} else {
fViewAction = B_OUTSIDE_VIEW;
}
@@ -1900,8 +1884,7 @@ RootLayer::show_winBorder(WinBorder *winBorder)
winBorder->Show(false);
for (int32 i = 0; i < fWsCount; i++)
{
for (int32 i = 0; i < fWsCount; i++) {
invalid = false;
if (fWorkspace[i] &&
@@ -1947,8 +1930,7 @@ RootLayer::hide_winBorder(WinBorder *winBorder)
winBorder->Hide(false);
for (int32 i = 0; i < fWsCount; i++)
{
for (int32 i = 0; i < fWsCount; i++) {
invalid = false;
if (fWorkspace[i] && fWorkspace[i]->HasWinBorder(winBorder))
@@ -1983,8 +1965,7 @@ RootLayer::change_winBorder_feel(WinBorder *winBorder, int32 newFeel)
WinBorder* exFocus = FocusWinBorder();
WinBorder* exActive = ActiveWinBorder();
if (!winBorder->IsHidden())
{
if (!winBorder->IsHidden()) {
isVisible = true;
wasVisibleInActiveWorkspace = ActiveWorkspace()->HasWinBorder(winBorder);
winBorder->Hide(false);
@@ -2110,12 +2091,10 @@ RootLayer::empty_visible_regions(Layer *layer)
{
// TODO: optimize by avoiding recursion?
// NOTE: first 'layer' must be a WinBorder
Layer *child;
layer->fFullVisible.MakeEmpty();
layer->fVisible.MakeEmpty();
child = layer->BottomChild();
Layer* child = layer->BottomChild();
while (child) {
empty_visible_regions(child);
child = layer->UpperSibling();
@@ -2126,19 +2105,20 @@ RootLayer::empty_visible_regions(Layer *layer)
inline void
RootLayer::winborder_activation(WinBorder* exActive)
{
if (exActive && (FocusWinBorder() != exActive || FrontWinBorder() != exActive)) {
// ToDo: not sure if this is correct - do floating windows get WindowActivated() events?
if (exActive && FocusWinBorder() != exActive) {
BMessage msg(B_WINDOW_ACTIVATED);
msg.AddBool("active", false);
exActive->Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false);
}
if (FocusWinBorder() == FrontWinBorder()
&& FrontWinBorder() != NULL && FrontWinBorder() != exActive) {
if (FocusWinBorder() && FocusWinBorder() != exActive) {
BMessage msg(B_WINDOW_ACTIVATED);
msg.AddBool("active", true);
FrontWinBorder()->Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false);
FocusWinBorder()->Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false);
}
}
inline void
RootLayer::show_final_scene(WinBorder *exFocus, WinBorder *exActive)
{
@@ -2156,7 +2136,6 @@ RootLayer::show_final_scene(WinBorder *exFocus, WinBorder *exActive)
}
draw_window_tab(exFocus);
winborder_activation(exActive);
// TODO: MoveEventHandler::B_MOUSE_DOWN may not need this. Investigate.
@@ -2173,6 +2152,7 @@ RootLayer::show_final_scene(WinBorder *exFocus, WinBorder *exActive)
}
}
void
RootLayer::Draw(const BRect &r)
{
+4 -8
View File
@@ -88,14 +88,10 @@ public:
uint32 oldWksIndex,
uint32 newWksIndex);
WinBorder* WinBorderAt(const BPoint& pt) const;
inline WinBorder* FocusWinBorder() const { return fWorkspace[fActiveWksIndex]->Focus(); }
inline WinBorder* FrontWinBorder() const { return fWorkspace[fActiveWksIndex]->Front(); }
inline WinBorder* ActiveWinBorder() const {
return (fWorkspace[fActiveWksIndex]->Focus() ==
fWorkspace[fActiveWksIndex]->Front()
&& fWorkspace[fActiveWksIndex]->Front() != NULL)?
fWorkspace[fActiveWksIndex]->Front(): NULL;
}
inline WinBorder* FocusWinBorder() const { return ActiveWorkspace()->Focus(); }
inline WinBorder* FrontWinBorder() const { return ActiveWorkspace()->Front(); }
inline WinBorder* ActiveWinBorder() const { return ActiveWorkspace()->Active(); }
inline void SetWorkspaceCount(int32 wksCount);
inline int32 WorkspaceCount() const { return fWsCount; }
+188 -219
View File
@@ -31,7 +31,7 @@
// Design Spec:
// The purpose of this class it to have visible windows appear in the
// correct order as defined by GUI guidelines. Those define 3 main type of windows:
// normal windows, modal and floating windows. Aditionaly there must be support
// normal windows, modal and floating windows. Aditionally there must be support
// for another 2 types of windows which will be used in special cases. We're talking
// about system front windows which always will be the front-most and have focus, and
// system last windows which will always be behind all other kind of windows.
@@ -145,22 +145,21 @@ STRACE(("~Workspace(%ld) - say bye bye\n", fID));
fTopItem = NULL;
}
//----------------------------------------------------------------------------------
/*!
\brief Adds layer ptr to workspace's list of WinBorders.
*/
void Workspace::AddWinBorder(WinBorder *winBorder)
void
Workspace::AddWinBorder(WinBorder *winBorder)
{
STRACE(("W(%ld)::AddWinBorder(%s)\n", fID, winBorder?winBorder->Name():"NULL"));
if (winBorder->Level() == B_FLOATING_APP)
{
if (winBorder->Level() == B_FLOATING_APP) {
// floating windows are automaticaly added when needed
// you cannot add one by hand.
return;
}
if (HasItem(winBorder))
{
if (HasItem(winBorder)) {
// NOTE: you may remove 'debugger' at Release Candidate time
debugger("WinBorder ALREADY in Workspace's list\n");
return;
@@ -174,77 +173,83 @@ STRACE(("W(%ld)::AddWinBorder(%s)\n", fID, winBorder?winBorder->Name():"NULL"));
placeInFront(item, false);
}
//----------------------------------------------------------------------------------
/*
\brief Removes a WinBorder from workspace's list.
*/
void Workspace::RemoveWinBorder(WinBorder *winBorder)
void
Workspace::RemoveWinBorder(WinBorder *winBorder)
{
STRACE(("W(%ld)::RemoveWinBorder(%s)\n", fID, winBorder?winBorder->Name():"NULL"));
ListData* item = HasItem(winBorder);
if (item)
{
if (item) {
RemoveItem(item);
fPool.ReleaseMemory(item);
}
}
//----------------------------------------------------------------------------------
bool Workspace::HasWinBorder(const WinBorder* winBorder) const
bool
Workspace::HasWinBorder(const WinBorder* winBorder) const
{
return HasItem(winBorder) ? true: false;
}
//----------------------------------------------------------------------------------
WinBorder *Workspace::Focus() const
WinBorder *
Workspace::Focus() const
{
return fFocusItem ? fFocusItem->layerPtr : NULL;
}
//----------------------------------------------------------------------------------
WinBorder *Workspace::Front() const
WinBorder *
Workspace::Front() const
{
return fFrontItem ? fFrontItem->layerPtr: NULL;
}
//----------------------------------------------------------------------------------
WinBorder *
Workspace::Active() const
{
// ToDo: for now!
return Focus();
//return fActiveItem ? fActiveItem->layerPtr: NULL;
}
/*
\brief This method provides you the list of visible windows in this workspace.
\param list The list of visible WinBorders found in this workspace.
\param itemCount Number of WinBorder pointers found in the list.
*/
bool Workspace::GetWinBorderList(void **list, int32 *itemCount ) const
bool
Workspace::GetWinBorderList(void **list, int32 *itemCount ) const
{
int32 count = 0;
ListData* cursor;
cursor = fBottomItem;
while(cursor)
{
while (cursor) {
if (!cursor->layerPtr->IsHidden())
count++;
cursor = cursor->upperItem;
}
if (*itemCount < count)
{
if (*itemCount < count) {
// buffer not big enough. buffer must be count high
*itemCount = count;
return false;
}
if (list)
{
if (list) {
*itemCount = count;
cursor = fBottomItem;
while(cursor)
{
if (!cursor->layerPtr->IsHidden())
{
while (cursor) {
if (!cursor->layerPtr->IsHidden()) {
*list = cursor->layerPtr;
list++;
}
@@ -255,7 +260,27 @@ bool Workspace::GetWinBorderList(void **list, int32 *itemCount ) const
return true;
}
//----------------------------------------------------------------------------------
bool
Workspace::SetFocus(WinBorder* newFocus)
{
// in case this normal window is the front window,
// BUT it does not have focus.
ListData* newFocusItem = HasItem(newFocus);
if (newFocusItem && fFocusItem != newFocusItem
&& !(newFocus->WindowFlags() & B_AVOID_FOCUS)) {
// ToDo: for now, the focus item is always the active item...
// (it will be changed later on, and fixed with the refactoring)
fFocusItem = newFocusItem;
fActiveItem = newFocusItem;
return true;
}
return false;
}
/*!
\brief Makes the specified WinBorder the front one.
\param newFront WinBorder which will try to take front state.
@@ -270,34 +295,25 @@ B_NORMAL window will get front (and focus) state and subset and application floa
window will be shown in front.
Note that floating windows cannot get/have front state.
*/
bool Workspace::MoveToFront(WinBorder *newFront, bool doNotDisturb)
bool
Workspace::MoveToFront(WinBorder *newFront, bool doNotDisturb)
{
STRACE(("\nWks(%ld)::MoveToFront ~%s~ \n", fID, newFront?newFront->Name():"NULL"));
if (!newFront)
return false;
if (newFront->IsHidden())
if (newFront->IsHidden() || newFront->Level() == B_SYSTEM_LAST)
return false;
if (fFrontItem && newFront == fFrontItem->layerPtr)
{
// in case this normal window is the front window,
// BUT it does not have focus.
ListData *newFocusItem = HasItem(newFront);
if (newFocusItem && fFocusItem != newFocusItem
&& !(newFront->WindowFlags() & B_AVOID_FOCUS))
{
fFocusItem = newFocusItem;
}
if (fFrontItem && newFront == fFrontItem->layerPtr) {
// we didn't change windows order
return false;
}
else
return ShowWinBorder(newFront);
}
//----------------------------------------------------------------------------------
/*!
\brief Moves the specified WinBorder in the back as it is possible.
\param newLast WinBorder which will be placed in the back.
@@ -311,7 +327,8 @@ undermine the role of modal windows in the system. Another example regards B_FLO
windows. These will ge in the back as possible, but never farther than the front
B_NORMAL window in front of which they appear.
*/
bool Workspace::MoveToBack(WinBorder *newLast)
bool
Workspace::MoveToBack(WinBorder *newLast)
{
STRACE(("Wks(%ld)::MoveToBack(%s) \n", fID, newLast? newLast->Name(): "NULL"));
if (newLast->IsHidden())
@@ -465,7 +482,7 @@ STRACE(("Wks(%ld)::MoveToBack(%s) \n", fID, newLast? newLast->Name(): "NULL"));
return returnValue;
}
//----------------------------------------------------------------------------------
/*!
\brief Hides a WinBorder.
\param winBorder WinBorder to be hidden.
@@ -476,41 +493,40 @@ may also be removed from Workspace's list.
If \a winBorder if the front WinBorder, another one (or none) will be automaticaly
chosen. Same goes for focus.
*/
bool Workspace::HideWinBorder(WinBorder *winBorder)
bool
Workspace::HideWinBorder(WinBorder *winBorder)
{
STRACE(("W(%ld)::HideWinBorder(%s) \n", fID, winBorder? winBorder->Name(): "NULL"));
bool returnValue = false;
int32 level = winBorder->Level();
bool changeFront = false;
bool changeFocus = false;
ListData* nextFocus = NULL;
if (fFrontItem && fFrontItem->layerPtr == winBorder)
changeFront = true;
if (fFocusItem && fFocusItem->layerPtr == winBorder)
if (fFocusItem && fFocusItem->layerPtr == winBorder) {
changeFocus = true;
nextFocus = fFocusItem->lowerItem;
}
if (level > B_SYSTEM_FIRST)
level = B_SYSTEM_FIRST;
switch(level)
{
switch (level) {
case B_MODAL_ALL:
case B_SYSTEM_FIRST:
case B_SYSTEM_LAST:
case B_FLOATING_ALL:
{
// window is just hidden. do nothing. its position is OK as it is now.
returnValue = true;
}
break;
case B_FLOATING_APP:
{
if (fFrontItem && fFrontItem->layerPtr->Level() == B_NORMAL)
{
if (fFrontItem && fFrontItem->layerPtr->Level() == B_NORMAL) {
ListData* item = HasItem(winBorder);
if (item)
{
if (item) {
fFrontItem->layerPtr->fSubWindowList.AddWinBorder(winBorder);
RemoveItem(item);
@@ -519,29 +535,23 @@ STRACE(("W(%ld)::HideWinBorder(%s) \n", fID, winBorder? winBorder->Name(): "NULL
returnValue = true;
}
}
}
break;
case B_NORMAL:
{
if (fFrontItem && fFrontItem->layerPtr == winBorder)
{
saveFloatingWindows(fFrontItem);
}
if (Focus() == winBorder)
saveFloatingWindows(fFocusItem);
// remove B_MODAL_SUBSET windows present before this window.
ListData* itemThis = HasItem(winBorder);
ListData* toast;
ListData* item = itemThis->lowerItem;
while(item)
{
while (item) {
// if this modal subset is in our list ONLY (not in other visible normal window's one),
// then remove from Workspace's list.
if (item->layerPtr->Level() == B_MODAL_APP)
{
if(winBorder->fSubWindowList.HasItem(item->layerPtr))
{
if(!searchFirstMainWindow(item->layerPtr))
{
if (item->layerPtr->Level() == B_MODAL_APP) {
if (winBorder->fSubWindowList.HasItem(item->layerPtr)) {
if (!searchFirstMainWindow(item->layerPtr)) {
// if this modal subset has front state, make sure another window will get that status.
if (fFrontItem == item)
changeFront = true;
@@ -551,10 +561,8 @@ STRACE(("W(%ld)::HideWinBorder(%s) \n", fID, winBorder? winBorder->Name(): "NULL
RemoveItem(toast);
fPool.ReleaseMemory(toast);
}
}
else if (!searchANormalWindow(item->layerPtr)
&& !(item->layerPtr->Workspaces() & (0x00000001 << fID)))
{
} else if (!searchANormalWindow(item->layerPtr)
&& !(item->layerPtr->Workspaces() & (0x00000001 << fID))) {
// if this modal subset has front state, make sure another window will get that status.
if (fFrontItem == item)
changeFront = true;
@@ -563,73 +571,73 @@ STRACE(("W(%ld)::HideWinBorder(%s) \n", fID, winBorder? winBorder->Name(): "NULL
item = item->lowerItem;
RemoveItem(toast);
fPool.ReleaseMemory(toast);
}
else
} else
item = item->lowerItem;
}
else
} else
item = item->lowerItem;
}
returnValue = true;
}
break;
}
case B_MODAL_APP:
{
// if a subset modal, then remove from Workspace's list.
if (!winBorder->App()->fAppSubWindowList.HasItem(winBorder))
{
if (!winBorder->App()->fAppSubWindowList.HasItem(winBorder)) {
ListData* toast = HasItem(winBorder);
if (toast)
{
if (toast) {
RemoveItem(toast);
fPool.ReleaseMemory(toast);
returnValue = true;
}
}
}
break;
default:
{
debugger("HideWinBorder: what kind of window is this?\n");
}
default:
debugger("HideWinBorder: what kind of window is this?\n");
}
// select a new Front if needed
if (changeFront)
{
ListData *newFront;
if (changeFront) {
fFrontItem = NULL;
fFocusItem = NULL;
newFront = findNextFront();
ListData* newFront = findNextFront();
if (newFront)
returnValue = MoveToFront(newFront->layerPtr);
MoveToFront(newFront->layerPtr);
}
if (!HasItem(fFocusItem))
fFocusItem = NULL;
// floating windows can have focus state. what if this removed window is
// the focus window? There will be no focus anymore.
// So, start a search to set the new focus
if (!fFocusItem || changeFocus)
{
ListData *cursor = fBottomItem;
if (!fFocusItem || changeFocus) {
if (!HasItem(nextFocus))
nextFocus = NULL;
while(cursor)
{
if (!cursor->layerPtr->IsHidden() && !(cursor->layerPtr->WindowFlags() & B_AVOID_FOCUS))
if (nextFocus == NULL) {
nextFocus = fBottomItem;
while (nextFocus) {
if (!nextFocus->layerPtr->IsHidden()
&& !(nextFocus->layerPtr->WindowFlags() & B_AVOID_FOCUS))
break;
else
cursor = cursor->upperItem;
nextFocus = nextFocus->upperItem;
}
}
fFocusItem = cursor;
fFocusItem = nextFocus;
fActiveItem = nextFocus;
}
return returnValue;
}
//----------------------------------------------------------------------------------
/*!
\brief Shows a WinBorder.
\param winBorder WinBorder to be show.
@@ -639,7 +647,8 @@ STRACE(("W(%ld)::HideWinBorder(%s) \n", fID, winBorder? winBorder->Name(): "NULL
ones will be placed in front if needed. Front & Focus state will be given to \a winBorder
unless a modal windows steals both.
*/
bool Workspace::ShowWinBorder(WinBorder *winBorder, bool userBusy)
bool
Workspace::ShowWinBorder(WinBorder *winBorder, bool userBusy)
{
STRACE(("W(%ld)::ShowWinBorder(%s) \n", fID, winBorder? winBorder->Name(): "NULL"));
bool returnValue = false;
@@ -651,9 +660,7 @@ STRACE(("W(%ld)::ShowWinBorder(%s) \n", fID, winBorder? winBorder->Name(): "NULL
// called of EVERY window except B_FLOATING_APP when
// ADDING a new window to Workspace's list!!!
switch (level)
{
switch (level) {
// B_MODAL_ALL, B_FLOATNG_ALL, B_SYSTEM_FIRST & B_SYSTEM_LAST
// will be removed ONLY when are deleted!
// ALSO, they will ALWAYS be the first/last windows in hierarchy, no matter
@@ -664,30 +671,26 @@ STRACE(("W(%ld)::ShowWinBorder(%s) \n", fID, winBorder? winBorder->Name(): "NULL
case B_SYSTEM_LAST:
{
// nothing special to be done. just compare indexes to see if front state will change.
if (fFrontItem)
{
if (fFrontItem) {
int32 reverseIndexThis, reverseIndexFront;
ListData *itemThis;
ListData* itemThis = HasItem(winBorder, &reverseIndexThis);
itemThis = HasItem(winBorder, &reverseIndexThis);
HasItem(fFrontItem->layerPtr, &reverseIndexFront);
if (reverseIndexThis < reverseIndexFront)
{
if (reverseIndexThis < reverseIndexFront) {
if (fFrontItem->layerPtr->Level() == B_NORMAL)
saveFloatingWindows(fFrontItem);
fFrontItem = itemThis;
}
}
// of course, if no front item, then set this one.
else
{
} else {
// of course, if there is no front item, then set this one.
fFrontItem = HasItem(winBorder);
}
returnValue = true;
}
break;
}
case B_FLOATING_ALL:
{
// simply relocate. A floating window can't have front state.
@@ -696,8 +699,8 @@ STRACE(("W(%ld)::ShowWinBorder(%s) \n", fID, winBorder? winBorder->Name(): "NULL
placeInFront(itemThis, userBusy);
returnValue = true;
}
break;
}
// FLOATING windows are always removed from Workspace's list when changing to a new front window.
@@ -705,29 +708,24 @@ STRACE(("W(%ld)::ShowWinBorder(%s) \n", fID, winBorder? winBorder->Name(): "NULL
{
// see if we have a front window which is a B_NORMAL window and who's list of floating
// and modal windows contains our window.
if (fFrontItem && fFrontItem->layerPtr->Level() == B_NORMAL)
{
if (fFrontItem && fFrontItem->layerPtr->Level() == B_NORMAL) {
// if this winBorder is the focus it is already the first among floating app windows.
if (fFocusItem && fFocusItem->layerPtr == winBorder)
break;
ListData* itemThis = NULL;
// remove from B_NORMAL's list.
if (fFrontItem->layerPtr->fSubWindowList.RemoveItem(winBorder))
{
if (fFrontItem->layerPtr->fSubWindowList.RemoveItem(winBorder)) {
// we need to add this window
itemThis = fPool.GetCleanMemory(winBorder);
}
else
{
} else {
itemThis = HasItem(winBorder);
// window is already in Workspace's list. Find and temporarly remove.
if (itemThis)
RemoveItem(itemThis);
}
if (itemThis)
{
if (itemThis) {
// insert in front of other B_FLOATING_APP windows.
ListData* item = fFrontItem->lowerItem;
while (item && item->layerPtr->Level() == B_FLOATING_APP)
@@ -738,14 +736,14 @@ STRACE(("W(%ld)::ShowWinBorder(%s) \n", fID, winBorder? winBorder->Name(): "NULL
returnValue = true;
}
}
}
break;
}
case B_NORMAL:
{
ListData* itemThis = HasItem(winBorder);
if (!itemThis)
{
if (!itemThis) {
debugger("ShowWinBorder: B_NORMAL window - cannot find specified window in workspace's list\n");
return false;
}
@@ -762,14 +760,10 @@ STRACE(("W(%ld)::ShowWinBorder(%s) \n", fID, winBorder? winBorder->Name(): "NULL
ListData* newFront = itemThis;
if (windowHasVisibleModals(winBorder))
{
newFront = putModalsInFront(itemThis);
}
if (fFrontItem)
{
if (!userBusy)
{
if (fFrontItem) {
if (!userBusy) {
int32 revFrontItemIndex, revNewFrontIndex;
HasItem(fFrontItem, &revFrontItemIndex);
@@ -777,9 +771,7 @@ STRACE(("W(%ld)::ShowWinBorder(%s) \n", fID, winBorder? winBorder->Name(): "NULL
if (revNewFrontIndex < revFrontItemIndex)
fFrontItem = newFront;
}
}
else
{
} else {
fFrontItem = newFront;
}
@@ -787,8 +779,8 @@ STRACE(("W(%ld)::ShowWinBorder(%s) \n", fID, winBorder? winBorder->Name(): "NULL
putFloatingInFront(fFrontItem);
returnValue = true;
}
break;
}
// MODAL windows usualy stay in Workspace's list, but they are scatered, so we must gather them
// when needed.
@@ -797,29 +789,24 @@ STRACE(("W(%ld)::ShowWinBorder(%s) \n", fID, winBorder? winBorder->Name(): "NULL
{
// build a list of modal windows to know what windows should be placed before this one.
BList tempList;
// APP modal
if (winBorder->App()->fAppSubWindowList.HasItem(winBorder))
{
if (winBorder->App()->fAppSubWindowList.HasItem(winBorder)) {
// take only application's modals
tempList.AddList(&winBorder->App()->fAppSubWindowList);
if (fFrontItem
&& fFrontItem->layerPtr->App()->ClientTeam() == winBorder->App()->ClientTeam())
userBusy = false;
}
} else {
// SUBSET modal
else
{
WinBorder *mainWindow = searchFirstMainWindow(winBorder);
if (mainWindow)
{
if (mainWindow) {
// add both mainWindow's subset modals and application's modals
tempList.AddList(&mainWindow->fSubWindowList);
tempList.AddList(&winBorder->App()->fAppSubWindowList);
if (fFrontItem && fFrontItem->layerPtr == mainWindow)
userBusy = false;
}
else
{
} else {
// none of the unhiden normal windows havs this window as part of its subset.
// as a result this window won't be added to Workspace's list for it to be shown.
return false;
@@ -836,12 +823,9 @@ STRACE(("W(%ld)::ShowWinBorder(%s) \n", fID, winBorder? winBorder->Name(): "NULL
// find and remove the Workspace's entry for this WinBorder.
ListData *itemThis;
itemThis = HasItem(winBorder);
if (itemThis)
{
if (itemThis) {
RemoveItem(itemThis);
}
else
{
} else {
// not found? no problem. create a new entry.
itemThis = fPool.GetCleanMemory(winBorder);
}
@@ -869,13 +853,10 @@ STRACE(("W(%ld)::ShowWinBorder(%s) \n", fID, winBorder? winBorder->Name(): "NULL
count = tempList.CountItems();
wbList = (WinBorder**)tempList.Items();
for(i = indexThisInTempList; i < count; i++)
{
if (!wbList[i]->IsHidden())
{
for (i = indexThisInTempList; i < count; i++) {
if (!wbList[i]->IsHidden()) {
itemX = HasItem(wbList[i], &revIndexItem);
if (itemX && revIndexItem > revIndexThis)
{
if (itemX && revIndexItem > revIndexThis) {
removeAndPlaceBefore(itemX, before);
newFront = itemX;
}
@@ -883,10 +864,8 @@ STRACE(("W(%ld)::ShowWinBorder(%s) \n", fID, winBorder? winBorder->Name(): "NULL
}
}
if (fFrontItem)
{
if (!userBusy)
{
if (fFrontItem) {
if (!userBusy) {
int32 revFrontItemIndex, revNewFrontIndex;
HasItem(fFrontItem, &revFrontItemIndex);
@@ -897,47 +876,39 @@ STRACE(("W(%ld)::ShowWinBorder(%s) \n", fID, winBorder? winBorder->Name(): "NULL
if (fFrontItem->layerPtr->Level() == B_NORMAL)
putFloatingInFront(fFrontItem);
}
else
{
} else {
fFrontItem = newFront;
}
returnValue = true;
}
break;
}
default:
debugger("What kind of window is this???\n");
}
if (!HasItem(fFocusItem))
fFocusItem = NULL;
// set new Focus if needed
if (returnValue)
{
if (Focus() == NULL) {
ListData* cursor = fBottomItem;
fFocusItem = NULL;
while(cursor)
{
if (!cursor->layerPtr->IsHidden() && !(cursor->layerPtr->WindowFlags() & B_AVOID_FOCUS))
{
if (cursor->layerPtr->Level() == B_FLOATING_APP || cursor->layerPtr->Level() == B_FLOATING_ALL)
{
while (cursor != NULL && fFocusItem == NULL) {
if (!cursor->layerPtr->IsHidden()
&& !(cursor->layerPtr->WindowFlags() & B_AVOID_FOCUS)) {
if (cursor->layerPtr->Level() == B_FLOATING_APP
|| cursor->layerPtr->Level() == B_FLOATING_ALL) {
// set focus to floating windows only if directly targeted
if (cursor->layerPtr == winBorder)
{
if (cursor->layerPtr == winBorder) {
fFocusItem = cursor;
break;
}
else
} else
cursor = cursor->upperItem;
}
else
{
} else
fFocusItem = cursor;
break;
}
}
else
} else
cursor = cursor->upperItem;
}
}
@@ -946,35 +917,34 @@ STRACE(("W(%ld)::ShowWinBorder(%s) \n", fID, winBorder? winBorder->Name(): "NULL
}
//----------------------------------------------------------------------------------
void Workspace::SetLocalSpace(const uint32 colorspace)
void
Workspace::SetLocalSpace(const uint32 colorspace)
{
fSpace = colorspace;
}
//----------------------------------------------------------------------------------
uint32 Workspace::LocalSpace() const
uint32
Workspace::LocalSpace() const
{
return fSpace;
}
//----------------------------------------------------------------------------------
void Workspace::SetBGColor(const RGBColor &c)
void
Workspace::SetBGColor(const RGBColor &c)
{
fBGColor = c;
}
//----------------------------------------------------------------------------------
RGBColor Workspace::BGColor(void) const
RGBColor
Workspace::BGColor(void) const
{
return fBGColor;
}
//----------------------------------------------------------------------------------
/*!
\brief Retrieves settings from a container message passed to PutSettings
\param A BMessage containing data from a PutSettings() call
@@ -982,7 +952,8 @@ RGBColor Workspace::BGColor(void) const
This function will place default values whenever a particular setting cannot
be found.
*/
void Workspace::GetSettings(const BMessage &msg)
void
Workspace::GetSettings(const BMessage &msg)
{
BMessage container;
rgb_color *color;
@@ -1156,7 +1127,9 @@ void Workspace::PutDefaultSettings(BMessage *msg, const uint8 &index)
//----------------------------------------------------------------------------------
// Debug method
void Workspace::PrintToStream() const
void
Workspace::PrintToStream() const
{
printf("Workspace %ld hierarchy shown from back to front:\n", fID);
for (ListData *item = fTopItem; item != NULL; item = item->lowerItem)
@@ -1187,9 +1160,9 @@ void Workspace::PrintToStream() const
printf("Front Layer:\t%s\n\n", fFrontItem? fFrontItem->layerPtr->Name(): "NULL");
}
//----------------------------------------------------------------------------------
// Debug method
void Workspace::PrintItem(ListData *item) const
void
Workspace::PrintItem(ListData *item) const
{
printf("ListData members:\n");
if(item)
@@ -1264,6 +1237,9 @@ Workspace::RemoveItem(ListData *item)
if (fFrontItem == item)
fFrontItem = NULL;
if (fActiveItem == item)
fActiveItem = NULL;
}
@@ -1426,42 +1402,35 @@ Workspace::placeInFront(ListData *item, const bool userBusy)
level = B_NORMAL;
// B_SYSTEM_LAST - always place (the most) last
if (level == B_SYSTEM_LAST)
{
if (level == B_SYSTEM_LAST) {
InsertItem(item, fTopItem);
return;
}
// search for the exact place...
while (cursor)
{
while (cursor) {
cursorLevel = cursor->layerPtr->Level();
// make MODAL windows act just like normal ones.
if (cursorLevel == B_MODAL_APP)
cursorLevel = B_NORMAL;
if (level < cursorLevel)
{
if (level < cursorLevel) {
cursor = cursor->upperItem;
continue;
}
else
{
} else {
// that's it, we've found the proper place.
break;
}
}
if (cursor)
{
if (cursor) {
// if user is busy typing something, or has an opened menu...
if (userBusy && cursor == fFrontItem)
InsertItem(item, cursor);
else
InsertItem(item, cursor->lowerItem);
}
else
} else
InsertItem(item, fTopItem);
}
+9 -6
View File
@@ -47,24 +47,26 @@ struct ListData
ListData *lowerItem;
};
class Workspace
{
class Workspace {
public:
Workspace( const int32 ID,
const uint32 colorspace,
const RGBColor& BGColor);
~Workspace(void);
~Workspace();
int32 ID(void) const { return fID; }
int32 ID() const { return fID; }
void AddWinBorder(WinBorder *winBorder);
void RemoveWinBorder(WinBorder *winBorder);
bool HasWinBorder(const WinBorder *winBorder) const;
WinBorder* Focus(void) const;
WinBorder* Front(void) const;
WinBorder* Focus() const;
WinBorder* Front() const;
WinBorder* Active() const;
bool GetWinBorderList(void **list, int32 *itemCount ) const;
bool SetFocus(WinBorder* newFocus);
bool MoveToBack(WinBorder *newLast);
bool MoveToFront(WinBorder *newFront, bool doNotDisturb = false);
@@ -139,6 +141,7 @@ private:
// pointer for which "big" actions are intended
ListData *fFrontItem;
ListData* fActiveItem;
// settings for each workspace -- example taken from R5's app_server_settings file
display_timing fDisplayTiming;