diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index e58f1e9541..490165defc 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -419,6 +419,21 @@ void Desktop::RemoveWinBorderFromSubset(WinBorder *winBorder, WinBorder *fromWin Unlock(); } +void Desktop::SetWinBorderFeel(WinBorder *winBorder, uint32 feel) +{ + // NOTE: this method is called from RootLayer thread only + + // we're playing with window list. lock first. + Lock(); + + RemoveWinBorder(winBorder); + winBorder->QuietlySetFeel(feel); + AddWinBorder(winBorder); + + // unlock! + Unlock(); +} + WinBorder* Desktop::FindWinBorderByServerWindowTokenAndTeamID(int32 token, team_id teamID) { WinBorder* wb; diff --git a/src/servers/app/Desktop.h b/src/servers/app/Desktop.h index 54319916dc..e581960334 100644 --- a/src/servers/app/Desktop.h +++ b/src/servers/app/Desktop.h @@ -67,6 +67,7 @@ public: // Methods for layer(WinBorder) manipulation. void AddWinBorder(WinBorder *winBorder); void RemoveWinBorder(WinBorder *winBorder); + void SetWinBorderFeel(WinBorder *winBorder, uint32 feel); void AddWinBorderToSubset(WinBorder *winBorder, WinBorder *toWinBorder); void RemoveWinBorderFromSubset(WinBorder *winBorder, WinBorder *fromWinBorder); diff --git a/src/servers/app/Layer.cpp b/src/servers/app/Layer.cpp index 2044a9264f..ba6b26d1e3 100644 --- a/src/servers/app/Layer.cpp +++ b/src/servers/app/Layer.cpp @@ -104,7 +104,6 @@ Layer::Layer(BRect frame, const char *name, int32 token, uint32 resize, fEventMask = 0UL; fEventOptions = 0UL; fIsTopLayer = false; - fLevel = -100; fViewToken = token; fServerWin = NULL; diff --git a/src/servers/app/Layer.h b/src/servers/app/Layer.h index 72cdfcee68..717eec929b 100644 --- a/src/servers/app/Layer.h +++ b/src/servers/app/Layer.h @@ -131,7 +131,6 @@ public: ServerApp *App(void) const { return fServerWin? fServerWin->App(): NULL; } virtual bool HasClient(void) { return true; } bool IsServerLayer() const; - int32 Level() const { return fLevel; } uint32 EventMask(void) const { return fEventMask; } uint32 EventOptions(void) const { return fEventOptions; } @@ -184,7 +183,6 @@ protected: ServerWindow *fServerWin; BString *fName; int32 fViewToken; - int32 fLevel; uint32 fFlags; uint32 fResizeMode; uint32 fEventMask; diff --git a/src/servers/app/RootLayer.cpp b/src/servers/app/RootLayer.cpp index b5ed93ce1f..8faf731844 100644 --- a/src/servers/app/RootLayer.cpp +++ b/src/servers/app/RootLayer.cpp @@ -290,6 +290,16 @@ int32 RootLayer::WorkingThread(void *data) oneRootLayer->SetWinBorderWorskpaces(winBorder, oldWks, newWks); break; } + case AS_ROOTLAYER_DO_CHANGE_WINBORDER_FEEL: + { + WinBorder *winBorder = NULL; + int32 newFeel = 0; + + messageQueue.Read(&winBorder); + messageQueue.Read(&newFeel); + oneRootLayer->change_winBorder_feel(winBorder, newFeel); + break; + } default: STRACE(("RootLayer(%s)::WorkingThread received unexpected code %lx\n",oneRootLayer->GetName(), code)); break; @@ -347,7 +357,14 @@ void RootLayer::redraw_layer(Layer *layer, const BRegion ®ion) layer->Invalidate(region); } - +void RootLayer::GoChangeWinBorderFeel(const WinBorder *winBorder, int32 newFeel) +{ + BPortLink msg(fListenPort, -1); + msg.StartMessage(AS_ROOTLAYER_DO_CHANGE_WINBORDER_FEEL); + msg.Attach(winBorder); + msg.Attach(newFeel); + msg.Flush(); +} void RootLayer::MoveBy(float x, float y) { @@ -524,7 +541,6 @@ void RootLayer::RemoveSubsetWinBorder(WinBorder *winBorder, WinBorder *fromWinBo show_final_scene(exFocus, exActive); } - // NOTE: This must be called by RootLayer's thread!!!! bool RootLayer::SetActiveWorkspace(int32 index) { @@ -1801,6 +1817,45 @@ void RootLayer::hide_winBorder(WinBorder *winBorder) show_final_scene(exFocus, exActive); } +void RootLayer::change_winBorder_feel(WinBorder *winBorder, int32 newFeel) +{ + bool isVisible = false; + bool wasVisibleInActiveWorkspace = false; + + WinBorder *exFocus = FocusWinBorder(); + WinBorder *exActive = ActiveWinBorder(); + + if (!winBorder->IsHidden()) + { + isVisible = true; + wasVisibleInActiveWorkspace = ActiveWorkspace()->HasWinBorder(winBorder); + winBorder->Hide(false); + } + + desktop->SetWinBorderFeel(winBorder, newFeel); + + if (isVisible) + { + if (fEventMaskLayer) + { + WinBorder *wb = fEventMaskLayer->fOwner? + fEventMaskLayer->fOwner: + (WinBorder*)fEventMaskLayer; + if (wb == fEventMaskLayer) + { + fMovingWindow = false; + fResizingWindow = false; + wb->MouseUp(DEC_NONE); + } + fEventMaskLayer = NULL; + } + + winBorder->Show(false); + if (wasVisibleInActiveWorkspace || ActiveWorkspace()->HasWinBorder(winBorder)) + show_final_scene(exFocus, exActive); + } +} + bool RootLayer::get_workspace_windows() { int32 bufferSize = fWinBorderListLength; diff --git a/src/servers/app/RootLayer.h b/src/servers/app/RootLayer.h index 035d8210af..b435e80623 100644 --- a/src/servers/app/RootLayer.h +++ b/src/servers/app/RootLayer.h @@ -119,6 +119,7 @@ public: status_t EnqueueMessage(BPortLink &message); void GoInvalidate(const Layer *layer, const BRegion ®ion); void GoRedraw(const Layer *layer, const BRegion ®ion); + void GoChangeWinBorderFeel(const WinBorder *winBorder, int32 newFeel); // Debug methods void PrintToStream(void); @@ -140,6 +141,8 @@ friend class Desktop; void show_winBorder(WinBorder* winBorder); void hide_winBorder(WinBorder* winBorder); + void change_winBorder_feel(WinBorder *winBorder, int32 newFeel); + bool get_workspace_windows(); void draw_window_tab(WinBorder *exFocus); void empty_visible_regions(Layer *layer); diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 290f5b0791..200cd5d96e 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -1368,8 +1368,10 @@ cl->fBoundsLeftTop.PrintToStream(); } case AS_SET_FEEL: { - // TODO: Implement AS_SET_FEEL - STRACE(("ServerWindow %s: Message Set_Feel unimplemented\n",fName)); + STRACE(("ServerWindow %s: Message AS_SET_FEEL\n",fName)); + int32 newFeel; + link.Read(&newFeel); + myRootLayer->GoChangeWinBorderFeel(fWinBorder, newFeel); break; } case AS_SET_ALIGNMENT: diff --git a/src/servers/app/WinBorder.cpp b/src/servers/app/WinBorder.cpp index 522c304724..bec78c6022 100644 --- a/src/servers/app/WinBorder.cpp +++ b/src/servers/app/WinBorder.cpp @@ -87,7 +87,7 @@ WinBorder::WinBorder( const BRect &r, DisplayDriver *driver) : Layer(r, name, B_NULL_TOKEN, B_FOLLOW_NONE, 0UL, driver), fLook(wlook), - fFeel(wfeel), + fLevel(-100), fWindowFlags(wflags), fWorkspaces(wwksindex) { @@ -110,30 +110,8 @@ cnt = 0; // for debugging fIsMinimizing = false; fIsZooming = false; - // floating and modal windows must appear in every workspace where - // their main window is present. Thus their wksIndex will be set to - // '0x0' and they will be made visible when needed. - switch (fFeel) - { - case B_MODAL_APP_WINDOW_FEEL: - case B_MODAL_SUBSET_WINDOW_FEEL: - case B_FLOATING_APP_WINDOW_FEEL: - case B_FLOATING_SUBSET_WINDOW_FEEL: - fWorkspaces = 0x0UL; - break; - case B_MODAL_ALL_WINDOW_FEEL: - case B_FLOATING_ALL_WINDOW_FEEL: - case B_SYSTEM_LAST: - case B_SYSTEM_FIRST: - fWorkspaces = 0xffffffffUL; - break; - case B_NORMAL_WINDOW_FEEL: - if (fWorkspaces == 0x0UL) - ; - } - fLastMousePosition.Set(-1,-1); - SetLevel(); + QuietlySetFeel(wfeel); if (fFeel != B_NO_BORDER_WINDOW_LOOK) fDecorator = new_decorator(r, name, fLook, fFeel, fWindowFlags, fDriver); @@ -401,9 +379,10 @@ void WinBorder::UpdateScreen(void) STRACE(("WinBorder %s: UpdateScreen unimplemented\n",GetName())); } -//--------------------- P R I V A T E ------------------- -void WinBorder::SetLevel() +void WinBorder::QuietlySetFeel(int32 feel) { + fFeel = feel; + switch(fFeel) { case B_FLOATING_SUBSET_WINDOW_FEEL: @@ -439,4 +418,26 @@ void WinBorder::SetLevel() default: fLevel = B_NORMAL; } -} \ No newline at end of file + + // floating and modal windows must appear in every workspace where + // their main window is present. Thus their wksIndex will be set to + // '0x0' and they will be made visible when needed. + switch (fFeel) + { + case B_MODAL_APP_WINDOW_FEEL: + case B_MODAL_SUBSET_WINDOW_FEEL: + case B_FLOATING_APP_WINDOW_FEEL: + case B_FLOATING_SUBSET_WINDOW_FEEL: + fWorkspaces = 0x0UL; + break; + case B_MODAL_ALL_WINDOW_FEEL: + case B_FLOATING_ALL_WINDOW_FEEL: + case B_SYSTEM_LAST: + case B_SYSTEM_FIRST: + fWorkspaces = 0xffffffffUL; + break; + case B_NORMAL_WINDOW_FEEL: + if (fWorkspaces == 0x0UL) + ; + } +} diff --git a/src/servers/app/WinBorder.h b/src/servers/app/WinBorder.h index d969a47f1b..5b11353c11 100644 --- a/src/servers/app/WinBorder.h +++ b/src/servers/app/WinBorder.h @@ -105,6 +105,7 @@ public: inline int32 Look(void) const { return fLook; } inline int32 Feel(void) const { return fFeel; } + inline int32 Level() const { return fLevel; } inline uint32 WindowFlags(void) const { return fWindowFlags; } inline uint32 Workspaces(void) const { return fWorkspaces; } @@ -113,12 +114,10 @@ public: bool HasPoint(const BPoint &pt) const; inline void QuietlySetWorkspaces(uint32 wks) { fWorkspaces = wks; } + void QuietlySetFeel(int32 feel); FMWList fFMWList; -private: - void SetLevel(); - protected: friend class Layer; friend class ServerWindow; @@ -144,6 +143,7 @@ protected: int32 fLook; int32 fFeel; + int32 fLevel; int32 fWindowFlags; uint32 fWorkspaces;