From 94d4c319129f9dd9e85fb7b3cebc1b09f61ae7e6 Mon Sep 17 00:00:00 2001 From: John Scipione Date: Sat, 18 Jan 2014 20:29:36 -0500 Subject: [PATCH] App Server: Update S&T window group navigation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Partially fixes #9431 Cycle through tabs in current S&T group with option+tab and backwards with option+shift+tab Cycle through S&T groups with option+PgDn and backwards with option+PgUp This change allows apps to once again use option+arrows when inside of a S&T group The problem isn’t truely fixed though, just moved to different shortcuts that hopefully will conflict in fewer applications. I also made some improvements to how S&T cycling works. A single window is now considered to be part of a S&T group for the purposes of cycling through S&T groups. We loop around when you get the last tab/group. When you cycle through S&T groups it remembers the active tab in the group instead of always activating the first tab. --- src/servers/app/stackandtile/SATGroup.cpp | 18 +- src/servers/app/stackandtile/SATGroup.h | 5 + src/servers/app/stackandtile/StackAndTile.cpp | 167 ++++++++++-------- src/servers/app/stackandtile/StackAndTile.h | 6 + 4 files changed, 125 insertions(+), 71 deletions(-) diff --git a/src/servers/app/stackandtile/SATGroup.cpp b/src/servers/app/stackandtile/SATGroup.cpp index b75a11df96..b5d5a76491 100644 --- a/src/servers/app/stackandtile/SATGroup.cpp +++ b/src/servers/app/stackandtile/SATGroup.cpp @@ -787,9 +787,9 @@ Tab::CompareFunction(const Tab* tab1, const Tab* tab2) SATGroup::SATGroup() : fHorizontalTabsSorted(false), - fVerticalTabsSorted(false) + fVerticalTabsSorted(false), + fActiveWindow(NULL) { - } @@ -932,6 +932,20 @@ SATGroup::WindowAt(int32 index) } +SATWindow* +SATGroup::ActiveWindow() const +{ + return fActiveWindow; +} + + +void +SATGroup::SetActiveWindow(SATWindow* window) +{ + fActiveWindow = window; +} + + const TabList* SATGroup::HorizontalTabs() { diff --git a/src/servers/app/stackandtile/SATGroup.h b/src/servers/app/stackandtile/SATGroup.h index a945354ef8..661f9f4c08 100644 --- a/src/servers/app/stackandtile/SATGroup.h +++ b/src/servers/app/stackandtile/SATGroup.h @@ -258,6 +258,9 @@ public: int32 CountItems(); SATWindow* WindowAt(int32 index); + SATWindow* ActiveWindow() const; + void SetActiveWindow(SATWindow* window); + const WindowAreaList& GetAreaList() { return fWindowAreaList; } /*! \return a sorted tab list. */ @@ -324,6 +327,8 @@ private: bool fHorizontalTabsSorted; TabList fVerticalTabs; bool fVerticalTabsSorted; + + SATWindow* fActiveWindow; }; diff --git a/src/servers/app/stackandtile/StackAndTile.cpp b/src/servers/app/stackandtile/StackAndTile.cpp index d6b8cf47b6..21ea2dee9e 100644 --- a/src/servers/app/stackandtile/StackAndTile.cpp +++ b/src/servers/app/stackandtile/StackAndTile.cpp @@ -19,6 +19,12 @@ #include "Window.h" +static const int32 kRightOptionKey = 0x67; +static const int32 kTabKey = 0x26; +static const int32 kPageUpKey = 0x21; +static const int32 kPageDownKey = 0x36; + + using namespace std; @@ -118,7 +124,6 @@ StackAndTile::WindowRemoved(Window* window) bool StackAndTile::KeyPressed(uint32 what, int32 key, int32 modifiers) { - const int32 kRightOptionKey = 103; if (what == B_MODIFIERS_CHANGED || (what == B_UNMAPPED_KEY_DOWN && key == kRightOptionKey) || (what == B_UNMAPPED_KEY_UP && key == kRightOptionKey)) { @@ -136,19 +141,13 @@ StackAndTile::KeyPressed(uint32 what, int32 key, int32 modifiers) if (!SATKeyPressed() || what != B_KEY_DOWN) return false; - const int kArrowKeyUp = 87; - const int kArrowKeyDown = 98; - const int kArrowKeyLeft = 97; - const int kArrowKeyRight = 99; + SATWindow* frontWindow = GetSATWindow(fDesktop->FocusWindow()); + SATGroup* currentGroup = _GetSATGroup(frontWindow); switch (key) { - case kArrowKeyLeft: - case kArrowKeyRight: + case kTabKey: { - SATWindow* frontWindow = GetSATWindow(fDesktop->FocusWindow()); - SATGroup* currentGroup = NULL; - if (frontWindow) - currentGroup = frontWindow->GetGroup(); + // go to previous or next window tab in current window group if (currentGroup == NULL) return false; @@ -159,11 +158,16 @@ StackAndTile::KeyPressed(uint32 what, int32 key, int32 modifiers) for (int32 i = 0; i < groupSize; i++) { SATWindow* targetWindow = currentGroup->WindowAt(i); if (targetWindow == frontWindow) { - if (key == kArrowKeyLeft && i > 0) { - targetWindow = currentGroup->WindowAt(i - 1); - } else if (key == kArrowKeyRight && i < groupSize - 1) { - targetWindow = currentGroup->WindowAt(i + 1); + if ((modifiers & B_SHIFT_KEY) != 0) { + // Go to previous window tab (wrap around) + int32 previousIndex = i > 0 ? i - 1 : groupSize - 1; + targetWindow = currentGroup->WindowAt(previousIndex); + } else { + // Go to next window tab (wrap around) + int32 nextIndex = i < groupSize - 1 ? i + 1 : 0; + targetWindow = currentGroup->WindowAt(nextIndex); } + _ActivateWindow(targetWindow); return true; } @@ -171,75 +175,74 @@ StackAndTile::KeyPressed(uint32 what, int32 key, int32 modifiers) break; } - case kArrowKeyDown: + case kPageUpKey: { - SATWindow* frontWindow = GetSATWindow(fDesktop->FocusWindow()); - SATGroup* currentGroup = NULL; - if (frontWindow) - currentGroup = frontWindow->GetGroup(); - if (currentGroup && currentGroup->CountItems() <= 1) - currentGroup = NULL; - + // go to previous window group GroupIterator groups(this, fDesktop); - bool currentFound = false; - while (true) { - SATGroup* group = groups.NextGroup(); - if (group == NULL) - break; - if (group->CountItems() <= 1) - continue; - - if (currentGroup == NULL) - currentFound = true; - // if no group is selected just activate the first one - else if (currentGroup == group) { - currentFound = true; - continue; - } - if (currentFound) { - _ActivateWindow(group->WindowAt(0)); - if (currentGroup) { - Window* window = currentGroup->WindowAt(0)->GetWindow(); - fDesktop->SendWindowBehind(window); - WindowSentBehind(window, NULL); - } - return true; - } - } - break; - } - - case kArrowKeyUp: - { - SATWindow* frontWindow = GetSATWindow(fDesktop->FocusWindow()); - SATGroup* currentGroup = NULL; - if (frontWindow) - currentGroup = frontWindow->GetGroup(); - if (currentGroup && currentGroup->CountItems() <= 1) - currentGroup = NULL; - + groups.SetCurrentGroup(currentGroup); SATGroup* backmostGroup = NULL; - GroupIterator groups(this, fDesktop); + while (true) { SATGroup* group = groups.NextGroup(); - if (group == NULL) + if (group == NULL || group == currentGroup) break; - if (group->CountItems() <= 1) + else if (group->CountItems() < 1) continue; - // if no group is selected just activate the first one + if (currentGroup == NULL) { - _ActivateWindow(group->WindowAt(0)); + SATWindow* activeWindow = group->ActiveWindow(); + if (activeWindow != NULL) + _ActivateWindow(activeWindow); + else + _ActivateWindow(group->WindowAt(0)); + return true; } backmostGroup = group; } - if (backmostGroup && backmostGroup != currentGroup) { - _ActivateWindow(backmostGroup->WindowAt(0)); + if (backmostGroup != NULL && backmostGroup != currentGroup) { + SATWindow* activeWindow = backmostGroup->ActiveWindow(); + if (activeWindow != NULL) + _ActivateWindow(activeWindow); + else + _ActivateWindow(backmostGroup->WindowAt(0)); + + return true; + } + + break; + } + + case kPageDownKey: + { + // go to next window group + GroupIterator groups(this, fDesktop); + groups.SetCurrentGroup(currentGroup); + + while (true) { + SATGroup* group = groups.NextGroup(); + if (group == NULL || group == currentGroup) + break; + else if (group->CountItems() < 1) + continue; + + SATWindow* activeWindow = group->ActiveWindow(); + if (activeWindow != NULL) + _ActivateWindow(activeWindow); + else + _ActivateWindow(group->WindowAt(0)); + + if (currentGroup != NULL && frontWindow != NULL) { + Window* window = frontWindow->GetWindow(); + fDesktop->SendWindowBehind(window); + WindowSentBehind(window, NULL); + } return true; } break; } } + return false; } @@ -596,8 +599,17 @@ StackAndTile::_ActivateWindow(SATWindow* satWindow) area->MoveToTopLayer(satWindow); - const WindowAreaList& areas = group->GetAreaList() ; - for (int32 i = 0; i < areas.CountItems(); i++) { + // save the active window of the current group + SATWindow* frontWindow = GetSATWindow(fDesktop->FocusWindow()); + SATGroup* currentGroup = _GetSATGroup(frontWindow); + if (currentGroup != NULL && currentGroup != group && frontWindow != NULL) + currentGroup->SetActiveWindow(frontWindow); + else + group->SetActiveWindow(satWindow); + + const WindowAreaList& areas = group->GetAreaList(); + int32 areasCount = areas.CountItems(); + for (int32 i = 0; i < areasCount; i++) { WindowArea* currentArea = areas.ItemAt(i); if (currentArea == area) continue; @@ -668,6 +680,23 @@ StackAndTile::_HandleMessage(BPrivate::LinkReceiver& link, } +SATGroup* +StackAndTile::_GetSATGroup(SATWindow* window) +{ + if (window == NULL) + return NULL; + + SATGroup* group = window->GetGroup(); + if (group == NULL) + return NULL; + + if (group->CountItems() < 1) + return NULL; + + return group; +} + + // #pragma mark - GroupIterator diff --git a/src/servers/app/stackandtile/StackAndTile.h b/src/servers/app/stackandtile/StackAndTile.h index ff5a604990..d7eac367e7 100644 --- a/src/servers/app/stackandtile/StackAndTile.h +++ b/src/servers/app/stackandtile/StackAndTile.h @@ -102,6 +102,7 @@ private: void _ActivateWindow(SATWindow* window); bool _HandleMessage(BPrivate::LinkReceiver& link, BPrivate::LinkSender& reply); + SATGroup* _GetSATGroup(SATWindow* window); Desktop* fDesktop; @@ -119,6 +120,11 @@ public: GroupIterator(StackAndTile* sat, Desktop* desktop); + SATGroup* CurrentGroup(void) const + { return fCurrentGroup; }; + void SetCurrentGroup(SATGroup* group) + { fCurrentGroup = group; }; + void RewindToFront(); SATGroup* NextGroup();