From 47007fb0711867af2e4beed1a95c1d3048e7fbd3 Mon Sep 17 00:00:00 2001 From: Adi Oanca Date: Wed, 14 Jan 2004 00:26:15 +0000 Subject: [PATCH] MANY improvements since yesterday! Now, we can have EVERY kind of window properly displayed in the *right* order! You can even use BWindow::AddToSubset and - it works! Also Mouse click works to change front/focus state between windows. Unfortunately window movement hasn''t yet been implemented and there are *minor* problems with the focus. That's all! If you want to see something... construct a project and use: * new BWindow() *BWindow::Show() *BWindow::AddToSubset[Of]() and link against libopenbeos.so. Ok now, bye! git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6068 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/server/AppServer.cpp | 2 + src/servers/app/server/DefaultDecorator.cpp | 154 ++++++++++++-------- src/servers/app/server/Desktop.cpp | 75 +++++++--- src/servers/app/server/Desktop.h | 4 +- src/servers/app/server/Layer.cpp | 4 +- src/servers/app/server/ServerWindow.cpp | 61 +++++--- src/servers/app/server/ServerWindow.h | 1 + src/servers/app/server/WinBorder.cpp | 56 +++++-- src/servers/app/server/Workspace.cpp | 89 ++++++++--- src/servers/app/server/Workspace.h | 7 +- 10 files changed, 310 insertions(+), 143 deletions(-) diff --git a/src/servers/app/server/AppServer.cpp b/src/servers/app/server/AppServer.cpp index 3a512969c7..98070faf10 100644 --- a/src/servers/app/server/AppServer.cpp +++ b/src/servers/app/server/AppServer.cpp @@ -520,6 +520,8 @@ void AppServer::DispatchMessage(PortMessage *msg) { srvapp = (ServerApp *)_applist->RemoveItem(i); if(srvapp){ + status_t temp; + wait_for_thread(srvapp_id, &temp); delete srvapp; srvapp = NULL; } diff --git a/src/servers/app/server/DefaultDecorator.cpp b/src/servers/app/server/DefaultDecorator.cpp index 7a1f5bc08d..235085ba3f 100644 --- a/src/servers/app/server/DefaultDecorator.cpp +++ b/src/servers/app/server/DefaultDecorator.cpp @@ -301,7 +301,17 @@ STRACE(("DefaultDecorator: Get Footprint\n")); // object's visible region. if(!region) return; + + if(_look == B_NO_BORDER_WINDOW_LOOK){ + region->Set(_frame); + return; + } + if(_look == B_BORDERED_WINDOW_LOOK){ + region->Set(_borderrect); + return; + } + region->Set(_borderrect); region->Include(_tabrect); } @@ -408,7 +418,7 @@ void DefaultDecorator::_DrawTab(BRect r) STRACE(("_DrawTab(%f,%f,%f,%f)\n", r.left, r.top, r.right, r.bottom)); // If a window has a tab, this will draw it and any buttons which are // in it. - if(_look==B_NO_BORDER_WINDOW_LOOK) + if(_look == B_NO_BORDER_WINDOW_LOOK || _look == B_BORDERED_WINDOW_LOOK) return; _layerdata.highcolor=(GetFocus())?_colors->window_tab:_colors->inactive_window_tab; @@ -443,7 +453,7 @@ STRACE(("_DrawTab(%f,%f,%f,%f)\n", r.left, r.top, r.right, r.bottom)); // Draw the buttons if we're supposed to if(!(_flags & B_NOT_CLOSABLE)) _DrawClose(_closerect); - if(!(_flags & B_NOT_ZOOMABLE)) + if(!(_flags & B_NOT_ZOOMABLE) && _look != B_MODAL_WINDOW_LOOK) _DrawZoom(_zoomrect); } @@ -531,10 +541,13 @@ STRACE(("_DrawFrame(%f,%f,%f,%f)\n", invalid.left, invalid.top, // we must clip the lines drawn by this function to the invalid rectangle we are given #ifdef USE_VIEW_FILL_HACK - _layerdata.highcolor = RGBColor( 255, 255, 255 ); + _layerdata.highcolor = RGBColor( 192, 192, 192 ); _driver->FillRect(_frame,_layerdata.highcolor); #endif + if(_look == B_NO_BORDER_WINDOW_LOOK) + return; + if(!borderwidth){ return; } @@ -798,7 +811,12 @@ STRACE(("_DrawFrame(%f,%f,%f,%f)\n", invalid.left, invalid.top, } } - _driver->StrokeLineArray(points,numlines,_layerdata.pensize,colors); + if(_feel == B_NO_BORDER_WINDOW_LOOK){ + //do(draw) nothing! + } + else{ + _driver->StrokeLineArray(points,numlines,_layerdata.pensize,colors); + } delete rightindices; delete leftindices; @@ -808,81 +826,89 @@ STRACE(("_DrawFrame(%f,%f,%f,%f)\n", invalid.left, invalid.top, { r=_resizerect; // int32 w=r.IntegerWidth(), h=r.IntegerHeight(); - + + switch(_look){ // This code is strictly for B_DOCUMENT_WINDOW looks - if(_look==B_DOCUMENT_WINDOW_LOOK) - { - r.right-=4; - r.bottom-=4; - _layerdata.highcolor=framecolors[2]; + case B_DOCUMENT_WINDOW_LOOK:{ + r.right-=4; + r.bottom-=4; + _layerdata.highcolor=framecolors[2]; - _driver->StrokeLine(r.LeftTop(),r.RightTop(),_layerdata.pensize,_layerdata.highcolor); - _driver->StrokeLine(r.LeftTop(),r.LeftBottom(),_layerdata.pensize,_layerdata.highcolor); + _driver->StrokeLine(r.LeftTop(),r.RightTop(),_layerdata.pensize,_layerdata.highcolor); + _driver->StrokeLine(r.LeftTop(),r.LeftBottom(),_layerdata.pensize,_layerdata.highcolor); - r.OffsetBy(1,1); - _layerdata.highcolor=framecolors[0]; - _driver->StrokeLine(r.LeftTop(),r.RightTop(),_layerdata.pensize,_layerdata.highcolor); - _driver->StrokeLine(r.LeftTop(),r.LeftBottom(),_layerdata.pensize,_layerdata.highcolor); + r.OffsetBy(1,1); + _layerdata.highcolor=framecolors[0]; + _driver->StrokeLine(r.LeftTop(),r.RightTop(),_layerdata.pensize,_layerdata.highcolor); + _driver->StrokeLine(r.LeftTop(),r.LeftBottom(),_layerdata.pensize,_layerdata.highcolor); - r.OffsetBy(1,1); - _layerdata.highcolor=framecolors[1]; - _driver->FillRect(r,_layerdata.highcolor); + r.OffsetBy(1,1); + _layerdata.highcolor=framecolors[1]; + _driver->FillRect(r,_layerdata.highcolor); -/* r.left+=2; - r.top+=2; - r.right-=3; - r.bottom-=3; +/* r.left+=2; + r.top+=2; + r.right-=3; + r.bottom-=3; */ - r.right-=2; - r.bottom-=2; - int32 w=r.IntegerWidth(), h=r.IntegerHeight(); + r.right-=2; + r.bottom-=2; + int32 w=r.IntegerWidth(), h=r.IntegerHeight(); - rgb_color halfcol, startcol, endcol; - float rstep,gstep,bstep,i; + rgb_color halfcol, startcol, endcol; + float rstep,gstep,bstep,i; - int steps=(wLock(); - for(i=0;i<=steps; i++) - { - _layerdata.highcolor.SetColor(uint8(startcol.red-(i*rstep)), - uint8(startcol.green-(i*gstep)), - uint8(startcol.blue-(i*bstep))); + // Explicitly locking the driver is normally unnecessary. However, we need to do + // this because we are rapidly drawing a series of calls which would not necessarily + // draw correctly if we didn't do so. + _driver->Lock(); + for(i=0;i<=steps; i++) + { + _layerdata.highcolor.SetColor(uint8(startcol.red-(i*rstep)), + uint8(startcol.green-(i*gstep)), + uint8(startcol.blue-(i*bstep))); - _driver->StrokeLine(BPoint(r.left,r.top+i), - BPoint(r.left+i,r.top),_layerdata.pensize,_layerdata.highcolor); + _driver->StrokeLine(BPoint(r.left,r.top+i), + BPoint(r.left+i,r.top),_layerdata.pensize,_layerdata.highcolor); - _layerdata.highcolor.SetColor(uint8(halfcol.red-(i*rstep)), - uint8(halfcol.green-(i*gstep)), - uint8(halfcol.blue-(i*bstep))); - _driver->StrokeLine(BPoint(r.left+steps,r.top+i), - BPoint(r.left+i,r.top+steps),_layerdata.pensize,_layerdata.highcolor); + _layerdata.highcolor.SetColor(uint8(halfcol.red-(i*rstep)), + uint8(halfcol.green-(i*gstep)), + uint8(halfcol.blue-(i*bstep))); + _driver->StrokeLine(BPoint(r.left+steps,r.top+i), + BPoint(r.left+i,r.top+steps),_layerdata.pensize,_layerdata.highcolor); + } + _driver->Unlock(); +// _layerdata.highcolor=framecolors[4]; +// _driver->StrokeRect(r,_layerdata.pensize,_layerdata.highcolor); + break; + } + + case B_TITLED_WINDOW_LOOK: + case B_FLOATING_WINDOW_LOOK:{ + _layerdata.highcolor=framecolors[2]; + _driver->StrokeLine(BPoint(r.right-4,r.top),BPoint(r.right-2,r.top), + _layerdata.pensize,_layerdata.highcolor); + _driver->StrokeLine(BPoint(r.left,r.bottom-4),BPoint(r.left,r.bottom-2), + _layerdata.pensize,_layerdata.highcolor); + + break; + } + + default:{ + // draw no resize corner + break; } - _driver->Unlock(); -// _layerdata.highcolor=framecolors[4]; -// _driver->StrokeRect(r,_layerdata.pensize,_layerdata.highcolor); - } - else - { - _layerdata.highcolor=framecolors[2]; - _driver->StrokeLine(BPoint(r.right-4,r.top),BPoint(r.right-2,r.top), - _layerdata.pensize,_layerdata.highcolor); - _driver->StrokeLine(BPoint(r.left,r.bottom-4),BPoint(r.left,r.bottom-2), - _layerdata.pensize,_layerdata.highcolor); } } - - } diff --git a/src/servers/app/server/Desktop.cpp b/src/servers/app/server/Desktop.cpp index ec31a7fd8a..a11fd25ab9 100644 --- a/src/servers/app/server/Desktop.cpp +++ b/src/servers/app/server/Desktop.cpp @@ -136,10 +136,11 @@ void Desktop::SetActiveRootLayer(RootLayer* rl){ return; fActiveRootLayer = rl; - + +// TODO: fix!!!!!!!!!!!!!!!!!!!!!!!! or not? // also set he new front and focus - SetFrontWinBorder(fActiveRootLayer->ActiveWorkspace()->FrontLayer()); - SetFocusWinBorder(fActiveRootLayer->ActiveWorkspace()->FocusLayer()); +// SetFrontWinBorder(fActiveRootLayer->ActiveWorkspace()->FrontLayer()); +// SetFocusWinBorder(fActiveRootLayer->ActiveWorkspace()->FocusLayer()); // TODO: other tasks required when this happens. I don't know them now. // Rebuild & Invalidate @@ -195,9 +196,10 @@ void Desktop::AddWinBorder(WinBorder* winBorder){ fLayerLock.Lock(); fWinBorderList.AddItem(winBorder); fLayerLock.Unlock(); - - SetFrontWinBorder(fActiveRootLayer->ActiveWorkspace()->FrontLayer()); - SetFocusWinBorder(fActiveRootLayer->ActiveWorkspace()->FocusLayer()); + +// TODO: remove those 2? I vote for: YES! still... have to think... +// SetFrontWinBorder(fActiveRootLayer->ActiveWorkspace()->FrontLayer()); +// SetFocusWinBorder(fActiveRootLayer->ActiveWorkspace()->FocusLayer()); } //--------------------------------------------------------------------------- void Desktop::RemoveWinBorder(WinBorder* winBorder){ @@ -209,10 +211,11 @@ void Desktop::RemoveWinBorder(WinBorder* winBorder){ winBorder->GetRootLayer()->RemoveWinBorder(winBorder); } - if (winBorder == fFrontWinBorder) - SetFrontWinBorder(fActiveRootLayer->ActiveWorkspace()->FrontLayer()); - if (winBorder == fFocusWinBorder) - SetFocusWinBorder(fActiveRootLayer->ActiveWorkspace()->FocusLayer()); +// TODO: remove those 4? I vote for: YES! still... have to think... +// if (winBorder == fFrontWinBorder) +// SetFrontWinBorder(fActiveRootLayer->ActiveWorkspace()->FrontLayer()); +// if (winBorder == fFocusWinBorder) +// SetFocusWinBorder(fActiveRootLayer->ActiveWorkspace()->FocusLayer()); fLayerLock.Lock(); fWinBorderList.RemoveItem(winBorder); @@ -228,10 +231,12 @@ void Desktop::SetFrontWinBorder(WinBorder* winBorder){ // TODO: implement } //--------------------------------------------------------------------------- -void Desktop::SetFocusWinBorder(WinBorder* winBorder){ - if (fFocusWinBorder == winBorder && (winBorder && !winBorder->IsHidden())) +void Desktop::SetFoocusWinBorder(WinBorder* winBorder){ + if (FocusWinBorder() == winBorder && (winBorder && !winBorder->IsHidden())) return; + fFocusWinBorder = FocusWinBorder(); + // NOTE: we assume both, the old and new focus layer are in the active workspace WinBorder *newFocus = NULL; @@ -240,8 +245,26 @@ void Desktop::SetFocusWinBorder(WinBorder* winBorder){ } if(winBorder){ +// TODO: NO! this call is to determine the correct order! NOT to rebuild/redraw anything! +// TODO: WinBorder::SetFront... will do that - both! +// TODO: modify later +// TODO: same applies for the focus state - RootLayer::SetFocus also does redraw +// Workspace::SetFocus - Only determines the focus! Just like above! +/* newFocus = winBorder->GetRootLayer()->ActiveWorkspace()->SetFocusLayer(winBorder); newFocus->SetFocus(true); +*/ + Workspace *aws; + + aws = winBorder->GetRootLayer()->ActiveWorkspace(); + aws->SearchAndSetNewFocus(winBorder); + + //why do put this line? Eh... I will remove it later... + newFocus = aws->FocusLayer(); + + aws->FocusLayer()->SetFocus(true); + + aws->Invalidate(); } fFocusWinBorder = newFocus; @@ -253,8 +276,8 @@ WinBorder* Desktop::FrontWinBorder(void) const{ } //--------------------------------------------------------------------------- WinBorder* Desktop::FocusWinBorder(void) const{ -// return fActiveRootLayer->ActiveWorkspace()->FocusLayer(); - return fFocusWinBorder; + return fActiveRootLayer->ActiveWorkspace()->FocusLayer(); +// return fFocusWinBorder; } // Input related methods @@ -285,21 +308,17 @@ void Desktop::MouseEventHandler(PortMessage *msg){ ws = rl->ActiveWorkspace(); target = ws->SearchLayerUnderPoint(pt); if (target){ - printf("\t '%s' was selected.\n", target->GetName()); fGeneralLock.Lock(); rl->fMainLock.Lock(); - - ws->SetFrontLayer(target); - SetFocusWinBorder(target); -// TODO: improve! - rl->Invalidate(rl->Bounds()); - + ws->SearchAndSetNewFront(target); +// NOTE: !!! Be VERY careful about this method !!!! + SetFoocusWinBorder(target); + //ws->SetFocusLayer(target); rl->fMainLock.Unlock(); fGeneralLock.Unlock(); } - break; } case B_MOUSE_UP:{ @@ -430,6 +449,18 @@ void Desktop::PrintToStream(){ } //--------------------------------------------------------------------------- +WinBorder* Desktop::FindWinBorderByServerWindowToken(int32 token){ + WinBorder* wb; + fLayerLock.Lock(); + for (int32 i = 0; (wb = (WinBorder*)fWinBorderList.ItemAt(i)); i++){ + if (wb->Window()->ClientToken() == token) + break; + } + fLayerLock.Unlock(); + + return wb; +} +//--------------------------------------------------------------------------- void Desktop::PrintVisibleInRootLayerNo(int32 no){ if (no<0 || no>=fRootLayerList.CountItems()) return; diff --git a/src/servers/app/server/Desktop.h b/src/servers/app/server/Desktop.h index 97ffa956aa..117e4f46cd 100644 --- a/src/servers/app/server/Desktop.h +++ b/src/servers/app/server/Desktop.h @@ -41,7 +41,7 @@ public: void RemoveWinBorder(WinBorder* winBorder); bool HasWinBorder(WinBorder* winBorder); void SetFrontWinBorder(WinBorder* winBorder); - void SetFocusWinBorder(WinBorder* winBorder); + void SetFoocusWinBorder(WinBorder* winBorder); WinBorder* FrontWinBorder(void) const; WinBorder* FocusWinBorder(void) const; @@ -74,6 +74,8 @@ public: // "Private" to app_server :-) - means they should not be used very much void RemoveSubsetWindow(WinBorder* wb); + WinBorder* FindWinBorderByServerWindowToken(int32 token); + BLocker fGeneralLock; BLocker fLayerLock; BList fWinBorderList; diff --git a/src/servers/app/server/Layer.cpp b/src/servers/app/server/Layer.cpp index 43a76315cc..451e0d867c 100644 --- a/src/servers/app/server/Layer.cpp +++ b/src/servers/app/server/Layer.cpp @@ -152,8 +152,6 @@ void Layer::AddChild(Layer *layer, RootLayer *rootLayer) } _bottomchild = layer; - layer->_level = _level+1; - layer->RebuildFullRegion(); @@ -1079,7 +1077,7 @@ void Layer::PrintToStream(void) else printf("Bottom child: NULL\n"); printf("Frame: "); _frame.PrintToStream(); - printf("Token: %ld\nLevel: %ld\n",_view_token, _level); + printf("Token: %ld\n",_view_token); printf("Hide count: %s\n",_hidden?"true":"false"); printf("Visible Areas: "); _visible.PrintToStream(); printf("Is updating = %s\n",(_is_updating)?"yes":"no"); diff --git a/src/servers/app/server/ServerWindow.cpp b/src/servers/app/server/ServerWindow.cpp index 400ad6fd30..3e9b06904f 100644 --- a/src/servers/app/server/ServerWindow.cpp +++ b/src/servers/app/server/ServerWindow.cpp @@ -292,22 +292,23 @@ void ServerWindow::Show(void) STRACE(("ServerWindow %s: Show\n",_title->String())); if(_winborder) { - desktop->fGeneralLock.Lock(); - _winborder->Show(); - desktop->fGeneralLock.Unlock(); - RootLayer *rl = _winborder->GetRootLayer(); desktop->fGeneralLock.Lock(); printf("ServerWindow(%s)::Show() - General lock acquired\n", _winborder->GetName()); rl->fMainLock.Lock(); printf("ServerWindow(%s)::Show() - Main lock acquired\n", _winborder->GetName()); + + _winborder->Show(); + int32 wksCount= rl->WorkspaceCount(); for(int32 i = 0; i < wksCount; i++){ - if (fWorkspaces & (0x00000001UL << i)) - rl->WorkspaceAt(i+1)->SetFrontLayer(_winborder); + if (fWorkspaces & (0x00000001UL << i)){ + Workspace *ws = rl->WorkspaceAt(i+1); + ws->SearchAndSetNewFront(_winborder); + ws->SetFocusLayer(_winborder); + } } - desktop->SetFocusWinBorder(_winborder); rl->fMainLock.Unlock(); printf("ServerWindow(%s)::Show() - Main lock released\n", _winborder->GetName()); desktop->fGeneralLock.Unlock(); @@ -320,25 +321,36 @@ void ServerWindow::Hide(void) { STRACE(("ServerWindow %s: Hide\n",_title->String())); if(_winborder){ - desktop->fGeneralLock.Lock(); - _winborder->Hide(); - desktop->fGeneralLock.Unlock(); - RootLayer *rl = _winborder->GetRootLayer(); Workspace *ws = NULL; + desktop->fGeneralLock.Lock(); +printf("ServerWindow(%s)::Hide() - General lock acquired\n", _winborder->GetName()); rl->fMainLock.Lock(); +printf("ServerWindow(%s)::Hide() - Main lock acquired\n", _winborder->GetName()); + + _winborder->Hide(); + int32 wksCount= rl->WorkspaceCount(); for(int32 i = 0; i < wksCount; i++){ ws = rl->WorkspaceAt(i+1); if ( ws->FrontLayer() == _winborder){ - ws->SetFrontLayer(_winborder); + if(ws->FocusLayer() == _winborder){ + // do not redraw! just set the new front. + ws->SearchAndSetNewFront(_winborder); + // redraw also + ws->SetFocusLayer(_winborder); + } + else{ + // redraw also + ws->SetFrontLayer(_winborder); + } } } - - if(desktop->FocusWinBorder() == _winborder) - desktop->SetFocusWinBorder(_winborder); rl->fMainLock.Unlock(); +printf("ServerWindow(%s)::Hide() - Main lock released\n", _winborder->GetName()); + desktop->fGeneralLock.Unlock(); +printf("ServerWindow(%s)::Hide() - General lock released\n", _winborder->GetName()); } } @@ -1358,8 +1370,24 @@ TODO: Figure out what Adi did here and convert to PortMessages } case AS_ADD_TO_SUBSET: { + WinBorder *wb; + int32 mainToken; + + ses->ReadInt32(&mainToken); + + wb = desktop->FindWinBorderByServerWindowToken(mainToken); + if(wb){ + ses->WriteInt32(SERVER_TRUE); + ses->Sync(); + + _winborder->AddToSubsetOf(wb); + } + else{ + ses->WriteInt32(SERVER_FALSE); + ses->Sync(); + } // TODO: Implement - STRACE(("ServerWindow %s: Message Add_To_Subset unimplemented\n",_title->String())); + STRACE(("\n\n\n\n\n\nServerWindow %s: Message ADD_TO_SUBSET unimplemented\n",_title->String())); break; } case AS_REM_FROM_SUBSET: @@ -2011,7 +2039,6 @@ int32 ServerWindow::MonitorWin(void *data) { code = 0; win->ses->ReadInt32(&code); - switch(code){ // this means the client has been killed case 0:{ diff --git a/src/servers/app/server/ServerWindow.h b/src/servers/app/server/ServerWindow.h index 89ff0413ac..3ba83c1966 100644 --- a/src/servers/app/server/ServerWindow.h +++ b/src/servers/app/server/ServerWindow.h @@ -129,6 +129,7 @@ public: { fWorkspaces = wks; } void QuietlySetFeel(int32 feel) { _feel = feel; } + int32 ClientToken() const { return _handlertoken; } FMWList fWinFMWList; protected: diff --git a/src/servers/app/server/WinBorder.cpp b/src/servers/app/server/WinBorder.cpp index d970c20931..eb4a48dba7 100644 --- a/src/servers/app/server/WinBorder.cpp +++ b/src/servers/app/server/WinBorder.cpp @@ -721,19 +721,40 @@ void WinBorder::AddToSubsetOf(WinBorder* main){ // because this window is in a subset it should appear in the // workspaces its main window appears in. Window()->QuietlySetWorkspaces(main->Window()->Workspaces()); - // this is a *modal* window, so add it to workspaces. - if ( !(main->IsHidden()) && Window()->Feel() == B_MODAL_SUBSET_WINDOW_FEEL){ - main->GetRootLayer()->AddWinBorderToWorkspaces(this, main->Window()->Workspaces()); + // this is a *modal* window, so add it to main windows workspaces. + if (Window()->Feel() == B_MODAL_SUBSET_WINDOW_FEEL){ + RootLayer *rl = main->GetRootLayer(); + rl->fMainLock.Lock(); + rl->AddWinBorderToWorkspaces(this, main->Window()->Workspaces()); + rl->fMainLock.Unlock(); } // this a *floating* window so if the main window is 'front', - // add it to the current workspace. + // add it to workspace. if ( !(main->IsHidden()) && Window()->Feel() == B_FLOATING_SUBSET_WINDOW_FEEL){ - int32 count = main->GetRootLayer()->WorkspaceCount(); - for(int32 i=0; i < count; i++){ - Workspace *ws = main->GetRootLayer()->WorkspaceAt(i+1); - if(ws->FrontLayer() == main) + RootLayer *rl = main->GetRootLayer(); + + desktop->fGeneralLock.Lock(); +printf("WinBorder(%s)::AddToSubsetOf() - General lock acquired\n", GetName()); + rl->fMainLock.Lock(); +printf("WinBorder(%s)::AddToSubsetOf() - Main lock acquired\n", GetName()); + for(int32 i = 0; i < rl->WorkspaceCount(); i++){ + Workspace *ws = rl->WorkspaceAt(i+1); + if(ws->FrontLayer() == main){ +printf("\n@\n@\n"); +ws->PrintToStream(); ws->AddLayerPtr(this); + if(rl->ActiveWorkspace() == ws && !IsHidden()){ + ws->Invalidate(); +printf("\n#\n#\n"); +ws->PrintToStream(); +printf("\n#\n#\n"); + } + } } + rl->fMainLock.Unlock(); +printf("WinBorder(%s)::AddToSubsetOf() - Main lock released\n", GetName()); + desktop->fGeneralLock.Unlock(); +printf("WinBorder(%s)::AddToSubsetOf() - General lock released\n", GetName()); } } } @@ -757,7 +778,7 @@ void WinBorder::RemoveFromSubsetOf(WinBorder* main){ //--------------------------------------------------------------------------- void WinBorder::PrintToStream(){ printf("\t%s", GetName()); - if (Window()->Feel() == B_FLOATING_SUBSET_WINDOW_FEEL) +/* if (Window()->Feel() == B_FLOATING_SUBSET_WINDOW_FEEL) printf("\t%s", "B_FLOATING_SUBSET_WINDOW_FEEL"); if (Window()->Feel() == B_FLOATING_APP_WINDOW_FEEL) printf("\t%s", "B_FLOATING_APP_WINDOW_FEEL"); @@ -771,9 +792,24 @@ void WinBorder::PrintToStream(){ printf("\t%s", "B_MODAL_ALL_WINDOW_FEEL"); if (Window()->Feel() == B_NORMAL_WINDOW_FEEL) printf("\t%s", "B_NORMAL_WINDOW_FEEL"); +*/ + if (_level == B_FLOATING_SUBSET_FEEL) + printf("\t%s", "B_FLOATING_SUBSET_WINDOW_FEEL"); + if (_level == B_FLOATING_APP_FEEL) + printf("\t%s", "B_FLOATING_APP_WINDOW_FEEL"); + if (_level == B_FLOATING_ALL_FEEL) + printf("\t%s", "B_FLOATING_ALL_WINDOW_FEEL"); + if (_level == B_MODAL_SUBSET_FEEL) + printf("\t%s", "B_MODAL_SUBSET_WINDOW_FEEL"); + if (_level == B_MODAL_APP_FEEL) + printf("\t%s", "B_MODAL_APP_WINDOW_FEEL"); + if (_level == B_MODAL_ALL_FEEL) + printf("\t%s", "B_MODAL_ALL_WINDOW_FEEL"); + if (_level == B_NORMAL_FEEL) + printf("\t%s", "B_NORMAL_WINDOW_FEEL"); printf("\t%s\n", _hidden?"hidden" : "not hidden"); - _full.PrintToStream(); +// _full.PrintToStream(); } //--------------------------------------------------------------------------- void WinBorder::UpdateColors(void) diff --git a/src/servers/app/server/Workspace.cpp b/src/servers/app/server/Workspace.cpp index 56f279230c..04540376b0 100644 --- a/src/servers/app/server/Workspace.cpp +++ b/src/servers/app/server/Workspace.cpp @@ -76,16 +76,20 @@ bool Workspace::AddLayerPtr(WinBorder* layer){ item->upperItem = NULL; item->lowerItem = NULL; + opLock.Lock(); // insert 'item' at the end. It doesn't matter where we add it, // it will be placed correctly by SearchAndSetNewFront(item->layerPtr); InsertItem(item, NULL); + opLock.Unlock(); STRACE(("\n*AddLayerPtr(%s) -", layer->GetName())); // do a *smart* search and set the new 'front' SearchAndSetNewFront(layer); // do a *smart* search and set the new 'focus' - SearchAndSetNewFocus(layer); -//STRACESTREAM(); + //SearchAndSetNewFocus(layer); // - it WILL be called! + // this also does a redraw + SetFocusLayer(layer); + return true; } /* Removes a WinBorder from workspace's list. It DOES NOT delete it! @@ -101,6 +105,8 @@ STRACE(("BEFORE ANY opperation:\n")); STRACESTREAM(); // 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; bool wasFront, wasFocus; @@ -123,29 +129,45 @@ STRACESTREAM(); // remove from workspace's list RemoveItem(item); + 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) - SearchAndSetNewFront(nextItem? nextItem->layerPtr: NULL); + if (wasFront){ + if(wasFocus){ + SearchAndSetNewFront(nextItem? nextItem->layerPtr: NULL); + SetFocusLayer(nextItem? nextItem->layerPtr: NULL); + } + else + SetFrontLayer(nextItem? nextItem->layerPtr: NULL); + } - if (wasFocus) - SearchAndSetNewFocus(nextItem? nextItem->layerPtr: NULL); + if (wasFocus && !wasFront) + SetFocusLayer(nextItem? nextItem->layerPtr: NULL); STRACE(("AFTER opperations...\n")); STRACESTREAM(); + // delete item struct, we no longer need that delete item; return true; } else{ printf("Layer %s NOT found in Workspace No %ld\n", layer->GetName(), ID()); + opLock.Unlock(); return false; } } //--------------------------------------------------------------------------- WinBorder* Workspace::SetFocusLayer(WinBorder* layer){ +STRACE(("\n@Workspace(%ld)::SetFOCUSLayer( %s )\n", ID(), layer? layer->GetName(): "NULL")); + SearchAndSetNewFocus(layer); +STRACESTREAM(); +// TODO: there had to be a Invalidate() vresion witch takes a BRegion parameter + Invalidate(); + return fFocusItem? fFocusItem->layerPtr : NULL; } //--------------------------------------------------------------------------- @@ -156,12 +178,9 @@ WinBorder* Workspace::FocusLayer() const{ WinBorder* Workspace::SetFrontLayer(WinBorder* layer){ STRACE(("\n@Workspace(%ld)::SetFrontLayer( %s )\n", ID(), layer? layer->GetName(): "NULL")); SearchAndSetNewFront(layer); -//TODO: *****!*!*!*!*!*!*!**!***REMOVE this! For Test purposes only! - if(fOwner->ActiveWorkspace() == this) - fOwner->DoInvalidate(BRegion(fOwner->Bounds()), NULL); -//---------------- - -// TODO: if (desktop->FrontWinBorder() != layer) REBUILD & INVALIDATE! +STRACESTREAM(); +// TODO: there had to be a Invalidate() vresion witch takes a BRegion parameter + Invalidate(); return fFrontItem? fFrontItem->layerPtr: NULL;; } @@ -233,6 +252,13 @@ printf("%s - SELECTED!\n", wb->GetName()); return target; } //--------------------------------------------------------------------------- +void Workspace::Invalidate(){ +//TODO: *****!*!*!*!*!*!*!**!***REMOVE this! For Test purposes only! + if(fOwner->ActiveWorkspace() == this) + fOwner->DoInvalidate(BRegion(fOwner->Bounds()), NULL); +//---------------- +} +//--------------------------------------------------------------------------- void Workspace::InsertItem(ListData* item, ListData* before){ // insert before one other item; if (before){ @@ -469,6 +495,8 @@ STRACE(("#WS(%ld)::SASNF(%s) ENDED 1\n", ID(), preferred? preferred->GetName(): ListData *lastInserted; lastInserted = FindPlace(HasItem(preferred)); preferred = lastInserted? lastInserted->layerPtr: NULL; +STRACE(("-WS(%ld)::SASNF(%s) - after FindPlace...", ID(), preferred? preferred->GetName(): "NULL")); +STRACESTREAM(); // if the new front layer is the same... there is no point continuing if(fFrontItem == lastInserted){ @@ -538,6 +566,8 @@ STRACE((" SAME TeamID\n")); listItem = listItem->lowerItem; RemoveItem(item); } + else + listItem = listItem->lowerItem; } else listItem = listItem->lowerItem; @@ -551,6 +581,7 @@ STRACE((" SAME TeamID\n")); else finalFMWList.AddItem(item); } + // colapse the 2 lists finalFMWList.AddFMWList(&commonFMW); finalFMWList.AddFMWList(&appFMW); @@ -913,13 +944,13 @@ void Workspace::SearchAndSetNewFocus(WinBorder* preferred){ bool selectOthers = false; ListData *item = NULL; + for(item = fBottomItem; item != NULL; item = item->upperItem){ // if this WinBorder doesn't want to have focus... get to the next one if (item->layerPtr->Window()->Flags() & B_AVOID_FOCUS) continue; - // this means there is no modal window before our preferred one. - if (item->layerPtr == preferred) + if (preferred && item->layerPtr == preferred){ // our preffered one is hidden so... select another one if (preferred && preferred->IsHidden()){ selectOthers = true; @@ -928,24 +959,34 @@ void Workspace::SearchAndSetNewFocus(WinBorder* preferred){ else{ break; } + } + + if (item->layerPtr->_level == B_SYSTEM_FIRST || item->layerPtr->_level == B_MODAL_ALL_FEEL) + { + break; + } + + if (item->layerPtr->_level == B_MODAL_APP_FEEL + && (preferred && preferred->Window()->ClientTeamID() == item->layerPtr->Window()->ClientTeamID())) + { + break; + } + + if (item->layerPtr->_level == B_MODAL_SUBSET_FEEL + && (preferred && item->layerPtr->MainWinBorder() == preferred)) + { + break; + } // select one window, other than a system_last one! - if (selectOthers && item->layerPtr->_level != B_SYSTEM_LAST) - break; - - // we now chose a modal window to give focus to - if (item->layerPtr->_level == B_SYSTEM_FIRST - || item->layerPtr->_level == B_MODAL_ALL_FEEL - || item->layerPtr->_level == B_MODAL_APP_FEEL - || item->layerPtr->_level == B_MODAL_SUBSET_FEEL) - { + if (selectOthers && item->layerPtr->_level != B_SYSTEM_LAST){ break; } } // there are no windows below us to select. take the one from above us. if(selectOthers && !item){ - // there HAS to be a + // there HAS to be valid item = HasItem(preferred); if (item) item= item->lowerItem; diff --git a/src/servers/app/server/Workspace.h b/src/servers/app/server/Workspace.h index 8053afc2cd..9c6c38c3c2 100644 --- a/src/servers/app/server/Workspace.h +++ b/src/servers/app/server/Workspace.h @@ -41,6 +41,7 @@ public: bool GoToItem(WinBorder* layer); WinBorder* SearchLayerUnderPoint(BPoint pt); + void Invalidate(); void SetLocalSpace(const uint32 colorspace); uint32 LocalSpace() const; @@ -56,6 +57,10 @@ public: void PrintToStream() const; void PrintItem(ListData *item) const; +// .... private :-) - do not use! + void SearchAndSetNewFront(WinBorder* preferred); + void SearchAndSetNewFocus(WinBorder* preferred); + private: void InsertItem(ListData* item, ListData* before); @@ -64,8 +69,6 @@ private: ListData* HasItem(WinBorder* layer); ListData* FindPlace(ListData* pref); - void SearchAndSetNewFront(WinBorder* preferred); - void SearchAndSetNewFocus(WinBorder* preferred); int32 fID; uint32 fSpace;