shelf_context_menu_model.cc 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // Copyright 2017 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_context_menu_model.h"
  5. #include <memory>
  6. #include <string>
  7. #include <utility>
  8. #include "ash/app_list/app_list_controller_impl.h"
  9. #include "ash/app_list/app_list_metrics.h"
  10. #include "ash/app_list/app_list_model_provider.h"
  11. #include "ash/app_list/model/app_list_model.h"
  12. #include "ash/constants/ash_features.h"
  13. #include "ash/constants/ash_pref_names.h"
  14. #include "ash/constants/personalization_entry_point.h"
  15. #include "ash/public/cpp/app_menu_constants.h"
  16. #include "ash/public/cpp/new_window_delegate.h"
  17. #include "ash/public/cpp/shelf_item_delegate.h"
  18. #include "ash/public/cpp/shelf_model.h"
  19. #include "ash/public/cpp/shelf_prefs.h"
  20. #include "ash/public/cpp/shelf_types.h"
  21. #include "ash/resources/vector_icons/vector_icons.h"
  22. #include "ash/root_window_controller.h"
  23. #include "ash/session/session_controller_impl.h"
  24. #include "ash/shell.h"
  25. #include "ash/strings/grit/ash_strings.h"
  26. #include "ash/wallpaper/wallpaper_controller_impl.h"
  27. #include "ash/wm/tablet_mode/tablet_mode_controller.h"
  28. #include "base/metrics/histogram_functions.h"
  29. #include "base/metrics/user_metrics.h"
  30. #include "base/numerics/safe_conversions.h"
  31. #include "components/prefs/pref_service.h"
  32. #include "ui/base/models/image_model.h"
  33. namespace ash {
  34. namespace {
  35. // Returns true if the user can modify the shelf's auto-hide behavior pref.
  36. bool CanUserModifyShelfAutoHide(PrefService* prefs) {
  37. return prefs && prefs->FindPreference(prefs::kShelfAutoHideBehaviorLocal)
  38. ->IsUserModifiable();
  39. }
  40. // Returns true if the display is showing a fullscreen window.
  41. // NOTE: This duplicates the functionality of Chrome's IsFullScreenMode.
  42. bool IsFullScreenMode(int64_t display_id) {
  43. auto* controller = Shell::GetRootWindowControllerWithDisplayId(display_id);
  44. return controller && controller->GetWindowForFullscreenMode();
  45. }
  46. } // namespace
  47. ShelfContextMenuModel::ShelfContextMenuModel(ShelfItemDelegate* delegate,
  48. int64_t display_id)
  49. : ui::SimpleMenuModel(this), delegate_(delegate), display_id_(display_id) {
  50. // Add shelf and wallpaper items if ShelfView or HomeButton are selected.
  51. if (!delegate)
  52. AddShelfAndWallpaperItems();
  53. }
  54. ShelfContextMenuModel::~ShelfContextMenuModel() = default;
  55. bool ShelfContextMenuModel::IsCommandIdChecked(int command_id) const {
  56. if (command_id == MENU_ALIGNMENT_LEFT ||
  57. command_id == MENU_ALIGNMENT_BOTTOM ||
  58. command_id == MENU_ALIGNMENT_RIGHT) {
  59. PrefService* prefs =
  60. Shell::Get()->session_controller()->GetLastActiveUserPrefService();
  61. const ShelfAlignment alignment = GetShelfAlignmentPref(prefs, display_id_);
  62. if (command_id == MENU_ALIGNMENT_LEFT)
  63. return alignment == ShelfAlignment::kLeft;
  64. if (command_id == MENU_ALIGNMENT_BOTTOM) {
  65. return alignment == ShelfAlignment::kBottom ||
  66. alignment == ShelfAlignment::kBottomLocked;
  67. }
  68. if (command_id == MENU_ALIGNMENT_RIGHT)
  69. return alignment == ShelfAlignment::kRight;
  70. }
  71. return SimpleMenuModel::Delegate::IsCommandIdChecked(command_id);
  72. }
  73. void ShelfContextMenuModel::ExecuteCommand(int command_id, int event_flags) {
  74. DCHECK(IsCommandIdEnabled(command_id));
  75. Shell* shell = Shell::Get();
  76. PrefService* prefs =
  77. shell->session_controller()->GetLastActiveUserPrefService();
  78. if (!prefs) // Null during startup.
  79. return;
  80. // Clamshell mode only options should not activate in tablet mode.
  81. const bool is_tablet_mode = shell->tablet_mode_controller()->InTabletMode();
  82. switch (command_id) {
  83. case MENU_AUTO_HIDE:
  84. SetShelfAutoHideBehaviorPref(
  85. prefs, display_id_,
  86. GetShelfAutoHideBehaviorPref(prefs, display_id_) ==
  87. ShelfAutoHideBehavior::kAlways
  88. ? ShelfAutoHideBehavior::kNever
  89. : ShelfAutoHideBehavior::kAlways);
  90. break;
  91. case MENU_ALIGNMENT_LEFT:
  92. DCHECK(!is_tablet_mode);
  93. base::RecordAction(base::UserMetricsAction("Shelf_AlignmentSetLeft"));
  94. SetShelfAlignmentPref(prefs, display_id_, ShelfAlignment::kLeft);
  95. break;
  96. case MENU_ALIGNMENT_RIGHT:
  97. DCHECK(!is_tablet_mode);
  98. base::RecordAction(base::UserMetricsAction("Shelf_AlignmentSetRight"));
  99. SetShelfAlignmentPref(prefs, display_id_, ShelfAlignment::kRight);
  100. break;
  101. case MENU_ALIGNMENT_BOTTOM:
  102. DCHECK(!is_tablet_mode);
  103. base::RecordAction(base::UserMetricsAction("Shelf_AlignmentSetBottom"));
  104. SetShelfAlignmentPref(prefs, display_id_, ShelfAlignment::kBottom);
  105. break;
  106. case MENU_CHANGE_WALLPAPER:
  107. DCHECK(!ash::features::IsPersonalizationHubEnabled());
  108. shell->wallpaper_controller()->OpenWallpaperPickerIfAllowed();
  109. break;
  110. case MENU_PERSONALIZATION_HUB:
  111. DCHECK(ash::features::IsPersonalizationHubEnabled());
  112. // Record entry point metric to Personalization Hub through Home Screen.
  113. base::UmaHistogramEnumeration(kPersonalizationEntryPointHistogramName,
  114. PersonalizationEntryPoint::kHomeScreen);
  115. NewWindowDelegate::GetPrimary()->OpenPersonalizationHub();
  116. break;
  117. case MENU_HIDE_CONTINUE_SECTION:
  118. DCHECK(features::IsLauncherHideContinueSectionEnabled());
  119. DCHECK(is_tablet_mode);
  120. shell->app_list_controller()->SetHideContinueSection(true);
  121. break;
  122. case MENU_SHOW_CONTINUE_SECTION:
  123. DCHECK(features::IsLauncherHideContinueSectionEnabled());
  124. DCHECK(is_tablet_mode);
  125. shell->app_list_controller()->SetHideContinueSection(false);
  126. break;
  127. // Using reorder CommandId in ash/public/cpp/app_menu_constants.h
  128. case REORDER_BY_NAME_ALPHABETICAL:
  129. AppListModelProvider::Get()->model()->delegate()->RequestAppListSort(
  130. AppListSortOrder::kNameAlphabetical);
  131. break;
  132. case REORDER_BY_COLOR:
  133. AppListModelProvider::Get()->model()->delegate()->RequestAppListSort(
  134. AppListSortOrder::kColor);
  135. break;
  136. default:
  137. if (delegate_) {
  138. if (IsCommandIdAnAppLaunch(command_id)) {
  139. shell->app_list_controller()->RecordShelfAppLaunched();
  140. }
  141. delegate_->ExecuteCommand(true, command_id, event_flags, display_id_);
  142. }
  143. break;
  144. }
  145. }
  146. void ShelfContextMenuModel::AddShelfAndWallpaperItems() {
  147. PrefService* prefs =
  148. Shell::Get()->session_controller()->GetLastActiveUserPrefService();
  149. if (!prefs) // Null during startup.
  150. return;
  151. // In fullscreen, the shelf is either hidden or auto-hidden, depending on the
  152. // type of fullscreen. Do not show the auto-hide menu item while in fullscreen
  153. // because it is confusing when the preference appears not to apply.
  154. if (CanUserModifyShelfAutoHide(prefs) && !IsFullScreenMode(display_id_)) {
  155. const bool is_autohide_set =
  156. GetShelfAutoHideBehaviorPref(prefs, display_id_) ==
  157. ShelfAutoHideBehavior::kAlways;
  158. auto string_id = is_autohide_set
  159. ? IDS_ASH_SHELF_CONTEXT_MENU_ALWAYS_SHOW_SHELF
  160. : IDS_ASH_SHELF_CONTEXT_MENU_AUTO_HIDE;
  161. AddItemWithStringIdAndIcon(
  162. MENU_AUTO_HIDE, string_id,
  163. ui::ImageModel::FromVectorIcon(
  164. is_autohide_set ? kAlwaysShowShelfIcon : kAutoHideIcon,
  165. ui::kColorAshSystemUIMenuIcon));
  166. }
  167. // Only allow shelf alignment modifications by the logged in Gaia users
  168. // (regular or Family Link user). In tablet mode, the shelf alignment option
  169. // is not shown.
  170. LoginStatus status = Shell::Get()->session_controller()->login_status();
  171. if ((status == LoginStatus::USER || status == LoginStatus::CHILD) &&
  172. !Shell::Get()->tablet_mode_controller()->InTabletMode() &&
  173. prefs->FindPreference(prefs::kShelfAlignmentLocal)->IsUserModifiable()) {
  174. alignment_submenu_ = std::make_unique<ui::SimpleMenuModel>(this);
  175. constexpr int group = 0;
  176. alignment_submenu_->AddRadioItemWithStringId(
  177. MENU_ALIGNMENT_LEFT, IDS_ASH_SHELF_CONTEXT_MENU_ALIGN_LEFT, group);
  178. alignment_submenu_->AddRadioItemWithStringId(
  179. MENU_ALIGNMENT_BOTTOM, IDS_ASH_SHELF_CONTEXT_MENU_ALIGN_BOTTOM, group);
  180. alignment_submenu_->AddRadioItemWithStringId(
  181. MENU_ALIGNMENT_RIGHT, IDS_ASH_SHELF_CONTEXT_MENU_ALIGN_RIGHT, group);
  182. AddSubMenuWithStringIdAndIcon(
  183. MENU_ALIGNMENT_MENU, IDS_ASH_SHELF_CONTEXT_MENU_POSITION,
  184. alignment_submenu_.get(),
  185. ui::ImageModel::FromVectorIcon(kShelfPositionIcon,
  186. ui::kColorAshSystemUIMenuIcon));
  187. }
  188. if (ash::features::IsPersonalizationHubEnabled()) {
  189. AddItemWithStringIdAndIcon(
  190. MENU_PERSONALIZATION_HUB, IDS_AURA_OPEN_PERSONALIZATION_HUB,
  191. ui::ImageModel::FromVectorIcon(kPaintBrushIcon,
  192. ui::kColorAshSystemUIMenuIcon));
  193. } else if (Shell::Get()->wallpaper_controller()->CanOpenWallpaperPicker()) {
  194. AddItemWithStringIdAndIcon(
  195. MENU_CHANGE_WALLPAPER, IDS_AURA_SET_DESKTOP_WALLPAPER,
  196. ui::ImageModel::FromVectorIcon(kWallpaperIcon,
  197. ui::kColorAshSystemUIMenuIcon));
  198. }
  199. }
  200. } // namespace ash