Flutter Engine
The Flutter Engine
keyboard_key_handler.h
Go to the documentation of this file.
1// Copyright 2013 The Flutter 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
5#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_KEYBOARD_KEY_HANDLER_H_
6#define FLUTTER_SHELL_PLATFORM_WINDOWS_KEYBOARD_KEY_HANDLER_H_
7
8#include <windows.h>
9#include <deque>
10#include <map>
11#include <memory>
12#include <string>
13
14#include "flutter/fml/macros.h"
15#include "flutter/shell/platform/common/client_wrapper/include/flutter/binary_messenger.h"
16#include "flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h"
17#include "flutter/shell/platform/common/client_wrapper/include/flutter/method_channel.h"
18#include "flutter/shell/platform/windows/keyboard_handler_base.h"
19
20namespace flutter {
21
22// Handles key events.
23//
24// This class detects whether an incoming event is a redispatched one,
25// dispatches native events to delegates and collect their responses,
26// and redispatches events unhandled by Flutter back to the system.
27// See |KeyboardHook| for more information about dispatching.
28//
29// This class owns multiple |KeyboardKeyHandlerDelegate|s, which
30// implements the exact behavior to asynchronously handle events. In
31// reality, this design is only to support sending events through
32// "channel" (RawKeyEvent) and "embedder" (KeyEvent) simultaneously,
33// the former of which shall be removed after the deprecation window
34// of the RawKeyEvent system.
36 public:
37 // An interface for concrete definition of how to asynchronously handle key
38 // events.
40 public:
41 // Defines how to how to asynchronously handle key events.
42 //
43 // |KeyboardHook| should invoke |callback| with the response (whether the
44 // event is handled) later for exactly once.
45 virtual void KeyboardHook(int key,
46 int scancode,
47 int action,
48 char32_t character,
49 bool extended,
50 bool was_down,
52
53 virtual void SyncModifiersIfNeeded(int modifiers_state) = 0;
54
55 virtual std::map<uint64_t, uint64_t> GetPressedState() = 0;
56
58 };
59
60 // Create a |KeyboardKeyHandler| by specifying the messenger
61 // through which the messages are sent.
63
65
66 // Init the keyboard channel used to answer to pressed state queries.
68
69 // Add a delegate that handles events received by |KeyboardHook|.
70 void AddDelegate(std::unique_ptr<KeyboardKeyHandlerDelegate> delegate);
71
72 // Synthesize modifier keys events if needed.
73 void SyncModifiersIfNeeded(int modifiers_state) override;
74
75 // Handles a key event.
76 //
77 // Returns whether this handler claims to handle the event, which is true if
78 // and only if the event is a non-synthesized event.
79 //
80 // Windows requires a synchronous response of whether a key event should be
81 // handled, while the query to Flutter is always asynchronous. This is
82 // resolved by the "redispatching" algorithm: by default, the response to a
83 // fresh event is always true. The event is then sent to the framework.
84 // If the framework later decides not to handle the event, this class will
85 // create an identical event and dispatch it to the system, and remember all
86 // synthesized events. The fist time an exact event (by |ComputeEventHash|) is
87 // received in the future, the new event is considered a synthesized one,
88 // causing |KeyboardHook| to return false to fall back to other keyboard
89 // handlers.
90 //
91 // Whether a non-synthesized event is considered handled by the framework is
92 // decided by dispatching the event to all delegates, simultaneously,
93 // unconditionally, in insertion order, and collecting their responses later.
94 // It's not supported to prevent any delegates to process the events, because
95 // in reality this will only support 2 hardcoded delegates, and only to
96 // continue supporting the legacy API (channel) during the deprecation window,
97 // after which the channel delegate should be removed.
98 //
99 // Inherited from |KeyboardHandlerBase|.
100 void KeyboardHook(int key,
101 int scancode,
102 int action,
103 char32_t character,
104 bool extended,
105 bool was_down,
106 KeyEventCallback callback) override;
107
108 // Returns the keyboard pressed state.
109 //
110 // Returns the keyboard pressed state. The dictionary contains one entry per
111 // pressed keys, mapping from the logical key to the physical key.
112 std::map<uint64_t, uint64_t> GetPressedState() override;
113
114 private:
115 struct PendingEvent {
116 // Self-incrementing ID attached to an event sent to the framework.
117 uint64_t sequence_id;
118 // The number of delegates that haven't replied.
119 size_t unreplied;
120 // Whether any replied delegates reported true (handled).
121 bool any_handled;
122
123 // Where to report the delegates' result to.
124 //
125 // Typically a callback provided by KeyboardManager32.
127 };
128
129 void ResolvePendingEvent(uint64_t sequence_id, bool handled);
130
131 // Called when a method is called on |channel_|;
132 void HandleMethodCall(
135
136 std::vector<std::unique_ptr<KeyboardKeyHandlerDelegate>> delegates_;
137
138 // The queue of key events that have been sent to the framework but have not
139 // yet received a response.
140 std::deque<std::unique_ptr<PendingEvent>> pending_responds_;
141
142 // The sequence_id attached to the last event sent to the framework.
143 uint64_t last_sequence_id_;
144
145 // The Flutter system channel for keyboard state messages.
146 std::unique_ptr<flutter::MethodChannel<EncodableValue>> channel_;
147
148 FML_DISALLOW_COPY_AND_ASSIGN(KeyboardKeyHandler);
149};
150
151} // namespace flutter
152
153#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_KEYBOARD_KEY_HANDLER_H_
std::function< void(bool)> KeyEventCallback
virtual std::map< uint64_t, uint64_t > GetPressedState()=0
virtual void KeyboardHook(int key, int scancode, int action, char32_t character, bool extended, bool was_down, KeyEventCallback callback)=0
virtual void SyncModifiersIfNeeded(int modifiers_state)=0
void SyncModifiersIfNeeded(int modifiers_state) override
KeyboardKeyHandler(flutter::BinaryMessenger *messenger)
void KeyboardHook(int key, int scancode, int action, char32_t character, bool extended, bool was_down, KeyEventCallback callback) override
void AddDelegate(std::unique_ptr< KeyboardKeyHandlerDelegate > delegate)
std::map< uint64_t, uint64_t > GetPressedState() override
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
G_BEGIN_DECLS G_MODULE_EXPORT FlMethodCall * method_call
GAsyncResult * result