From 0a8120dd1ce8eb8b1aa4370d6ed5711a5da1fede Mon Sep 17 00:00:00 2001 From: Adi Oanca Date: Sat, 17 Jan 2004 16:33:22 +0000 Subject: [PATCH] * fixed some bugs, and improved some things. * rendered BWindow::RemoveFromSubset operationable That's it! I seems regular windows NORMAL/FLOATING/MODAL windows are shown when and how they should be. There are other kind of windows, to be precise B_SYSTEM_LAST and B_SYSTEM_FIRST, with witch I played very little. I'll be back on them 2 weks from now when I hope I'll start codeing again. Till then... happy coding! :-) git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6114 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/server/Desktop.cpp | 11 +- src/servers/app/server/RootLayer.cpp | 2 + src/servers/app/server/ServerWindow.cpp | 35 +++-- src/servers/app/server/WinBorder.cpp | 12 +- src/servers/app/server/Workspace.cpp | 170 +++++++++++++++++------- src/servers/app/server/Workspace.h | 2 + 6 files changed, 171 insertions(+), 61 deletions(-) diff --git a/src/servers/app/server/Desktop.cpp b/src/servers/app/server/Desktop.cpp index 589ea2fd39..c25e486e54 100644 --- a/src/servers/app/server/Desktop.cpp +++ b/src/servers/app/server/Desktop.cpp @@ -425,14 +425,23 @@ void Desktop::SaveWorkspaceData(void){ //--------------------------------------------------------------------------- void Desktop::RemoveSubsetWindow(WinBorder* wb){ WinBorder *winBorder = NULL; + + fLayerLock.Lock(); int32 count = fWinBorderList.CountItems(); for(int32 i=0; i < count; i++){ winBorder = static_cast(fWinBorderList.ItemAt(i)); if (winBorder->_level == B_NORMAL_FEEL) winBorder->Window()->fWinFMWList.RemoveItem(wb); } - + fLayerLock.Unlock(); + RootLayer *rl = winBorder->GetRootLayer(); + + if (!fGeneralLock.IsLocked()) + debugger("Desktop::RemoveWinBorder() - fGeneralLock must be locked!\n"); + if (!(rl->fMainLock.IsLocked())) + debugger("Desktop::RemoveWinBorder() - fMainLock must be locked!\n"); + int32 countWKs = rl->WorkspaceCount(); for (int32 i=0; i < countWKs; i++){ rl->WorkspaceAt(i+1)->RemoveLayerPtr(wb); diff --git a/src/servers/app/server/RootLayer.cpp b/src/servers/app/server/RootLayer.cpp index 578f2281a2..f8527a9d6b 100644 --- a/src/servers/app/server/RootLayer.cpp +++ b/src/servers/app/server/RootLayer.cpp @@ -52,6 +52,8 @@ printf("*RootLayer(%s)::Draw(r)\n", GetName()); if (!desktop->fGeneralLock.IsLocked()) printf("\n\n\tWARNING: desktop->fGeneralLock MUST be locked!!!\n\n"); +// NOTE: in case you have problems - ActiveWorkspace()->opLock was acquired in Workspace::Invalidate()!!! + RGBColor c(51,102,152); fDriver->FillRect(Bounds(), c); diff --git a/src/servers/app/server/ServerWindow.cpp b/src/servers/app/server/ServerWindow.cpp index 23a1e705e2..26e07310c3 100644 --- a/src/servers/app/server/ServerWindow.cpp +++ b/src/servers/app/server/ServerWindow.cpp @@ -200,7 +200,7 @@ ServerWindow::ServerWindow(BRect rect, const char *string, uint32 wlook, //!Tears down all connections with the user application, kills the monitoring thread. ServerWindow::~ServerWindow(void) { -STRACE(("*ServerWindow %s:~ServerWindow()\n",_title->String())); +STRACE(("*ServerWindow (%s):~ServerWindow()\n",_title->String())); desktop->fGeneralLock.Lock(); @@ -317,6 +317,7 @@ printf("ServerWindow(%s)::Show() - Main lock acquired\n", _winborder->GetName()) for(int32 i = 0; i < wksCount; i++){ if (fWorkspaces & (0x00000001UL << i)){ Workspace *ws = rl->WorkspaceAt(i+1); + ws->BringToFrontANormalWindow(_winborder); ws->SearchAndSetNewFront(_winborder); ws->SetFocusLayer(_winborder); } @@ -352,16 +353,16 @@ printf("ServerWindow(%s)::Hide() - Main lock acquired\n", _winborder->GetName()) int32 wksCount= rl->WorkspaceCount(); for(int32 i = 0; i < wksCount; i++){ ws = rl->WorkspaceAt(i+1); - if ( ws->FrontLayer() == _winborder){ - if(ws->FocusLayer() == _winborder){ - // do not redraw! just set the new front. - ws->SearchAndSetNewFront(_winborder); - // redraw also + if (ws->FrontLayer() == _winborder){ + ws->HideSubsetWindows(_winborder); + ws->SetFocusLayer(ws->FrontLayer()); + } + else{ + if (ws->FocusLayer() == _winborder){ ws->SetFocusLayer(_winborder); } else{ - // redraw also - ws->SetFrontLayer(_winborder); + ws->Invalidate(); } } } @@ -1412,6 +1413,24 @@ TODO: Figure out what Adi did here and convert to PortMessages } case AS_REM_FROM_SUBSET: { + WinBorder *wb; + int32 mainToken; + team_id teamID; + + ses->ReadInt32(&mainToken); + ses->ReadData(&teamID, sizeof(team_id)); + + wb = desktop->FindWinBorderByServerWindowTokenAndTeamID(mainToken, teamID); + if(wb){ + ses->WriteInt32(SERVER_TRUE); + ses->Sync(); + + _winborder->RemoveFromSubsetOf(wb); + } + else{ + ses->WriteInt32(SERVER_FALSE); + ses->Sync(); + } // TODO: Implement STRACE(("ServerWindow %s: Message Remove_From_Subset unimplemented\n",_title->String())); break; diff --git a/src/servers/app/server/WinBorder.cpp b/src/servers/app/server/WinBorder.cpp index b29d049f02..fdb6a28c66 100644 --- a/src/servers/app/server/WinBorder.cpp +++ b/src/servers/app/server/WinBorder.cpp @@ -754,6 +754,12 @@ printf("WinBorder(%s)::AddToSubsetOf(%s) - General lock released\n", GetName(), } //--------------------------------------------------------------------------- void WinBorder::RemoveFromSubsetOf(WinBorder* main){ + RootLayer *rl = main->GetRootLayer(); + + desktop->fGeneralLock.Lock(); +printf("WinBorder(%s)::RemoveFromSubsetOf(%s) - General lock acquired\n", GetName(), main->GetName()); + rl->fMainLock.Lock(); +printf("WinBorder(%s)::RemoveFromSubsetOf(%s) - Main lock acquired\n", GetName(), main->GetName()); // remove from main window's subset list. if(main->Window()->fWinFMWList.RemoveItem(this)){ int32 count = main->GetRootLayer()->WorkspaceCount(); @@ -766,8 +772,12 @@ void WinBorder::RemoveFromSubsetOf(WinBorder* main){ } } } - fMainWinBorder = NULL; + + rl->fMainLock.Unlock(); +printf("WinBorder(%s)::RemoveFromSubsetOf(%s) - Main lock released\n", GetName(), main->GetName()); + desktop->fGeneralLock.Unlock(); +printf("WinBorder(%s)::RemoveFromSubsetOf(%s) - General lock released\n", GetName(), main->GetName()); } //--------------------------------------------------------------------------- void WinBorder::PrintToStream(){ diff --git a/src/servers/app/server/Workspace.cpp b/src/servers/app/server/Workspace.cpp index 1687321356..760b8aebcd 100644 --- a/src/servers/app/server/Workspace.cpp +++ b/src/servers/app/server/Workspace.cpp @@ -102,7 +102,7 @@ STRACE(("\n*AddLayerPtr(%s) -", layer->GetName())); bool Workspace::RemoveLayerPtr(WinBorder* layer){ if (!layer) return false; -STRACE(("\n#Workspace(%ld)::RemoveLayerPtr(%s)\n", ID(), layer->GetName())); +STRACE(("\n*Workspace(%ld)::RemoveLayerPtr(%s)\n", ID(), layer->GetName())); STRACE(("BEFORE ANY opperation:\n")); STRACESTREAM(); // search to see if this workspace has WinBorder's pointer in its list @@ -110,49 +110,51 @@ STRACESTREAM(); opLock.Lock(); if ((item = HasItem(layer))){ - ListData *nextItem = NULL; - bool wasFront, wasFocus; + ListData *nextItem = NULL; + bool wasFront = false; + bool wasFocus = false; + + wasFront = FrontLayer() == layer; + wasFocus = FocusLayer() == layer; // prepare to set new front/focus if this layer was front/focus nextItem = item->upperItem; - wasFront = fFrontItem? fFrontItem->layerPtr == layer: false; - wasFocus = fFocusItem? fFocusItem->layerPtr == layer: false; - // remove any floating window our window may have - ListData *listItem = item->lowerItem; - while(listItem && (listItem->layerPtr->_level == B_FLOATING_SUBSET_FEEL - || listItem->layerPtr->_level == B_FLOATING_APP_FEEL)) - { // *carefully* remove the item from the list - ListData *itemX = listItem; - listItem = listItem->lowerItem; - RemoveItem(itemX); + if (wasFront) + SearchAndSetNewFront(nextItem? nextItem->layerPtr: NULL); + + // remove some windows. + if (item && item->layerPtr->_level == B_NORMAL_FEEL) + { + ListData *listItem = item->lowerItem; + while(listItem && (listItem->layerPtr->_level == B_FLOATING_SUBSET_FEEL + || listItem->layerPtr->_level == B_FLOATING_APP_FEEL + || listItem->layerPtr->_level == B_MODAL_SUBSET_FEEL)) + { + // *carefuly* remove the item from the list + ListData *itemX = listItem; + listItem = listItem->lowerItem; + RemoveItem(itemX); + delete itemX; + } } - - // remove from workspace's list + RemoveItem(item); - + delete item; +STRACESTREAM(); opLock.Unlock(); // reset some internal variables layer->SetMainWinBorder(NULL); // its RootLayer is set to NULL by Layer::RemoveChild(layer); + printf("Layer %s found and removed from Workspace No %ld\n", layer->GetName(), ID()); - if (wasFront){ - if(wasFocus){ - SearchAndSetNewFront(nextItem? nextItem->layerPtr: NULL); - SetFocusLayer(nextItem? nextItem->layerPtr: NULL); - } - else - SetFrontLayer(nextItem? nextItem->layerPtr: NULL); - } - if (wasFocus && !wasFront) + if (wasFocus) SetFocusLayer(nextItem? nextItem->layerPtr: NULL); -STRACE(("AFTER opperations...\n")); -STRACESTREAM(); + else + Invalidate(); - // delete item struct, we no longer need that - delete item; return true; } else{ @@ -162,6 +164,50 @@ printf("Layer %s NOT found in Workspace No %ld\n", layer->GetName(), ID()); } } //--------------------------------------------------------------------------- +bool Workspace::HideSubsetWindows(WinBorder* layer){ + if (!layer) + return false; + + // search to see if this workspace has WinBorder's pointer in its list + ListData *item = NULL; + + opLock.Lock(); + if ((item = HasItem(layer))){ + ListData *nextItem = NULL; + + // prepare to set new front/focus if this layer was front/focus + nextItem = item->upperItem; + + SearchAndSetNewFront(nextItem? nextItem->layerPtr: NULL); + // we don't care bout focus in this method!!! + //SearchAndSetNewFocus(nextItem? nextItem->layerPtr: NULL); + + // remove some windows. + if (item && item->layerPtr->_level == B_NORMAL_FEEL) + { + ListData *listItem = item->lowerItem; + while(listItem && (listItem->layerPtr->_level == B_FLOATING_SUBSET_FEEL + || listItem->layerPtr->_level == B_FLOATING_APP_FEEL + || listItem->layerPtr->_level == B_MODAL_SUBSET_FEEL)) + { + // *carefuly* remove the item from the list + ListData *itemX = listItem; + listItem = listItem->lowerItem; + RemoveItem(itemX); + delete itemX; + } + } + + opLock.Unlock(); + + return true; + } + else{ + opLock.Unlock(); + return false; + } +} +//--------------------------------------------------------------------------- WinBorder* Workspace::SetFocusLayer(WinBorder* layer){ STRACE(("\n@Workspace(%ld)::SetFOCUSLayer( %s )\n", ID(), layer? layer->GetName(): "NULL")); @@ -280,8 +326,10 @@ printf("%s - SELECTED!\n", wb->GetName()); //--------------------------------------------------------------------------- void Workspace::Invalidate(){ //TODO: *****!*!*!*!*!*!*!**!***REMOVE this! For Test purposes only! + opLock.Lock(); if(fOwner->ActiveWorkspace() == this) fOwner->DoInvalidate(BRegion(fOwner->Bounds()), NULL); + opLock.Unlock(); //---------------- } //--------------------------------------------------------------------------- @@ -376,7 +424,9 @@ ListData* Workspace::HasItem(WinBorder* layer){ ListData* Workspace::FindPlace(ListData* pref){ // if we received a NULL value, we stil have to give 'front' state to some window... if (!pref) - pref = fBottomItem; + pref = HasItem(fBottomItem); + else + pref = HasItem(pref); ListData *item = NULL; @@ -385,7 +435,7 @@ ListData* Workspace::FindPlace(ListData* pref){ while(pref && item->lowerItem != pref && (pref->upperItem || pref->lowerItem)){ if ( !(item->layerPtr->Window()->Flags() & B_AVOID_FRONT) && !(item->layerPtr->IsHidden()) ) break; - +printf("item: %s - pref: %s\n", item->layerPtr->GetName(), pref->layerPtr->GetName()); if (item == fTopItem) item = fBottomItem; else @@ -519,8 +569,6 @@ STRACE(("#WS(%ld)::SASNF(%s) ENDED 1\n", ID(), preferred? preferred->GetName(): return; } -// ListData *exFocusItem = fFocusItem; - // properly place this 'preferred' WinBorder. ListData *lastInserted; lastInserted = FindPlace(HasItem(preferred)); @@ -553,18 +601,6 @@ STRACE((" NORMAL Window '%s' -", preferred? preferred->GetName(): "NULL")); // if they are in the same team... if (preferred->Window()->ClientTeamID() == fFrontItem->layerPtr->Window()->ClientTeamID()){ STRACE((" SAME TeamID\n")); -/* - { - int32 exFeel = exFocusItem? exFocusItem->layerPtr->Window()->Feel() : 0; - if (exFocusItem && - (exFeel == B_FLOATING_SUBSET_WINDOW_FEEL || exFeel == B_MODAL_SUBSET_WINDOW_FEEL) - { - if ( !(fFocusItem->layerPtr->Window()->fWinFMWList.HasItem(exFocusItem->layerPtr)) ){ - - } - } - } -*/ // collect subset windows that are common to application's windows... // NOTE: A subset window *can* be added to more than just one window. FMWList commonFMW; @@ -593,8 +629,9 @@ STRACE((" SAME TeamID\n")); listItem = listItem->lowerItem; RemoveItem(item); } - else + else{ listItem = listItem->lowerItem; + } } // ALSO collect application's floating and modal windows, // for reinsertion, later. @@ -619,7 +656,8 @@ STRACE((" SAME TeamID\n")); count = preferred->Window()->fWinFMWList.CountItems(); for (i=0; iWindow()->fWinFMWList.ItemAt(i); - if (commonFMW.HasItem(item)){ } + if (commonFMW.HasItem(item)){ + } else finalFMWList.AddItem(item); } @@ -931,7 +969,7 @@ STRACE((" MODAL ALL/SYSTEM FIRST Window '%s'\n", preferred? preferred->GetName() ListData *exFrontItem = fFrontItem; ListData *newFrontItem = NULL; - if(preferred){ + if(preferred && fBottomItem){ int32 feel = fBottomItem->layerPtr->Window()->Feel(); // if preferred is one of these *don't* give front state to it! @@ -979,9 +1017,7 @@ STRACESTREAM(); */ //--------------------------------------------------------------------------- void Workspace::SearchAndSetNewFocus(WinBorder* preferred){ -// TODO: remove! -// return; - +STRACE(("*WS(%ld)::SASNFocus(%s)\n", ID(), preferred? preferred->GetName(): "NULL")); opLock.Lock(); if(!preferred) @@ -1052,6 +1088,38 @@ void Workspace::SearchAndSetNewFocus(WinBorder* preferred){ opLock.Unlock(); } +//--------------------------------------------------------------------------- +void Workspace::BringToFrontANormalWindow(WinBorder* layer){ + switch (layer->Window()->Feel()){ + case B_FLOATING_SUBSET_WINDOW_FEEL: + case B_MODAL_SUBSET_WINDOW_FEEL:{ + SearchAndSetNewFront(layer->MainWinBorder()); + break; + } + case B_FLOATING_APP_WINDOW_FEEL: + case B_MODAL_APP_WINDOW_FEEL:{ + opLock.Lock(); + ListData *item = fBottomItem; + team_id tid = layer->Window()->ClientTeamID(); + while(item){ + if(item->layerPtr->Window()->ClientTeamID() == tid + && item->layerPtr->Window()->Feel() == B_NORMAL_WINDOW_FEEL) + { + break; + } + item = item->upperItem; + } + if(item){ + SearchAndSetNewFront(item->layerPtr); + } + opLock.Unlock(); + break; + } + default:{ + // in case of MODAL/FLOATING_ALL or _NORMAL_ or SYSTEM_FIRST/LAST do nothing! + } + } +} /* The method moves a window to the back of its subset. */ //--------------------------------------------------------------------------- diff --git a/src/servers/app/server/Workspace.h b/src/servers/app/server/Workspace.h index 1e75df1442..aa59d45c7e 100644 --- a/src/servers/app/server/Workspace.h +++ b/src/servers/app/server/Workspace.h @@ -27,6 +27,7 @@ public: bool AddLayerPtr(WinBorder* layer); bool RemoveLayerPtr(WinBorder* layer); + bool HideSubsetWindows(WinBorder* layer); WinBorder* SetFocusLayer(WinBorder* layer); WinBorder* FocusLayer() const; WinBorder* SetFrontLayer(WinBorder* layer); @@ -60,6 +61,7 @@ public: // .... private :-) - do not use! void SearchAndSetNewFront(WinBorder* preferred); void SearchAndSetNewFocus(WinBorder* preferred); + void BringToFrontANormalWindow(WinBorder* layer); ListData* HasItem(ListData* item); ListData* HasItem(WinBorder* layer);