Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 7ad07f6

Browse files
committed
[Windows] Return keyboard pressed state
1 parent 036c58f commit 7ad07f6

9 files changed

+251
-9
lines changed

shell/platform/windows/flutter_windows_engine.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,7 @@ FlutterWindowsEngine::CreateKeyboardKeyHandler(
631631
BinaryMessenger* messenger,
632632
KeyboardKeyEmbedderHandler::GetKeyStateHandler get_key_state,
633633
KeyboardKeyEmbedderHandler::MapVirtualKeyToScanCode map_vk_to_scan) {
634-
auto keyboard_key_handler = std::make_unique<KeyboardKeyHandler>();
634+
auto keyboard_key_handler = std::make_unique<KeyboardKeyHandler>(messenger);
635635
keyboard_key_handler->AddDelegate(
636636
std::make_unique<KeyboardKeyEmbedderHandler>(
637637
[this](const FlutterKeyEvent& event, FlutterKeyEventCallback callback,
@@ -641,6 +641,7 @@ FlutterWindowsEngine::CreateKeyboardKeyHandler(
641641
get_key_state, map_vk_to_scan));
642642
keyboard_key_handler->AddDelegate(
643643
std::make_unique<KeyboardKeyChannelHandler>(messenger));
644+
keyboard_key_handler->InitKeyboardChannel();
644645
return keyboard_key_handler;
645646
}
646647

shell/platform/windows/keyboard_handler_base.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ class KeyboardHandlerBase {
3333
// If needed, synthesize modifier keys events by comparing the
3434
// given modifiers state to the known pressing state..
3535
virtual void SyncModifiersIfNeeded(int modifiers_state) = 0;
36+
37+
// Returns the keyboard pressed state.
38+
//
39+
// Returns the keyboard pressed state. The map contains one entry per
40+
// pressed keys, mapping from the logical key to the physical key.
41+
virtual std::map<uint64_t, uint64_t> GetPressedState() = 0;
3642
};
3743

3844
} // namespace flutter

shell/platform/windows/keyboard_key_channel_handler.cc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,12 @@ KeyboardKeyChannelHandler::KeyboardKeyChannelHandler(
110110
KeyboardKeyChannelHandler::~KeyboardKeyChannelHandler() = default;
111111

112112
void KeyboardKeyChannelHandler::SyncModifiersIfNeeded(int modifiers_state) {
113-
// Do nothing
113+
// Do nothing.
114+
}
115+
116+
std::map<uint64_t, uint64_t> KeyboardKeyChannelHandler::GetPressedState() {
117+
std::map<uint64_t, uint64_t> Empty_State;
118+
return Empty_State;
114119
}
115120

116121
void KeyboardKeyChannelHandler::KeyboardHook(

shell/platform/windows/keyboard_key_channel_handler.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ class KeyboardKeyChannelHandler
4141

4242
void SyncModifiersIfNeeded(int modifiers_state);
4343

44+
std::map<uint64_t, uint64_t> GetPressedState();
45+
4446
private:
4547
// The Flutter system channel for key event messages.
4648
std::unique_ptr<flutter::BasicMessageChannel<rapidjson::Document>> channel_;

shell/platform/windows/keyboard_key_embedder_handler.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,10 @@ void KeyboardKeyEmbedderHandler::KeyboardHook(
350350
}
351351
}
352352

353+
std::map<uint64_t, uint64_t> KeyboardKeyEmbedderHandler::GetPressedState() {
354+
return pressingRecords_;
355+
}
356+
353357
void KeyboardKeyEmbedderHandler::UpdateLastSeenCriticalKey(
354358
int virtual_key,
355359
uint64_t physical_key,

shell/platform/windows/keyboard_key_embedder_handler.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ class KeyboardKeyEmbedderHandler
7373

7474
void SyncModifiersIfNeeded(int modifiers_state) override;
7575

76+
std::map<uint64_t, uint64_t> GetPressedState() override;
77+
7678
private:
7779
struct PendingResponse {
7880
std::function<void(bool, uint64_t)> callback;

shell/platform/windows/keyboard_key_handler.cc

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <windows.h>
88

99
#include "flutter/fml/logging.h"
10+
#include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_method_codec.h"
1011
#include "flutter/shell/platform/windows/keyboard_utils.h"
1112

1213
namespace flutter {
@@ -17,15 +18,51 @@ namespace {
1718
// emitting a warning on the console about unhandled events.
1819
static constexpr int kMaxPendingEvents = 1000;
1920

21+
// The name of the channel for keyboard state queries.
22+
static constexpr char kChannelName[] = "flutter/keyboard";
23+
24+
static constexpr char kGetKeyboardStateMethod[] = "getKeyboardState";
25+
2026
} // namespace
2127

2228
KeyboardKeyHandler::KeyboardKeyHandlerDelegate::~KeyboardKeyHandlerDelegate() =
2329
default;
2430

25-
KeyboardKeyHandler::KeyboardKeyHandler() : last_sequence_id_(1) {}
31+
KeyboardKeyHandler::KeyboardKeyHandler(flutter::BinaryMessenger* messenger)
32+
: last_sequence_id_(1),
33+
channel_(std::make_unique<MethodChannel<EncodableValue>>(
34+
messenger,
35+
kChannelName,
36+
&StandardMethodCodec::GetInstance())) {}
2637

2738
KeyboardKeyHandler::~KeyboardKeyHandler() = default;
2839

40+
void KeyboardKeyHandler::InitKeyboardChannel() {
41+
channel_->SetMethodCallHandler(
42+
[this](const MethodCall<EncodableValue>& call,
43+
std::unique_ptr<MethodResult<EncodableValue>> result) {
44+
HandleMethodCall(call, std::move(result));
45+
});
46+
}
47+
48+
void KeyboardKeyHandler::HandleMethodCall(
49+
const MethodCall<EncodableValue>& method_call,
50+
std::unique_ptr<MethodResult<EncodableValue>> result) {
51+
const std::string& method = method_call.method_name();
52+
if (method.compare(kGetKeyboardStateMethod) == 0) {
53+
EncodableMap value;
54+
const auto& pressed_state = GetPressedState();
55+
for (const auto& pressed_key : pressed_state) {
56+
EncodableValue physical_value(static_cast<long long>(pressed_key.first));
57+
EncodableValue logical_value(static_cast<long long>(pressed_key.second));
58+
value[physical_value] = logical_value;
59+
}
60+
result->Success(EncodableValue(value));
61+
} else {
62+
result->NotImplemented();
63+
}
64+
}
65+
2966
void KeyboardKeyHandler::AddDelegate(
3067
std::unique_ptr<KeyboardKeyHandlerDelegate> delegate) {
3168
delegates_.push_back(std::move(delegate));
@@ -37,6 +74,12 @@ void KeyboardKeyHandler::SyncModifiersIfNeeded(int modifiers_state) {
3774
key_embedder_handler->SyncModifiersIfNeeded(modifiers_state);
3875
}
3976

77+
std::map<uint64_t, uint64_t> KeyboardKeyHandler::GetPressedState() {
78+
// The embedder responder is the first element in delegates_.
79+
auto& key_embedder_handler = delegates_.front();
80+
return key_embedder_handler->GetPressedState();
81+
}
82+
4083
void KeyboardKeyHandler::KeyboardHook(int key,
4184
int scancode,
4285
int action,

shell/platform/windows/keyboard_key_handler.h

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@
77

88
#include <windows.h>
99
#include <deque>
10+
#include <map>
1011
#include <memory>
1112
#include <string>
1213

1314
#include "flutter/fml/macros.h"
14-
#include "flutter/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.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"
1518
#include "flutter/shell/platform/windows/keyboard_handler_base.h"
16-
#include "rapidjson/document.h"
1719

1820
namespace flutter {
1921

@@ -50,14 +52,20 @@ class KeyboardKeyHandler : public KeyboardHandlerBase {
5052

5153
virtual void SyncModifiersIfNeeded(int modifiers_state) = 0;
5254

55+
virtual std::map<uint64_t, uint64_t> GetPressedState() = 0;
56+
5357
virtual ~KeyboardKeyHandlerDelegate();
5458
};
5559

56-
// Create a KeyboardKeyHandler.
57-
explicit KeyboardKeyHandler();
60+
// Create a |KeyboardKeyHandler| by specifying the messenger
61+
// through which the messages are sent.
62+
explicit KeyboardKeyHandler(flutter::BinaryMessenger* messenger);
5863

5964
~KeyboardKeyHandler();
6065

66+
// Init the keyboard channel used to answer to pressed state queries.
67+
void InitKeyboardChannel();
68+
6169
// Add a delegate that handles events received by |KeyboardHook|.
6270
void AddDelegate(std::unique_ptr<KeyboardKeyHandlerDelegate> delegate);
6371

@@ -97,6 +105,12 @@ class KeyboardKeyHandler : public KeyboardHandlerBase {
97105
bool was_down,
98106
KeyEventCallback callback) override;
99107

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+
100114
private:
101115
struct PendingEvent {
102116
// Self-incrementing ID attached to an event sent to the framework.
@@ -114,6 +128,11 @@ class KeyboardKeyHandler : public KeyboardHandlerBase {
114128

115129
void ResolvePendingEvent(uint64_t sequence_id, bool handled);
116130

131+
// Called when a method is called on |channel_|;
132+
void HandleMethodCall(
133+
const flutter::MethodCall<EncodableValue>& method_call,
134+
std::unique_ptr<flutter::MethodResult<EncodableValue>> result);
135+
117136
std::vector<std::unique_ptr<KeyboardKeyHandlerDelegate>> delegates_;
118137

119138
// The queue of key events that have been sent to the framework but have not
@@ -123,6 +142,9 @@ class KeyboardKeyHandler : public KeyboardHandlerBase {
123142
// The sequence_id attached to the last event sent to the framework.
124143
uint64_t last_sequence_id_;
125144

145+
// The Flutter system channel for keyboard state messages.
146+
std::unique_ptr<flutter::MethodChannel<EncodableValue>> channel_;
147+
126148
FML_DISALLOW_COPY_AND_ASSIGN(KeyboardKeyHandler);
127149
};
128150

0 commit comments

Comments
 (0)