bool StackAndTile::KeyPressed(uint32 what, int32 key, int32 modifiers) { if (what == B_MODIFIERS_CHANGED || (what == B_UNMAPPED_KEY_DOWN && key == kRightOptionKey) || (what == B_UNMAPPED_KEY_UP && key == kRightOptionKey)) { // switch to and from stacking and snapping mode bool wasPressed = fSATKeyPressed; fSATKeyPressed = (what == B_MODIFIERS_CHANGED && (modifiers & kModifiers) == B_OPTION_KEY) || (what == B_UNMAPPED_KEY_DOWN && key == kRightOptionKey); if (wasPressed && !fSATKeyPressed) _StopSAT(); if (!wasPressed && fSATKeyPressed) _StartSAT(); } if (!SATKeyPressed() || what != B_KEY_DOWN) return false; SATWindow* frontWindow = GetSATWindow(fDesktop->FocusWindow()); SATGroup* currentGroup = _GetSATGroup(frontWindow); switch (key) { case kLeftArrowKey: case kRightArrowKey: case kTabKey: { // go to previous or next window tab in current window group if (currentGroup == NULL) return false; int32 groupSize = currentGroup->CountItems(); if (groupSize <= 1) return false; for (int32 i = 0; i < groupSize; i++) { SATWindow* targetWindow = currentGroup->WindowAt(i); if (targetWindow == frontWindow) { if (key == kLeftArrowKey || (key == kTabKey && (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; } } break; } case kUpArrowKey: case kPageUpKey: { // go to previous window group GroupIterator groups(this, fDesktop); groups.SetCurrentGroup(currentGroup); SATGroup* backmostGroup = NULL; while (true) { SATGroup* group = groups.NextGroup(); if (group == NULL || group == currentGroup) break; else if (group->CountItems() < 1) continue; if (currentGroup == NULL) { SATWindow* activeWindow = group->ActiveWindow(); if (activeWindow != NULL) _ActivateWindow(activeWindow); else _ActivateWindow(group->WindowAt(0)); return true; } backmostGroup = group; } if (backmostGroup != NULL && backmostGroup != currentGroup) { SATWindow* activeWindow = backmostGroup->ActiveWindow(); if (activeWindow != NULL) _ActivateWindow(activeWindow); else _ActivateWindow(backmostGroup->WindowAt(0)); return true; } break; } case kDownArrowKey: 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; }