| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef ASH_ACCELERATORS_ASH_ACCELERATOR_CONFIGURATION_H_ |
| #define ASH_ACCELERATORS_ASH_ACCELERATOR_CONFIGURATION_H_ |
| |
| #include <map> |
| #include <vector> |
| |
| #include "ash/accelerators/accelerator_table.h" |
| #include "ash/ash_export.h" |
| #include "ash/public/cpp/accelerator_configuration.h" |
| #include "ash/public/cpp/accelerators.h" |
| #include "ash/public/cpp/session/session_observer.h" |
| #include "ash/public/mojom/accelerator_configuration.mojom-shared.h" |
| #include "ash/public/mojom/accelerator_configuration.mojom.h" |
| #include "ash/public/mojom/accelerator_info.mojom.h" |
| #include "base/containers/flat_set.h" |
| #include "base/containers/span.h" |
| #include "base/observer_list.h" |
| #include "base/observer_list_types.h" |
| #include "base/values.h" |
| #include "components/prefs/pref_registry_simple.h" |
| #include "mojo/public/cpp/bindings/clone_traits.h" |
| #include "ui/base/accelerators/accelerator_map.h" |
| |
| namespace { |
| // Represents the state of the accelerator modification in the prefs. |
| // `kAdd` - User adds a custom accelerator ontop of the default accelerators. |
| // `kRemove` - User removes a default accelerator. |
| // Removing a user-added accelerator will not result in a new action, rather it |
| // will remove the pref override entry with `kAdd`. |
| enum class AcceleratorModificationAction { |
| kAdd = 0, |
| kRemove = 1, |
| }; |
| |
| // Represents the underlying data of a modified accelerator in the pref |
| // storage. |
| struct AcceleratorModificationData { |
| ui::Accelerator accelerator; |
| AcceleratorModificationAction action; |
| }; |
| } // namespace |
| |
| namespace ash { |
| |
| // Implementor of AcceleratorConfiguration for Ash accelerators. |
| // This class exist as a way to provide access to view and modify Ash |
| // accelerators. |
| class ASH_EXPORT AshAcceleratorConfiguration : public AcceleratorConfiguration, |
| public SessionObserver { |
| public: |
| // Observer to notify clients of when accelerators are updated. |
| // Clients can receive a list of accelerators via |
| // `AshAcceleratorConfiguration::GetAllAccelerators()`. |
| class Observer : public base::CheckedObserver { |
| public: |
| ~Observer() override = default; |
| virtual void OnAcceleratorsUpdated() = 0; |
| }; |
| |
| AshAcceleratorConfiguration(); |
| AshAcceleratorConfiguration(const AshAcceleratorConfiguration&) = delete; |
| AshAcceleratorConfiguration& operator=(const AshAcceleratorConfiguration&) = |
| delete; |
| ~AshAcceleratorConfiguration() override; |
| |
| static void RegisterProfilePrefs(PrefRegistrySimple* registry); |
| |
| // AcceleratorConfiguration:: |
| const std::vector<ui::Accelerator>& GetAcceleratorsForAction( |
| AcceleratorActionId action_id) override; |
| // Whether the source is mutable and shortcuts can be changed. If this returns |
| // false then any of the Add/Remove/Replace class will DCHECK. The two Restore |
| // methods will be no-ops. |
| bool IsMutable() const override; |
| // Return true if the accelerator is deprecated. |
| bool IsDeprecated(const ui::Accelerator& accelerator) const override; |
| mojom::AcceleratorConfigResult AddUserAccelerator( |
| AcceleratorActionId action_id, |
| const ui::Accelerator& accelerator) override; |
| // TODO(jimmyxgong): Implement disabling accelerators after pref storage is |
| // implemented. |
| mojom::AcceleratorConfigResult RemoveAccelerator( |
| AcceleratorActionId action_id, |
| const ui::Accelerator& accelerator) override; |
| mojom::AcceleratorConfigResult ReplaceAccelerator( |
| AcceleratorActionId action_id, |
| const ui::Accelerator& old_accelerator, |
| const ui::Accelerator& new_accelerator) override; |
| mojom::AcceleratorConfigResult RestoreDefault( |
| AcceleratorActionId action_id) override; |
| mojom::AcceleratorConfigResult RestoreAllDefaults() override; |
| |
| // SessionObserver:: |
| void OnActiveUserPrefServiceChanged(PrefService* pref_service) override; |
| |
| void Initialize(); |
| void Initialize(base::span<const AcceleratorData> accelerators); |
| void InitializeDeprecatedAccelerators( |
| base::span<const DeprecatedAcceleratorData> deprecated_datas, |
| base::span<const AcceleratorData> deprecated_accelerators); |
| |
| void AddObserver(Observer* observer); |
| void RemoveObserver(Observer* observer); |
| bool HasObserver(Observer* observer); |
| |
| const AcceleratorAction* FindAcceleratorAction( |
| const ui::Accelerator& accelerator) const; |
| |
| const std::vector<ui::Accelerator>& GetAllAccelerators() { |
| return accelerators_; |
| } |
| |
| void SetUsePositionalLookup(bool use_positional_lookup) { |
| accelerator_to_id_.set_use_positional_lookup(use_positional_lookup); |
| } |
| |
| // Returns a nullptr if `action` is not a deprecated action, otherwise |
| // returns the deprecated data. |
| const DeprecatedAcceleratorData* GetDeprecatedAcceleratorData( |
| AcceleratorActionId action); |
| |
| // Returns the ID of the action if `accelerator` is a default accelerator. |
| // If there is no ID found, returns absl::nullopt. |
| absl::optional<AcceleratorAction> GetIdForDefaultAccelerator( |
| ui::Accelerator accelerator); |
| |
| // Returns the default accelerators of a given accelerator ID. |
| std::vector<ui::Accelerator> GetDefaultAcceleratorsForId( |
| AcceleratorActionId id); |
| |
| // Returns true if the `id` is a valid ash accelerator ID. |
| bool IsValid(uint32_t id) const; |
| |
| private: |
| // A map for looking up actions from accelerators. |
| using AcceleratorActionMap = ui::AcceleratorMap<AcceleratorAction>; |
| |
| void InitializeDeprecatedAccelerators(); |
| |
| void AddAccelerators(base::span<const AcceleratorData> accelerators); |
| |
| void ApplyPrefOverrides(); |
| void SaveOverridePrefChanges(); |
| void UpdateOverrides(AcceleratorActionId action_id, |
| const ui::Accelerator& accelerator, |
| AcceleratorModificationAction action); |
| |
| // Remove the accelerator, does not notify observers. |
| mojom::AcceleratorConfigResult DoRemoveAccelerator( |
| AcceleratorActionId action_id, |
| const ui::Accelerator& accelerator, |
| bool save_override); |
| |
| // Adds the accelerator, does not notify observers. |
| mojom::AcceleratorConfigResult DoAddAccelerator( |
| AcceleratorActionId action_id, |
| const ui::Accelerator& accelerator, |
| bool save_override); |
| |
| // Replace the accelerator, does not notify observers. |
| mojom::AcceleratorConfigResult DoReplaceAccelerator( |
| AcceleratorActionId action_id, |
| const ui::Accelerator& old_accelerator, |
| const ui::Accelerator& new_accelerator); |
| |
| void NotifyAcceleratorsUpdated(); |
| |
| void UpdateAndNotifyAccelerators(); |
| |
| // Checks that the accelerators are in a valid state, if not reset back to |
| // the default state and clear the override prefs. |
| bool AreAcceleratorsValid(); |
| |
| // Resets all accelerator mappings to the the system default. |
| void ResetAllAccelerators(); |
| |
| // A local copy of the pref overrides, allows modifying the overrides before |
| // updating the override pref. |
| base::Value::Dict accelerator_overrides_; |
| |
| std::vector<ui::Accelerator> accelerators_; |
| |
| AcceleratorActionMap deprecated_accelerators_to_id_; |
| |
| // A map of accelerator ID's that are deprecated. |
| std::map<AcceleratorActionId, const DeprecatedAcceleratorData*> |
| actions_with_deprecations_; |
| |
| // One accelerator action ID can potentially have multiple accelerators |
| // associated with it. |
| ActionIdToAcceleratorsMap id_to_accelerators_; |
| // A map from accelerators to the AcceleratorAction values, which are used in |
| // the implementation. |
| AcceleratorActionMap accelerator_to_id_; |
| |
| // The following are caches for system default accelerators. |
| // These should not be modified after the initial instantiation. Provides a |
| // reference to the defaults in the event of customization or resets. |
| // These are effectively const and should not be modified after the initial |
| // data is set. |
| ActionIdToAcceleratorsMap default_id_to_accelerators_cache_; |
| AcceleratorActionMap default_accelerators_to_id_cache_; |
| std::map<AcceleratorActionId, const DeprecatedAcceleratorData*> |
| default_actions_with_deprecations_cache_; |
| AcceleratorActionMap default_deprecated_accelerators_to_id_cache_; |
| |
| // List of all observer clients. |
| base::ObserverList<Observer> observer_list_; |
| }; |
| |
| } // namespace ash |
| |
| #endif // ASH_ACCELERATORS_ASH_ACCELERATOR_CONFIGURATION_H_ |