1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_GLIC_WIDGET_LOCAL_HOTKEY_MANAGER_H_
#define CHROME_BROWSER_GLIC_WIDGET_LOCAL_HOTKEY_MANAGER_H_
#include "base/containers/flat_map.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_list_observer.h"
#include "components/prefs/pref_change_registrar.h"
#include "ui/base/accelerators/accelerator.h"
namespace glic {
class GlicWindowController;
// Manages hotkeys that are active within a specific local scope, such as the
// Glic window itself or the broader Chrome application when Glic is relevant.
// This class handles retrieving accelerator definitions (potentially from user
// preferences), registering them within the appropriate scope via a Delegate,
// and dispatching pressed accelerators back to the Delegate for handling.
class LocalHotkeyManager : public ui::AcceleratorTarget {
public:
// Enum representing the different hotkeys managed by this class.
enum class Hotkey {
// Close the Glic window. Only works when the Glic window has focus.
kClose,
// Toggle focus between the Glic window and the last active
// browser window.
kFocusToggle,
#if BUILDFLAG(IS_WIN)
// Show the title bar context menu
kTitleBarContextMenu,
#endif
};
constexpr static const char* HotkeyToString(Hotkey hotkey) {
switch (hotkey) {
case Hotkey::kClose:
return "kClose";
case Hotkey::kFocusToggle:
return "kFocusToggle";
#if BUILDFLAG(IS_WIN)
case Hotkey::kTitleBarContextMenu:
return "kTitleBarContextMenu";
#endif
}
}
// Interface for managing the lifetime of a registered hotkey.
// Implementations handle the specific registration/unregistration logic
// for their scope (e.g., adding/removing from a views::View or
// views::FocusManager).
class ScopedHotkeyRegistration {
public:
virtual ~ScopedHotkeyRegistration() = default;
};
// Delegate interface responsible for the actual registration and handling
// of hotkeys within a specific scope (e.g., Glic window, application-wide).
class Delegate {
public:
virtual ~Delegate() = default;
virtual const base::span<const Hotkey> GetSupportedHotkeys() const = 0;
// Creates a ScopedHotkeyRegistration for the given accelerator.
// The implementation should register the hotkey within its specific scope
// and return an object that unregisters it upon destruction.
virtual std::unique_ptr<ScopedHotkeyRegistration>
CreateScopedHotkeyRegistration(
ui::Accelerator accelerator,
base::WeakPtr<ui::AcceleratorTarget> target) = 0;
// Called when a registered hotkey associated with this manager is pressed.
// Returns true if the accelerator was handled, false otherwise.
virtual bool AcceleratorPressed(Hotkey) = 0;
};
explicit LocalHotkeyManager(
base::WeakPtr<GlicWindowController> window_controller,
std::unique_ptr<Delegate> delegate);
~LocalHotkeyManager() override;
// Returns the default accelerator for a given hotkey.
static ui::Accelerator GetDefaultAccelerator(Hotkey hotkey_enum);
// Returns the hardcoded, non-configurable accelerators for a given hotkey.
// CHECKs if the hotkey is not defined as static (i.e., not in
// kHotkeyToStaticAcceleratorsMap).
static base::span<const ui::Accelerator> GetStaticAccelerators(
LocalHotkeyManager::Hotkey hotkey);
// Returns the current configurable accelerator for a given hotkey,
// potentially reading from user preferences. Falls back to the default if
// no preference is set or the preference is invalid. CHECKs if the passed
// hotkey_enum is not defined as configurable.
static ui::Accelerator GetConfigurableAccelerator(Hotkey hotkey_enum);
// Returns the Hotkey enum value corresponding to the given accelerator.
// CHECKs if the accelerator is not supported by this manager.
Hotkey GetHotkeyEnum(ui::Accelerator accelerator);
void InitializeAccelerators();
// ui::AcceleratorTarget:
bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
bool CanHandleAccelerators() const override;
base::WeakPtr<LocalHotkeyManager> GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
private:
std::vector<ui::Accelerator> GetAccelerators(Hotkey hotkey);
void RegisterHotkey(Hotkey hotkey_enum);
base::WeakPtr<GlicWindowController> window_controller_;
std::unique_ptr<Delegate> delegate_;
PrefChangeRegistrar pref_registrar_;
base::flat_map<Hotkey, std::vector<std::unique_ptr<ScopedHotkeyRegistration>>>
hotkey_registrations_;
base::WeakPtrFactory<LocalHotkeyManager> weak_ptr_factory_{this};
};
} // namespace glic
#endif // CHROME_BROWSER_GLIC_WIDGET_LOCAL_HOTKEY_MANAGER_H_
|