| // Copyright 2018 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ash/system/caps_lock_notification_controller.h" |
| |
| #include "ash/accessibility/accessibility_controller.h" |
| #include "ash/constants/notifier_catalogs.h" |
| #include "ash/public/cpp/notification_utils.h" |
| #include "ash/resources/vector_icons/vector_icons.h" |
| #include "ash/root_window_controller.h" |
| #include "ash/session/session_controller_impl.h" |
| #include "ash/shell.h" |
| #include "ash/strings/grit/ash_strings.h" |
| #include "ash/system/input_device_settings/input_device_settings_controller_impl.h" |
| #include "ash/system/status_area_widget.h" |
| #include "ash/system/unified/unified_system_tray.h" |
| #include "ash/system/unified/unified_system_tray_model.h" |
| #include "base/metrics/user_metrics.h" |
| #include "components/prefs/pref_registry_simple.h" |
| #include "components/prefs/pref_service.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/events/ash/mojom/modifier_key.mojom.h" |
| #include "ui/events/ash/pref_names.h" |
| #include "ui/message_center/message_center.h" |
| #include "ui/message_center/public/cpp/notification.h" |
| |
| using message_center::MessageCenter; |
| using message_center::Notification; |
| using SystemTrayButtonSize = ash::UnifiedSystemTrayModel::SystemTrayButtonSize; |
| |
| namespace ash { |
| |
| namespace { |
| |
| const char kCapsLockNotificationId[] = "capslock"; |
| const char kNotifierCapsLock[] = "ash.caps-lock"; |
| |
| int GetMessageStringId() { |
| const ash::mojom::Keyboard* keyboard = |
| Shell::Get() |
| ->input_device_settings_controller() |
| ->GetGeneralizedKeyboard(); |
| |
| if (keyboard != nullptr) { |
| // If the keyboard has function key, return function key message id. |
| if (std::ranges::find(keyboard->modifier_keys, |
| ui::mojom::ModifierKey::kFunction) != |
| keyboard->modifier_keys.end()) { |
| return IDS_ASH_STATUS_TRAY_CAPS_LOCK_CANCEL_BY_FN_QUICK_INSERT; |
| } |
| |
| // If the search key is remapped to kCapsLock, return search key message id. |
| auto iter = keyboard->settings->modifier_remappings.find( |
| ui::mojom::ModifierKey::kMeta); |
| if (iter != keyboard->settings->modifier_remappings.end() && |
| iter->second == ui::mojom::ModifierKey::kCapsLock) { |
| return IDS_ASH_STATUS_TRAY_CAPS_LOCK_CANCEL_BY_SEARCH; |
| } |
| } |
| |
| // Otherwise return alt search key message id. |
| return IDS_ASH_STATUS_TRAY_CAPS_LOCK_CANCEL_BY_ALT_SEARCH; |
| } |
| |
| std::unique_ptr<Notification> CreateNotification() { |
| const gfx::VectorIcon& capslock_icon = |
| features::IsModifierSplitEnabled() |
| ? kModifierSplitNotificationCapslockIcon |
| : kNotificationCapslockIcon; |
| std::unique_ptr<Notification> notification = ash::CreateSystemNotificationPtr( |
| message_center::NOTIFICATION_TYPE_SIMPLE, kCapsLockNotificationId, |
| l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_CAPS_LOCK_ENABLED), |
| l10n_util::GetStringUTF16(GetMessageStringId()), |
| std::u16string() /* display_source */, GURL(), |
| message_center::NotifierId(message_center::NotifierType::SYSTEM_COMPONENT, |
| kNotifierCapsLock, |
| NotificationCatalogName::kCapsLock), |
| message_center::RichNotificationData(), nullptr, capslock_icon, |
| message_center::SystemNotificationWarningLevel::NORMAL); |
| notification->set_pinned(true); |
| |
| SystemTrayButtonSize primary_tray_button_size = |
| Shell::GetPrimaryRootWindowController() |
| ->GetStatusAreaWidget() |
| ->unified_system_tray() |
| ->model() |
| ->GetSystemTrayButtonSize(); |
| |
| // Set the priority to low to prevent the notification showing as a popup in |
| // medium or large size tray button because we already show an icon in tray |
| // for this in the feature. |
| if (primary_tray_button_size != SystemTrayButtonSize::kSmall) { |
| notification->set_priority(message_center::LOW_PRIORITY); |
| } |
| |
| return notification; |
| } |
| |
| } // namespace |
| |
| CapsLockNotificationController::CapsLockNotificationController() { |
| Shell::Get()->ime_controller()->AddObserver(this); |
| } |
| |
| CapsLockNotificationController::~CapsLockNotificationController() { |
| Shell::Get()->ime_controller()->RemoveObserver(this); |
| } |
| |
| void CapsLockNotificationController::OnCapsLockChanged(bool enabled) { |
| // Send an a11y alert. |
| Shell::Get()->accessibility_controller()->TriggerAccessibilityAlert( |
| enabled ? AccessibilityAlert::CAPS_ON : AccessibilityAlert::CAPS_OFF); |
| |
| if (enabled) { |
| base::RecordAction(base::UserMetricsAction("StatusArea_CapsLock_Popup")); |
| MessageCenter::Get()->AddNotification(CreateNotification()); |
| } else { |
| MessageCenter::Get()->RemoveNotification(kCapsLockNotificationId, false); |
| } |
| } |
| |
| } // namespace ash |