shelf_focus_cycler.cc 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/shelf/shelf_focus_cycler.h"
  5. #include "ash/focus_cycler.h"
  6. #include "ash/shelf/login_shelf_view.h"
  7. #include "ash/shelf/login_shelf_widget.h"
  8. #include "ash/shelf/scrollable_shelf_view.h"
  9. #include "ash/shelf/shelf.h"
  10. #include "ash/shelf/shelf_navigation_widget.h"
  11. #include "ash/shelf/shelf_view.h"
  12. #include "ash/shelf/shelf_widget.h"
  13. #include "ash/shell.h"
  14. #include "ash/system/status_area_widget.h"
  15. #include "ash/system/status_area_widget_delegate.h"
  16. #include "ash/system/tray/system_tray_notifier.h"
  17. namespace ash {
  18. ShelfFocusCycler::ShelfFocusCycler(Shelf* shelf) : shelf_(shelf) {}
  19. void ShelfFocusCycler::FocusOut(bool reverse, SourceView source_view) {
  20. // TODO(manucornet): Once the non-views-based shelf is gone, make this a
  21. // simple cycling logic instead of a long switch.
  22. switch (source_view) {
  23. case SourceView::kShelfNavigationView:
  24. if (reverse)
  25. FocusStatusArea(reverse);
  26. else
  27. FocusShelf(reverse);
  28. break;
  29. case SourceView::kShelfView:
  30. if (reverse)
  31. FocusNavigation(reverse);
  32. else
  33. FocusStatusArea(reverse);
  34. break;
  35. case SourceView::kStatusAreaView: {
  36. // If we are using a views-based shelf:
  37. // * If we're in an active session, either focus the navigation widget
  38. // (going forward) or the shelf (reverse).
  39. // * Otherwise (login/lock screen, OOBE), bring focus to the shelf only
  40. // if we're going in reverse; if we're going forward, let the system
  41. // tray focus observers focus the lock/login view.
  42. if (shelf_->shelf_widget()->GetLoginShelfView()->GetVisible() &&
  43. (!reverse ||
  44. (!shelf_->shelf_widget()->GetLoginShelfView()->IsFocusable() &&
  45. reverse))) {
  46. // Login/lock screen or OOBE.
  47. Shell::Get()->system_tray_notifier()->NotifyFocusOut(reverse);
  48. } else if (reverse) {
  49. FocusShelf(reverse);
  50. } else {
  51. FocusNavigation(reverse);
  52. }
  53. break;
  54. }
  55. }
  56. }
  57. void ShelfFocusCycler::FocusNavigation(bool last_element) {
  58. ShelfNavigationWidget* navigation_widget = shelf_->navigation_widget();
  59. if (!navigation_widget->GetHomeButton() &&
  60. !navigation_widget->GetBackButton()) {
  61. FocusOut(last_element, SourceView::kShelfNavigationView);
  62. return;
  63. }
  64. navigation_widget->PrepareForGettingFocus(last_element);
  65. Shell::Get()->focus_cycler()->FocusWidget(navigation_widget);
  66. }
  67. void ShelfFocusCycler::FocusShelf(bool last_element) {
  68. if (shelf_->shelf_widget()->GetLoginShelfView()->GetVisible()) {
  69. // TODO(https://crbug.com/1343114): refactor the code below after the login
  70. // shelf widget is ready.
  71. if (features::IsUseLoginShelfWidgetEnabled()) {
  72. LoginShelfWidget* login_shelf_widget = shelf_->login_shelf_widget();
  73. login_shelf_widget->SetDefaultLastFocusableChild(last_element);
  74. Shell::Get()->focus_cycler()->FocusWidget(login_shelf_widget);
  75. } else {
  76. ShelfWidget* shelf_widget = shelf_->shelf_widget();
  77. shelf_widget->set_default_last_focusable_child(last_element);
  78. Shell::Get()->focus_cycler()->FocusWidget(shelf_widget);
  79. }
  80. } else {
  81. HotseatWidget* hotseat_widget = shelf_->hotseat_widget();
  82. hotseat_widget->scrollable_shelf_view()->set_default_last_focusable_child(
  83. last_element);
  84. Shell::Get()->focus_cycler()->FocusWidget(hotseat_widget);
  85. }
  86. }
  87. void ShelfFocusCycler::FocusStatusArea(bool last_element) {
  88. StatusAreaWidget* status_area_widget = shelf_->GetStatusAreaWidget();
  89. status_area_widget->status_area_widget_delegate()
  90. ->set_default_last_focusable_child(last_element);
  91. Shell::Get()->focus_cycler()->FocusWidget(status_area_widget);
  92. }
  93. } // namespace ash