From 42fb26b60432c0a7169622d4afd6be2aa394c9ec Mon Sep 17 00:00:00 2001 From: Adi Oanca Date: Thu, 22 Sep 2005 21:43:23 +0000 Subject: [PATCH] * changed the way we get data from the Window Manager (Workspace class for now) (there will be a WindowManager class soon). We use a simple BList now, for simplicity reasons; performance comes later :-). * added RootLayer::RevealNewWMState() which will actualise the window list and display/repaint differences between this state and the previous one, including focus. It also sends B_WINDOW_ACTIVATED as appropriate. This method removes other like get_workspace_windows(), draw_window_tab(), winborder_activation(), show_final_scene() which were a bit confussing. * ALL these changes are available under NEW_INPUT_HANDLING define which isn't active yet. Soon... git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14228 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/RootLayer.cpp | 216 ++++++++++++++++++++++++++++++++-- src/servers/app/RootLayer.h | 19 ++- src/servers/app/WinBorder.cpp | 46 +------- src/servers/app/Workspace.h | 2 +- 4 files changed, 227 insertions(+), 56 deletions(-) diff --git a/src/servers/app/RootLayer.cpp b/src/servers/app/RootLayer.cpp index c072ae0024..9ea41afce0 100644 --- a/src/servers/app/RootLayer.cpp +++ b/src/servers/app/RootLayer.cpp @@ -97,10 +97,13 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount, fWsCount(0), fWorkspace(new Workspace*[kMaxWorkspaceCount]), fWorkspacesLayer(NULL), - +#ifndef NEW_INPUT_HANDLING fWinBorderListLength(64), fWinBorderList2((WinBorder**)malloc(fWinBorderListLength * sizeof(WinBorder*))), fWinBorderList((WinBorder**)malloc(fWinBorderListLength * sizeof(WinBorder*))), +#else + fWMState(), +#endif fWinBorderCount(0), fWinBorderIndex(0), @@ -185,8 +188,11 @@ RootLayer::~RootLayer() delete fWorkspace[i]; delete[] fWorkspace; +#ifndef NEW_INPUT_HANDLING free(fWinBorderList2); free(fWinBorderList); +#endif + // RootLayer object just uses Screen objects, it is not allowed to delete them. #if DISPLAY_HAIKU_LOGO @@ -497,45 +503,63 @@ RootLayer::ResizeBy(float x, float y) Layer* RootLayer::FirstChild() const { +#ifndef NEW_INPUT_HANDLING fWinBorderIndex = fWinBorderCount - 1; if (fWinBorderIndex >= 0) return fWinBorderList[fWinBorderIndex]; return NULL; +#else + fWinBorderIndex = fWMState.WindowList.CountItems()-1; + return static_cast(fWMState.WindowList.ItemAt(fWinBorderIndex--)); +#endif } Layer* RootLayer::NextChild() const { +#ifndef NEW_INPUT_HANDLING fWinBorderIndex--; if (fWinBorderIndex < fWinBorderCount && fWinBorderIndex >= 0) return fWinBorderList[fWinBorderIndex]; return NULL; +#else + return static_cast(fWMState.WindowList.ItemAt(fWinBorderIndex--)); +#endif } Layer* RootLayer::PreviousChild() const { +#ifndef NEW_INPUT_HANDLING fWinBorderIndex++; if (fWinBorderIndex < fWinBorderCount && fWinBorderIndex >= 0) return fWinBorderList[fWinBorderIndex]; return NULL; +#else + return static_cast(fWMState.WindowList.ItemAt(fWinBorderIndex++)); +#endif } Layer* RootLayer::LastChild() const { +#ifndef NEW_INPUT_HANDLING fWinBorderIndex = 0; if (fWinBorderIndex < fWinBorderCount) return fWinBorderList[fWinBorderIndex]; return NULL; +#else + fWinBorderIndex = 0; + return static_cast(fWMState.WindowList.ItemAt(fWinBorderIndex++)); +#endif } @@ -625,9 +649,13 @@ RootLayer::AddSubsetWinBorder(WinBorder *winBorder, WinBorder *toWinBorder) bool invalidate = false; bool invalid; +#ifndef NEW_INPUT_HANDLING WinBorder* exFocus = FocusWinBorder(); WinBorder* exActive = ActiveWinBorder(); - +#else + Workspace::State oldWMState; + ActiveWorkspace()->GetState(&oldWMState); +#endif // 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++) { @@ -641,7 +669,11 @@ RootLayer::AddSubsetWinBorder(WinBorder *winBorder, WinBorder *toWinBorder) } if (invalidate) +#ifndef NEW_INPUT_HANDLING show_final_scene(exFocus, exActive); +#else + RevealNewWMState(oldWMState); +#endif } @@ -655,8 +687,13 @@ RootLayer::RemoveSubsetWinBorder(WinBorder *winBorder, WinBorder *fromWinBorder) bool invalidate = false; bool invalid; +#ifndef NEW_INPUT_HANDLING WinBorder* exFocus = FocusWinBorder(); WinBorder* exActive = ActiveWinBorder(); +#else + Workspace::State oldWMState; + ActiveWorkspace()->GetState(&oldWMState); +#endif // we try to remove from all workspaces. If winBorder is not in there, nothing will be done. for (int32 i = 0; i < fWsCount; i++) { @@ -670,7 +707,11 @@ RootLayer::RemoveSubsetWinBorder(WinBorder *winBorder, WinBorder *fromWinBorder) } if (invalidate) +#ifndef NEW_INPUT_HANDLING show_final_scene(exFocus, exActive); +#else + RevealNewWMState(oldWMState); +#endif } // NOTE: This must be called by RootLayer's thread!!!! @@ -719,7 +760,10 @@ bool RootLayer::SetActiveWorkspace(int32 index) fLayerData->SetLowColor(fWorkspace[index]->BGColor()); int32 exIndex = ActiveWorkspaceIndex(); - +#ifdef NEW_INPUT_HANDLING + Workspace::State oldWMState; + ActiveWorkspace()->GetState(&oldWMState); +#endif // send the workspace changed message for the old workspace { BMessage activatedMsg(B_WORKSPACE_ACTIVATED); @@ -727,8 +771,18 @@ bool RootLayer::SetActiveWorkspace(int32 index) activatedMsg.AddInt32("workspace", fActiveWksIndex); activatedMsg.AddBool("active", false); +#ifndef NEW_INPUT_HANDLING for (int32 i = 0; i < fWinBorderCount; i++) fWinBorderList[i]->Window()->SendMessageToClient(&activatedMsg, B_NULL_TOKEN, false); +#else + Layer *layer; + WinBorder *winBorder; + for (int32 i = 0; (layer = static_cast(fWMState.WindowList.ItemAt(i++))); ) { + winBorder = dynamic_cast(layer); + if (winBorder) + winBorder->Window()->SendMessageToClient(&activatedMsg, B_NULL_TOKEN, false); + } +#endif } fActiveWksIndex = index; @@ -787,6 +841,7 @@ bool RootLayer::SetActiveWorkspace(int32 index) }*/ fHaveWinBorderList = true; +#ifndef NEW_INPUT_HANDLING get_workspace_windows(); if (WorkspacesLayer() != NULL) @@ -796,6 +851,10 @@ bool RootLayer::SetActiveWorkspace(int32 index) GoRedraw(WorkspacesLayer(), WorkspacesLayer()->VisibleRegion()); #endif +#else + RevealNewWMState(oldWMState); +#endif + // send the workspace changed message for the new workspace { BMessage activatedMsg(B_WORKSPACE_ACTIVATED); @@ -803,8 +862,19 @@ bool RootLayer::SetActiveWorkspace(int32 index) activatedMsg.AddInt32("workspace", fActiveWksIndex); activatedMsg.AddBool("active", true); +#ifndef NEW_INPUT_HANDLING for (int32 i = 0; i < fWinBorderCount; i++) fWinBorderList[i]->Window()->SendMessageToClient(&activatedMsg, B_NULL_TOKEN, false); +#else + Layer *layer; + WinBorder *winBorder; + for (int32 i = 0; (layer = static_cast(fWMState.WindowList.ItemAt(i++))); ) { + winBorder = dynamic_cast(layer); + if (winBorder) + winBorder->Window()->SendMessageToClient(&activatedMsg, B_NULL_TOKEN, false); + } +#endif + } // workspace changed @@ -822,8 +892,13 @@ RootLayer::SetWinBorderWorskpaces(WinBorder *winBorder, uint32 oldWksIndex, uint bool invalidate = false; bool invalid; +#ifndef NEW_INPUT_HANDLING WinBorder* exFocus = FocusWinBorder(); - WinBorder* exActive = ActiveWinBorder(); + WinBorder* exActive = ActiveWinBorder(); +#else + Workspace::State oldWMState; + ActiveWorkspace()->GetState(&oldWMState); +#endif for (int32 i = 0; i < 32; i++) { if (fWorkspace[i]) { @@ -877,7 +952,11 @@ RootLayer::SetWinBorderWorskpaces(WinBorder *winBorder, uint32 oldWksIndex, uint winBorder->Window()->SendMessageToClient(&changedMsg, B_NULL_TOKEN, false); if (invalidate) +#ifndef NEW_INPUT_HANDLING show_final_scene(exFocus, exActive); +#else + RevealNewWMState(oldWMState); +#endif } @@ -1011,6 +1090,7 @@ RootLayer::ShowWinBorder(WinBorder* winBorder) WinBorder * RootLayer::WinBorderAt(const BPoint& pt) const { +#ifndef NEW_INPUT_HANDLING for (int32 i = 0; i < fWinBorderCount; i++) { #ifndef NEW_CLIPPING @@ -1018,10 +1098,91 @@ RootLayer::WinBorderAt(const BPoint& pt) const return fWinBorderList[i]; #endif } +#endif return NULL; } +#ifdef NEW_INPUT_HANDLING +void +RootLayer::RevealNewWMState(Workspace::State &oldWMState) +{ + // clean fWMState + fWMState.Focus = NULL; + fWMState.Front = NULL; + fWMState.Active = NULL; + fWMState.WindowList.MakeEmpty(); + ActiveWorkspace()->GetState(&fWMState); + +// BOOKMARK! +// TODO: there can be more than one window active at a time! ex: a normal + floating_app, with +// floating window having focus. + // send window activation messages + if (oldWMState.Active != fWMState.Active) { + if (oldWMState.Active && oldWMState.Active->Window()) { + BMessage msg(B_WINDOW_ACTIVATED); + msg.AddBool("active", false); + oldWMState.Active->Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false); + } + if (fWMState.Active && fWMState.Active->Window()) { + BMessage msg(B_WINDOW_ACTIVATED); + msg.AddBool("active", true); + fWMState.Active->Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false); + } + } + + // calculate the region that must be invalidated/redrawn + + bool redraw = false; + // first, if the focus window changed, make sure the decorators reflect this state. + BRegion dirtyRegion; + if (oldWMState.Focus != fWMState.Focus) { + if (oldWMState.Focus) { + dirtyRegion.Include(&oldWMState.Focus->VisibleRegion()); + redraw = true; + } + if (fWMState.Focus) { + dirtyRegion.Include(&fWMState.Focus->VisibleRegion()); + redraw = true; + } + if (redraw) { +#ifndef NEW_CLIPPING + fRedrawReg.Include(&dirtyRegion); +#else +// TODO: code for new clipping engine! +#endif + } + } + + bool invalidate = false; + // check to see if window count changed over states + if (oldWMState.WindowList.CountItems() != fWMState.WindowList.CountItems()) { + invalidate = true; + } + else if (memcmp(oldWMState.WindowList.Items(), fWMState.WindowList.Items(), + fWMState.WindowList.CountItems()) != 0) { + invalidate = true; + } + + if (invalidate) { + // redraw of focus change is automaticaly done + redraw = false; + // trigger region rebuilding and redraw +#ifndef NEW_CLIPPING + invalidate_layer(this, fFull); +#else + do_Invalidate(Bounds()); +#endif + } + else if (redraw) { +#ifndef NEW_CLIPPING + invalidate_layer(this, dirtyRegion); +#else + do_Redraw(dirtyRegion); +#endif + } +} +#endif //--------------------------------------------------------------------------- // Workspace related methods //--------------------------------------------------------------------------- @@ -1575,12 +1736,15 @@ RootLayer::KeyboardEventHandler(int32 code, BPrivate::PortLink& msg) #endif { STRACE(("Set Workspace %ld\n",scancode-1)); +#ifndef NEW_INPUT_HANDLING WinBorder* exFocus = FocusWinBorder(); WinBorder* exActive = ActiveWinBorder(); if (SetActiveWorkspace(scancode - 2)) show_final_scene(exFocus, exActive); - +#else + SetActiveWorkspace(scancode - 2); +#endif #ifdef APPSERVER_ROOTLAYER_SHOW_WORKSPACE_NUMBER // to draw the current Workspace index on screen. #ifndef NEW_CLIPPING @@ -1606,11 +1770,14 @@ RootLayer::KeyboardEventHandler(int32 code, BPrivate::PortLink& msg) //ServerApp *deskbar = app_server->FindApp("application/x-vnd.Be-TSKB"); //if(deskbar) //{ +#ifndef NEW_INPUT_HANDLING WinBorder* exActive = ActiveWinBorder(); WinBorder* exFocus = FocusWinBorder(); if (ActiveWorkspace()->MoveToBack(exActive)) show_final_scene(exFocus, exActive); - +#else + // TODO: implement; +#endif printf("Send Twitcher message key to Deskbar - unimplmemented\n"); free(string); break; @@ -1994,8 +2161,13 @@ RootLayer::show_winBorder(WinBorder *winBorder) { bool invalidate = false; bool invalid; +#ifndef NEW_INPUT_HANDLING WinBorder* exFocus = FocusWinBorder(); WinBorder* exActive = ActiveWinBorder(); +#else + Workspace::State oldWMState; + ActiveWorkspace()->GetState(&oldWMState); +#endif winBorder->Show(false); @@ -2027,6 +2199,7 @@ RootLayer::show_winBorder(WinBorder *winBorder) } if (invalidate) +#ifndef NEW_INPUT_HANDLING show_final_scene(exFocus, exActive); if (WorkspacesLayer()) @@ -2035,6 +2208,11 @@ RootLayer::show_winBorder(WinBorder *winBorder) #else GoRedraw(WorkspacesLayer(), FullVisible()); #endif + +#else + RevealNewWMState(oldWMState); +#endif + } @@ -2043,8 +2221,13 @@ RootLayer::hide_winBorder(WinBorder *winBorder) { bool invalidate = false; bool invalid; +#ifndef NEW_INPUT_HANDLING WinBorder* exFocus = FocusWinBorder(); WinBorder* exActive = ActiveWinBorder(); +#else + Workspace::State oldWMState; + ActiveWorkspace()->GetState(&oldWMState); +#endif winBorder->Hide(false); @@ -2063,6 +2246,7 @@ RootLayer::hide_winBorder(WinBorder *winBorder) } if (invalidate) +#ifndef NEW_INPUT_HANDLING show_final_scene(exFocus, exActive); if (WorkspacesLayer()) @@ -2071,6 +2255,10 @@ RootLayer::hide_winBorder(WinBorder *winBorder) #else GoRedraw(WorkspacesLayer(), FullVisible()); #endif + +#else + RevealNewWMState(oldWMState); +#endif } @@ -2080,8 +2268,13 @@ RootLayer::change_winBorder_feel(WinBorder *winBorder, int32 newFeel) bool isVisible = false; bool wasVisibleInActiveWorkspace = false; +#ifndef NEW_INPUT_HANDLING WinBorder* exFocus = FocusWinBorder(); WinBorder* exActive = ActiveWinBorder(); +#else + Workspace::State oldWMState; + ActiveWorkspace()->GetState(&oldWMState); +#endif if (!winBorder->IsHidden()) { isVisible = true; @@ -2110,10 +2303,15 @@ RootLayer::change_winBorder_feel(WinBorder *winBorder, int32 newFeel) winBorder->Show(false); if (wasVisibleInActiveWorkspace || ActiveWorkspace()->HasWinBorder(winBorder)) - show_final_scene(exFocus, exActive); +#ifndef NEW_INPUT_HANDLING + show_final_scene(exFocus, exActive); +#else + RevealNewWMState(oldWMState); +#endif } } +#ifndef NEW_INPUT_HANDLING bool RootLayer::get_workspace_windows() { int32 bufferSize = fWinBorderListLength; @@ -2202,6 +2400,7 @@ RootLayer::draw_window_tab(WinBorder *exFocus) } } } +#endif #ifndef NEW_CLIPPING void @@ -2220,6 +2419,7 @@ RootLayer::empty_visible_regions(Layer *layer) } #endif +#ifndef NEW_INPUT_HANDLING void RootLayer::winborder_activation(WinBorder* exActive) { @@ -2269,7 +2469,7 @@ RootLayer::show_final_scene(WinBorder *exFocus, WinBorder *exActive) fLastLayerUnderMouse = this; } } - +#endif void RootLayer::Draw(const BRect &r) diff --git a/src/servers/app/RootLayer.h b/src/servers/app/RootLayer.h index b614277b2c..aeeb734c8b 100644 --- a/src/servers/app/RootLayer.h +++ b/src/servers/app/RootLayer.h @@ -87,7 +87,9 @@ public: uint32 oldWksIndex, uint32 newWksIndex); WinBorder* WinBorderAt(const BPoint& pt) const; - +#ifdef NEW_INPUT_HANDLING + void RevealNewWMState(Workspace::State &oldWMState); +#endif inline WinBorder* FocusWinBorder() const { return ActiveWorkspace()->Focus(); } inline WinBorder* FrontWinBorder() const { return ActiveWorkspace()->Front(); } inline WinBorder* ActiveWinBorder() const { return ActiveWorkspace()->Active(); } @@ -156,17 +158,17 @@ friend class WinBorder; // temporarily, I need invalidate_layer() void change_winBorder_feel(WinBorder *winBorder, int32 newFeel); - bool get_workspace_windows(); - void draw_window_tab(WinBorder *exFocus); #ifndef NEW_CLIPPING void empty_visible_regions(Layer *layer); void invalidate_layer(Layer *layer, const BRegion ®ion); void redraw_layer(Layer *layer, const BRegion ®ion); #endif +#ifndef NEW_INPUT_HANDLING + bool get_workspace_windows(); + void draw_window_tab(WinBorder *exFocus); void winborder_activation(WinBorder* exActive); - void show_final_scene(WinBorder *exFocus, WinBorder *exActive); - +#endif // Input related methods void MouseEventHandler(int32 code, BPrivate::PortLink& link); void KeyboardEventHandler(int32 code, BPrivate::PortLink& link); @@ -205,9 +207,16 @@ friend class WinBorder; // temporarily, I need invalidate_layer() Workspace** fWorkspace; Layer* fWorkspacesLayer; +#ifndef NEW_INPUT_HANDLING int32 fWinBorderListLength; WinBorder** fWinBorderList2; WinBorder** fWinBorderList; +#else +// TODO: fWMState MUST be associated with a surface. This is the case now +// with RootLayer, but after Axel's refractoring this should go in +// WorkspaceLayer, I think. + Workspace::State fWMState; +#endif int32 fWinBorderCount; mutable int32 fWinBorderIndex; diff --git a/src/servers/app/WinBorder.cpp b/src/servers/app/WinBorder.cpp index e6f67eea92..f3484a4dc8 100644 --- a/src/servers/app/WinBorder.cpp +++ b/src/servers/app/WinBorder.cpp @@ -450,9 +450,9 @@ void WinBorder::MouseDown(const PointerEvent& evt) { DesktopSettings desktopSettings(gDesktop); - Workspace::State oldState, newState; + Workspace::State oldWMState; - GetRootLayer()->ActiveWorkspace()->GetState(&oldState); + GetRootLayer()->ActiveWorkspace()->GetState(&oldWMState); // not in FFM mode? if (desktopSettings.MouseMode() == B_NORMAL_MOUSE) { @@ -532,45 +532,7 @@ WinBorder::MouseDown(const PointerEvent& evt) GetRootLayer()->ActiveWorkspace()->AttemptToActivate(this); } - GetRootLayer()->ActiveWorkspace()->GetState(&newState); - -// BOOKMARK! -// TODO: there can be more than one window active at a time! ex: a normal + floating_app, with -// floating window having focus. - // send window activation messages - if (oldState.Active != newState.Active) { - if (oldState.Active && oldState.Active->Window()) { - BMessage msg(B_WINDOW_ACTIVATED); - msg.AddBool("active", false); - oldState.Active->Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false); - } - if (newState.Active && newState.Active->Window()) { - BMessage msg(B_WINDOW_ACTIVATED); - msg.AddBool("active", true); - newState.Active->Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false); - } - } - - // calculate the region that must be invalidated/redrawn - - // first, if the focus window changed, make sure the decorators reflect this state. - BRegion dirtyRegion; - if (oldState.Focus != newState.Focus) { - dirtyRegion.Include(&oldState.Focus->VisibleRegion()); - dirtyRegion.Include(&newState.Focus->VisibleRegion()); -#ifndef NEW_CLIPPING - GetRootLayer()->fRedrawReg.Include(&dirtyRegion); -#else -// TODO: code for new clipping engine! -#endif - } - - // trigger region rebuilding and redraw -#ifndef NEW_CLIPPING - GetRootLayer()->invalidate_layer(this, fFull); -#else - GetRootLayer()->do_Invalidate(Bounds()); -#endif + GetRootLayer()->RevealNewWMState(oldWMState); } } // in FFM mode @@ -619,7 +581,7 @@ WinBorder::MouseUp(const PointerEvent& event) // TODO: set dirty regions! #ifndef NEW_CLIPPING - GetRootLayer()->invalidate_layer(this, VisibleRegion()); + GetRootLayer()->invalidate_layer(GetRootLayer(), VisibleRegion()); #else do_Invalidate(VisibleRegion()); #endif diff --git a/src/servers/app/Workspace.h b/src/servers/app/Workspace.h index 0376c2f5d0..6f12838fe3 100644 --- a/src/servers/app/Workspace.h +++ b/src/servers/app/Workspace.h @@ -51,7 +51,7 @@ class Workspace { public: class State { public: - State() : Front(NULL), Focus(NULL), WindowList(40) { } + State() : Front(NULL), Focus(NULL), WindowList(50) { } WinBorder* Front; WinBorder* Focus; WinBorder* Active;