Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion shell/platform/windows/flutter_windows_engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,7 @@ FlutterWindowsEngine::CreateKeyboardKeyHandler(
BinaryMessenger* messenger,
KeyboardKeyEmbedderHandler::GetKeyStateHandler get_key_state,
KeyboardKeyEmbedderHandler::MapVirtualKeyToScanCode map_vk_to_scan) {
auto keyboard_key_handler = std::make_unique<KeyboardKeyHandler>();
auto keyboard_key_handler = std::make_unique<KeyboardKeyHandler>(messenger);
keyboard_key_handler->AddDelegate(
std::make_unique<KeyboardKeyEmbedderHandler>(
[this](const FlutterKeyEvent& event, FlutterKeyEventCallback callback,
Expand All @@ -641,6 +641,7 @@ FlutterWindowsEngine::CreateKeyboardKeyHandler(
get_key_state, map_vk_to_scan));
keyboard_key_handler->AddDelegate(
std::make_unique<KeyboardKeyChannelHandler>(messenger));
keyboard_key_handler->InitKeyboardChannel();
return keyboard_key_handler;
}

Expand Down
6 changes: 6 additions & 0 deletions shell/platform/windows/keyboard_handler_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ class KeyboardHandlerBase {
// If needed, synthesize modifier keys events by comparing the
// given modifiers state to the known pressing state..
virtual void SyncModifiersIfNeeded(int modifiers_state) = 0;

// Returns the keyboard pressed state.
//
// Returns the keyboard pressed state. The map contains one entry per
// pressed keys, mapping from the logical key to the physical key.
virtual std::map<uint64_t, uint64_t> GetPressedState() = 0;
};

} // namespace flutter
Expand Down
10 changes: 9 additions & 1 deletion shell/platform/windows/keyboard_key_channel_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,15 @@ KeyboardKeyChannelHandler::KeyboardKeyChannelHandler(
KeyboardKeyChannelHandler::~KeyboardKeyChannelHandler() = default;

void KeyboardKeyChannelHandler::SyncModifiersIfNeeded(int modifiers_state) {
// Do nothing
// Do nothing.
}

std::map<uint64_t, uint64_t> KeyboardKeyChannelHandler::GetPressedState() {
// Returns an empty state because it will never be called.
// KeyboardKeyEmbedderHandler is the only KeyboardKeyHandlerDelegate to handle
// GetPressedState() calls.
std::map<uint64_t, uint64_t> empty_state;
return empty_state;
}

void KeyboardKeyChannelHandler::KeyboardHook(
Expand Down
2 changes: 2 additions & 0 deletions shell/platform/windows/keyboard_key_channel_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ class KeyboardKeyChannelHandler

void SyncModifiersIfNeeded(int modifiers_state);

std::map<uint64_t, uint64_t> GetPressedState();

private:
// The Flutter system channel for key event messages.
std::unique_ptr<flutter::BasicMessageChannel<rapidjson::Document>> channel_;
Expand Down
4 changes: 4 additions & 0 deletions shell/platform/windows/keyboard_key_embedder_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,10 @@ void KeyboardKeyEmbedderHandler::KeyboardHook(
}
}

std::map<uint64_t, uint64_t> KeyboardKeyEmbedderHandler::GetPressedState() {
return pressingRecords_;
}

void KeyboardKeyEmbedderHandler::UpdateLastSeenCriticalKey(
int virtual_key,
uint64_t physical_key,
Expand Down
2 changes: 2 additions & 0 deletions shell/platform/windows/keyboard_key_embedder_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ class KeyboardKeyEmbedderHandler

void SyncModifiersIfNeeded(int modifiers_state) override;

std::map<uint64_t, uint64_t> GetPressedState() override;

private:
struct PendingResponse {
std::function<void(bool, uint64_t)> callback;
Expand Down
45 changes: 44 additions & 1 deletion shell/platform/windows/keyboard_key_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <windows.h>

#include "flutter/fml/logging.h"
#include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_method_codec.h"
#include "flutter/shell/platform/windows/keyboard_utils.h"

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

// The name of the channel for keyboard state queries.
static constexpr char kChannelName[] = "flutter/keyboard";

static constexpr char kGetKeyboardStateMethod[] = "getKeyboardState";

} // namespace

KeyboardKeyHandler::KeyboardKeyHandlerDelegate::~KeyboardKeyHandlerDelegate() =
default;

KeyboardKeyHandler::KeyboardKeyHandler() : last_sequence_id_(1) {}
KeyboardKeyHandler::KeyboardKeyHandler(flutter::BinaryMessenger* messenger)
: last_sequence_id_(1),
channel_(std::make_unique<MethodChannel<EncodableValue>>(
messenger,
kChannelName,
&StandardMethodCodec::GetInstance())) {}

KeyboardKeyHandler::~KeyboardKeyHandler() = default;

void KeyboardKeyHandler::InitKeyboardChannel() {
channel_->SetMethodCallHandler(
[this](const MethodCall<EncodableValue>& call,
std::unique_ptr<MethodResult<EncodableValue>> result) {
HandleMethodCall(call, std::move(result));
});
}

void KeyboardKeyHandler::HandleMethodCall(
const MethodCall<EncodableValue>& method_call,
std::unique_ptr<MethodResult<EncodableValue>> result) {
const std::string& method = method_call.method_name();
if (method.compare(kGetKeyboardStateMethod) == 0) {
EncodableMap value;
const auto& pressed_state = GetPressedState();
for (const auto& pressed_key : pressed_state) {
EncodableValue physical_value(static_cast<long long>(pressed_key.first));
EncodableValue logical_value(static_cast<long long>(pressed_key.second));
value[physical_value] = logical_value;
}
result->Success(EncodableValue(value));
} else {
result->NotImplemented();
}
}

void KeyboardKeyHandler::AddDelegate(
std::unique_ptr<KeyboardKeyHandlerDelegate> delegate) {
delegates_.push_back(std::move(delegate));
Expand All @@ -37,6 +74,12 @@ void KeyboardKeyHandler::SyncModifiersIfNeeded(int modifiers_state) {
key_embedder_handler->SyncModifiersIfNeeded(modifiers_state);
}

std::map<uint64_t, uint64_t> KeyboardKeyHandler::GetPressedState() {
// The embedder responder is the first element in delegates_.
auto& key_embedder_handler = delegates_.front();
return key_embedder_handler->GetPressedState();
}

void KeyboardKeyHandler::KeyboardHook(int key,
int scancode,
int action,
Expand Down
30 changes: 26 additions & 4 deletions shell/platform/windows/keyboard_key_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@

#include <windows.h>
#include <deque>
#include <map>
#include <memory>
#include <string>

#include "flutter/fml/macros.h"
#include "flutter/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h"
#include "flutter/shell/platform/common/client_wrapper/include/flutter/binary_messenger.h"
#include "flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h"
#include "flutter/shell/platform/common/client_wrapper/include/flutter/method_channel.h"
#include "flutter/shell/platform/windows/keyboard_handler_base.h"
#include "rapidjson/document.h"

namespace flutter {

Expand Down Expand Up @@ -50,14 +52,20 @@ class KeyboardKeyHandler : public KeyboardHandlerBase {

virtual void SyncModifiersIfNeeded(int modifiers_state) = 0;

virtual std::map<uint64_t, uint64_t> GetPressedState() = 0;

virtual ~KeyboardKeyHandlerDelegate();
};

// Create a KeyboardKeyHandler.
explicit KeyboardKeyHandler();
// Create a |KeyboardKeyHandler| by specifying the messenger
// through which the messages are sent.
explicit KeyboardKeyHandler(flutter::BinaryMessenger* messenger);

~KeyboardKeyHandler();

// Init the keyboard channel used to answer to pressed state queries.
void InitKeyboardChannel();

// Add a delegate that handles events received by |KeyboardHook|.
void AddDelegate(std::unique_ptr<KeyboardKeyHandlerDelegate> delegate);

Expand Down Expand Up @@ -97,6 +105,12 @@ class KeyboardKeyHandler : public KeyboardHandlerBase {
bool was_down,
KeyEventCallback callback) override;

// Returns the keyboard pressed state.
//
// Returns the keyboard pressed state. The dictionary contains one entry per
// pressed keys, mapping from the logical key to the physical key.
std::map<uint64_t, uint64_t> GetPressedState() override;

private:
struct PendingEvent {
// Self-incrementing ID attached to an event sent to the framework.
Expand All @@ -114,6 +128,11 @@ class KeyboardKeyHandler : public KeyboardHandlerBase {

void ResolvePendingEvent(uint64_t sequence_id, bool handled);

// Called when a method is called on |channel_|;
void HandleMethodCall(
const flutter::MethodCall<EncodableValue>& method_call,
std::unique_ptr<flutter::MethodResult<EncodableValue>> result);

std::vector<std::unique_ptr<KeyboardKeyHandlerDelegate>> delegates_;

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

// The Flutter system channel for keyboard state messages.
std::unique_ptr<flutter::MethodChannel<EncodableValue>> channel_;

FML_DISALLOW_COPY_AND_ASSIGN(KeyboardKeyHandler);
};

Expand Down
Loading