App Server: Update S&T window group navigation

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.
This commit is contained in:
John Scipione
2014-01-30 19:48:36 -05:00
parent 5002366cf4
commit 94d4c31912
4 changed files with 125 additions and 71 deletions
+16 -2
View File
@@ -787,9 +787,9 @@ Tab::CompareFunction(const Tab* tab1, const Tab* tab2)
SATGroup::SATGroup() SATGroup::SATGroup()
: :
fHorizontalTabsSorted(false), 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* const TabList*
SATGroup::HorizontalTabs() SATGroup::HorizontalTabs()
{ {
+5
View File
@@ -258,6 +258,9 @@ public:
int32 CountItems(); int32 CountItems();
SATWindow* WindowAt(int32 index); SATWindow* WindowAt(int32 index);
SATWindow* ActiveWindow() const;
void SetActiveWindow(SATWindow* window);
const WindowAreaList& GetAreaList() { return fWindowAreaList; } const WindowAreaList& GetAreaList() { return fWindowAreaList; }
/*! \return a sorted tab list. */ /*! \return a sorted tab list. */
@@ -324,6 +327,8 @@ private:
bool fHorizontalTabsSorted; bool fHorizontalTabsSorted;
TabList fVerticalTabs; TabList fVerticalTabs;
bool fVerticalTabsSorted; bool fVerticalTabsSorted;
SATWindow* fActiveWindow;
}; };
+98 -69
View File
@@ -19,6 +19,12 @@
#include "Window.h" #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; using namespace std;
@@ -118,7 +124,6 @@ StackAndTile::WindowRemoved(Window* window)
bool bool
StackAndTile::KeyPressed(uint32 what, int32 key, int32 modifiers) StackAndTile::KeyPressed(uint32 what, int32 key, int32 modifiers)
{ {
const int32 kRightOptionKey = 103;
if (what == B_MODIFIERS_CHANGED if (what == B_MODIFIERS_CHANGED
|| (what == B_UNMAPPED_KEY_DOWN && key == kRightOptionKey) || (what == B_UNMAPPED_KEY_DOWN && key == kRightOptionKey)
|| (what == B_UNMAPPED_KEY_UP && 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) if (!SATKeyPressed() || what != B_KEY_DOWN)
return false; return false;
const int kArrowKeyUp = 87; SATWindow* frontWindow = GetSATWindow(fDesktop->FocusWindow());
const int kArrowKeyDown = 98; SATGroup* currentGroup = _GetSATGroup(frontWindow);
const int kArrowKeyLeft = 97;
const int kArrowKeyRight = 99;
switch (key) { switch (key) {
case kArrowKeyLeft: case kTabKey:
case kArrowKeyRight:
{ {
SATWindow* frontWindow = GetSATWindow(fDesktop->FocusWindow()); // go to previous or next window tab in current window group
SATGroup* currentGroup = NULL;
if (frontWindow)
currentGroup = frontWindow->GetGroup();
if (currentGroup == NULL) if (currentGroup == NULL)
return false; return false;
@@ -159,11 +158,16 @@ StackAndTile::KeyPressed(uint32 what, int32 key, int32 modifiers)
for (int32 i = 0; i < groupSize; i++) { for (int32 i = 0; i < groupSize; i++) {
SATWindow* targetWindow = currentGroup->WindowAt(i); SATWindow* targetWindow = currentGroup->WindowAt(i);
if (targetWindow == frontWindow) { if (targetWindow == frontWindow) {
if (key == kArrowKeyLeft && i > 0) { if ((modifiers & B_SHIFT_KEY) != 0) {
targetWindow = currentGroup->WindowAt(i - 1); // Go to previous window tab (wrap around)
} else if (key == kArrowKeyRight && i < groupSize - 1) { int32 previousIndex = i > 0 ? i - 1 : groupSize - 1;
targetWindow = currentGroup->WindowAt(i + 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); _ActivateWindow(targetWindow);
return true; return true;
} }
@@ -171,75 +175,74 @@ StackAndTile::KeyPressed(uint32 what, int32 key, int32 modifiers)
break; break;
} }
case kArrowKeyDown: case kPageUpKey:
{ {
SATWindow* frontWindow = GetSATWindow(fDesktop->FocusWindow()); // go to previous window group
SATGroup* currentGroup = NULL;
if (frontWindow)
currentGroup = frontWindow->GetGroup();
if (currentGroup && currentGroup->CountItems() <= 1)
currentGroup = NULL;
GroupIterator groups(this, fDesktop); GroupIterator groups(this, fDesktop);
bool currentFound = false; groups.SetCurrentGroup(currentGroup);
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;
SATGroup* backmostGroup = NULL; SATGroup* backmostGroup = NULL;
GroupIterator groups(this, fDesktop);
while (true) { while (true) {
SATGroup* group = groups.NextGroup(); SATGroup* group = groups.NextGroup();
if (group == NULL) if (group == NULL || group == currentGroup)
break; break;
if (group->CountItems() <= 1) else if (group->CountItems() < 1)
continue; continue;
// if no group is selected just activate the first one
if (currentGroup == NULL) { if (currentGroup == NULL) {
_ActivateWindow(group->WindowAt(0)); SATWindow* activeWindow = group->ActiveWindow();
if (activeWindow != NULL)
_ActivateWindow(activeWindow);
else
_ActivateWindow(group->WindowAt(0));
return true; return true;
} }
backmostGroup = group; backmostGroup = group;
} }
if (backmostGroup && backmostGroup != currentGroup) { if (backmostGroup != NULL && backmostGroup != currentGroup) {
_ActivateWindow(backmostGroup->WindowAt(0)); 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; return true;
} }
break; break;
} }
} }
return false; return false;
} }
@@ -596,8 +599,17 @@ StackAndTile::_ActivateWindow(SATWindow* satWindow)
area->MoveToTopLayer(satWindow); area->MoveToTopLayer(satWindow);
const WindowAreaList& areas = group->GetAreaList() ; // save the active window of the current group
for (int32 i = 0; i < areas.CountItems(); i++) { 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); WindowArea* currentArea = areas.ItemAt(i);
if (currentArea == area) if (currentArea == area)
continue; 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 // #pragma mark - GroupIterator
@@ -102,6 +102,7 @@ private:
void _ActivateWindow(SATWindow* window); void _ActivateWindow(SATWindow* window);
bool _HandleMessage(BPrivate::LinkReceiver& link, bool _HandleMessage(BPrivate::LinkReceiver& link,
BPrivate::LinkSender& reply); BPrivate::LinkSender& reply);
SATGroup* _GetSATGroup(SATWindow* window);
Desktop* fDesktop; Desktop* fDesktop;
@@ -119,6 +120,11 @@ public:
GroupIterator(StackAndTile* sat, GroupIterator(StackAndTile* sat,
Desktop* desktop); Desktop* desktop);
SATGroup* CurrentGroup(void) const
{ return fCurrentGroup; };
void SetCurrentGroup(SATGroup* group)
{ fCurrentGroup = group; };
void RewindToFront(); void RewindToFront();
SATGroup* NextGroup(); SATGroup* NextGroup();