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 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
|
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_EXO_KEYBOARD_H_
#define COMPONENTS_EXO_KEYBOARD_H_
#include <memory>
#include "ash/ime/ime_controller_impl.h"
#include "ash/public/cpp/keyboard/keyboard_controller_observer.h"
#include "ash/public/mojom/input_device_settings.mojom.h"
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "base/time/time.h"
#include "components/exo/key_state.h"
#include "components/exo/keyboard_observer.h"
#include "components/exo/seat_observer.h"
#include "components/exo/surface_observer.h"
#include "ui/events/event.h"
#include "ui/events/event_handler.h"
namespace ui {
enum class DomCode : uint32_t;
class KeyEvent;
}
namespace exo {
class KeyboardDelegate;
class KeyboardDeviceConfigurationDelegate;
class Seat;
class Surface;
// This class implements a client keyboard that represents one or more keyboard
// devices.
class Keyboard : public ui::EventHandler,
public SurfaceObserver,
public SeatObserver,
public ash::KeyboardControllerObserver,
public ash::ImeController::Observer {
public:
Keyboard(std::unique_ptr<KeyboardDelegate> delegate, Seat* seat);
Keyboard(const Keyboard&) = delete;
Keyboard& operator=(const Keyboard&) = delete;
~Keyboard() override;
KeyboardDelegate* delegate() const { return delegate_.get(); }
bool HasDeviceConfigurationDelegate() const;
void SetDeviceConfigurationDelegate(
KeyboardDeviceConfigurationDelegate* delegate);
// Management of the observer list.
void AddObserver(KeyboardObserver* observer);
bool HasObserver(KeyboardObserver* observer) const;
void RemoveObserver(KeyboardObserver* observer);
void SetNeedKeyboardKeyAcks(bool need_acks);
bool AreKeyboardKeyAcksNeeded() const;
void AckKeyboardKey(uint32_t serial, bool handled);
// Overridden from ui::EventHandler:
void OnKeyEvent(ui::KeyEvent* event) override;
// Overridden from SurfaceObserver:
void OnSurfaceDestroying(Surface* surface) override;
// Overridden from SeatObserver:
void OnSurfaceFocused(Surface* gained_focus,
Surface* lost_focus,
bool has_focused_surface) override;
void OnKeyboardModifierUpdated() override;
// Overridden from ash::KeyboardControllerObserver:
void OnKeyboardEnableFlagsChanged(
const std::set<keyboard::KeyboardEnableFlag>& flags) override;
void OnKeyRepeatSettingsChanged(
const ash::KeyRepeatSettings& settings) override;
// Overridden from ash::ImeController::Observer:
void OnCapsLockChanged(bool enabled) override;
void OnKeyboardLayoutNameChanged(const std::string& layout_name) override;
Surface* focused_surface_for_testing() const { return focus_; }
private:
// Returns a set of keys with keys that should not be handled by the surface
// filtered out from pressed_keys_.
base::flat_map<PhysicalCode, base::flat_set<KeyState>>
GetPressedKeysForSurface(Surface* surface);
// Change keyboard focus to |surface|.
void SetFocus(Surface* surface);
// Processes expired key state changes in |pending_key_acks_| as they have not
// been acknowledged.
void ProcessExpiredPendingKeyAcks();
// Schedule next call of ProcessExpiredPendingKeyAcks after |delay|
void ScheduleProcessExpiredPendingKeyAcks(base::TimeDelta delay);
// Adds/Removes pre or post event handler depending on if key acks are needed.
// If key acks are needed, pre target handler will be added because this class
// wants to dispatch keys before they are consumed by Chrome. Otherwise, post
// target handler will be added because all accelerators should be handled by
// Chrome before they are dispatched by this class.
void AddEventHandler();
void RemoveEventHandler();
// Notify the current keyboard type.
void UpdateKeyboardType();
// The delegate instance that all events except for events about device
// configuration are dispatched to.
std::unique_ptr<KeyboardDelegate> delegate_;
// Seat that the Keyboard recieves focus events from.
const raw_ptr<Seat> seat_;
// The delegate instance that events about device configuration are dispatched
// to.
raw_ptr<KeyboardDeviceConfigurationDelegate> device_configuration_delegate_ =
nullptr;
// Indicates that each key event is expected to be acknowledged.
bool are_keyboard_key_acks_needed_ = false;
// The current focus surface for the keyboard.
raw_ptr<Surface> focus_ = nullptr;
// Set of currently pressed keys. First value is a platform code and second
// value is the code that was delivered to client. See Seat.h for more
// details.
base::flat_map<PhysicalCode, base::flat_set<KeyState>> pressed_keys_;
// Key state changes that are expected to be acknowledged.
using KeyStateChange = std::pair<ui::KeyEvent, base::TimeTicks>;
base::flat_map<uint32_t, KeyStateChange> pending_key_acks_;
// Indicates that a ProcessExpiredPendingKeyAcks call is pending.
bool process_expired_pending_key_acks_pending_ = false;
// Delay until a key state change expected to be acknowledged is expired.
const base::TimeDelta expiration_delay_for_pending_key_acks_;
// Tracks whether the last key event is the target of autorepeat.
bool auto_repeat_enabled_ = true;
// True when the ARC app window is focused.
// TODO(yhanada, https://crbug.com/847500): Remove this when we find a way to
// fix https://crbug.com/847500 without breaking ARC++ apps.
bool focused_on_ime_supported_surface_ = false;
base::ObserverList<KeyboardObserver>::Unchecked observer_list_;
base::WeakPtrFactory<Keyboard> weak_ptr_factory_{this};
};
} // namespace exo
#endif // COMPONENTS_EXO_KEYBOARD_H_
|