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()
:
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()
{
+5
View File
@@ -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;
};
+98 -69
View File
@@ -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
@@ -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();