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 1 commit
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
10 changes: 10 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -3028,6 +3028,11 @@ ORIGIN: ../../../flutter/shell/platform/linux/fl_key_responder.h + ../../../flut
ORIGIN: ../../../flutter/shell/platform/linux/fl_keyboard_manager.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/linux/fl_keyboard_manager.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/linux/fl_keyboard_manager_test.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/linux/fl_keyboard_plugin.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/linux/fl_keyboard_plugin.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/linux/fl_keyboard_plugin_test.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/linux/fl_keyboard_plugin_view_delegate.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/linux/fl_keyboard_plugin_view_delegate.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/linux/fl_keyboard_view_delegate.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/linux/fl_keyboard_view_delegate.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/linux/fl_message_codec.cc + ../../../flutter/LICENSE
Expand Down Expand Up @@ -5704,6 +5709,11 @@ FILE: ../../../flutter/shell/platform/linux/fl_key_responder.h
FILE: ../../../flutter/shell/platform/linux/fl_keyboard_manager.cc
FILE: ../../../flutter/shell/platform/linux/fl_keyboard_manager.h
FILE: ../../../flutter/shell/platform/linux/fl_keyboard_manager_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_keyboard_plugin.cc
FILE: ../../../flutter/shell/platform/linux/fl_keyboard_plugin.h
FILE: ../../../flutter/shell/platform/linux/fl_keyboard_plugin_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_keyboard_plugin_view_delegate.cc
FILE: ../../../flutter/shell/platform/linux/fl_keyboard_plugin_view_delegate.h
FILE: ../../../flutter/shell/platform/linux/fl_keyboard_view_delegate.cc
FILE: ../../../flutter/shell/platform/linux/fl_keyboard_view_delegate.h
FILE: ../../../flutter/shell/platform/linux/fl_message_codec.cc
Expand Down
4 changes: 4 additions & 0 deletions shell/platform/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ source_set("flutter_linux_sources") {
"fl_dart_project_private.h",
"fl_engine_private.h",
"fl_keyboard_manager.h",
"fl_keyboard_plugin_view_delegate.h",
"fl_keyboard_view_delegate.h",
"fl_key_event.h",
"fl_key_responder.h",
Expand Down Expand Up @@ -116,6 +117,8 @@ source_set("flutter_linux_sources") {
"fl_key_event.cc",
"fl_key_responder.cc",
"fl_keyboard_manager.cc",
"fl_keyboard_plugin.cc",
"fl_keyboard_plugin_view_delegate.cc",
"fl_keyboard_view_delegate.cc",
"fl_message_codec.cc",
"fl_method_call.cc",
Expand Down Expand Up @@ -207,6 +210,7 @@ executable("flutter_linux_unittests") {
"fl_key_channel_responder_test.cc",
"fl_key_embedder_responder_test.cc",
"fl_keyboard_manager_test.cc",
"fl_keyboard_plugin_test.cc",
"fl_message_codec_test.cc",
"fl_method_channel_test.cc",
"fl_method_codec_test.cc",
Expand Down
5 changes: 5 additions & 0 deletions shell/platform/linux/fl_key_embedder_responder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -885,3 +885,8 @@ void fl_key_embedder_responder_sync_modifiers_if_needed(
synchronize_pressed_states_loop_body,
&sync_state_context);
}

GHashTable* fl_key_embedder_responder_get_pressed_state(
FlKeyEmbedderResponder* self) {
return self->pressing_records;
}
9 changes: 9 additions & 0 deletions shell/platform/linux/fl_key_embedder_responder.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ void fl_key_embedder_responder_sync_modifiers_if_needed(
guint state,
double event_time);

/**
* fl_key_embedder_responder_get_pressed_state:
* @responder: the #FlKeyEmbedderResponder self.
*
* Returns the keyboard pressed state.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Returns the keyboard pressed state.
* Returns the keyboard pressed state. The hash table contains one entry per pressed keys, mapping from the logical key to the physical key.

*/
GHashTable* fl_key_embedder_responder_get_pressed_state(
FlKeyEmbedderResponder* responder);

G_END_DECLS

#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_KEY_EMBEDDER_RESPONDER_H_
12 changes: 12 additions & 0 deletions shell/platform/linux/fl_keyboard_manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -614,10 +614,22 @@ gboolean fl_keyboard_manager_is_state_clear(FlKeyboardManager* self) {
void fl_keyboard_manager_sync_modifier_if_needed(FlKeyboardManager* self,
guint state,
double event_time) {
g_return_if_fail(FL_IS_KEYBOARD_MANAGER(self));

// The embedder responder is the first element in
// FlKeyboardManager.responder_list.
FlKeyEmbedderResponder* responder =
FL_KEY_EMBEDDER_RESPONDER(g_ptr_array_index(self->responder_list, 0));
fl_key_embedder_responder_sync_modifiers_if_needed(responder, state,
event_time);
}

GHashTable* fl_keyboard_manager_get_pressed_state(FlKeyboardManager* self) {
g_return_val_if_fail(FL_IS_KEYBOARD_MANAGER(self), nullptr);

// The embedder responder is the first element in
// FlKeyboardManager.responder_list.
FlKeyEmbedderResponder* responder =
FL_KEY_EMBEDDER_RESPONDER(g_ptr_array_index(self->responder_list, 0));
return fl_key_embedder_responder_get_pressed_state(responder);
}
8 changes: 8 additions & 0 deletions shell/platform/linux/fl_keyboard_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ void fl_keyboard_manager_sync_modifier_if_needed(FlKeyboardManager* manager,
guint state,
double event_time);

/**
* fl_keyboard_manager_get_pressed_state:
* @manager: the #FlKeyboardManager self.
*
* Returns the keyboard pressed state.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Returns the keyboard pressed state.
* Returns the keyboard pressed state. The hash table contains one entry per pressed keys, mapping from the logical key to the physical key.

*/
GHashTable* fl_keyboard_manager_get_pressed_state(FlKeyboardManager* responder);

G_END_DECLS

#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_KEYBOARD_MANAGER_H_
19 changes: 19 additions & 0 deletions shell/platform/linux/fl_keyboard_manager_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <vector>

#include "flutter/shell/platform/embedder/test_utils/key_codes.g.h"
#include "flutter/shell/platform/linux/key_mapping.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_json_message_codec.h"
#include "flutter/shell/platform/linux/testing/mock_text_input_plugin.h"
#include "gtest/gtest.h"
Expand Down Expand Up @@ -926,6 +927,24 @@ TEST(FlKeyboardManagerTest, SynthesizeModifiersIfNeeded) {
kLogicalShiftLeft);
}

TEST(FlKeyboardManagerTest, GetPressedState) {
KeyboardTester tester;
tester.respondToTextInputWith(true);

// Dispatch a key event.
fl_keyboard_manager_handle_event(
tester.manager(),
fl_key_event_new_by_mock(true, GDK_KEY_a, kKeyCodeKeyA, 0, false));

GHashTable* pressedState =
fl_keyboard_manager_get_pressed_state(tester.manager());
EXPECT_EQ(g_hash_table_size(pressedState), 1u);

gpointer physical_key =
g_hash_table_lookup(pressedState, uint64_to_gpointer(kPhysicalKeyA));
EXPECT_EQ(gpointer_to_uint64(physical_key), kLogicalKeyA);
}

// The following layout data is generated using DEBUG_PRINT_LAYOUT.

const MockGroupLayoutData kLayoutUs0{{
Expand Down
111 changes: 111 additions & 0 deletions shell/platform/linux/fl_keyboard_plugin.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/shell/platform/linux/fl_keyboard_plugin.h"

#include <gtk/gtk.h>
#include <cstring>

#include "flutter/shell/platform/linux/public/flutter_linux/fl_method_channel.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_standard_method_codec.h"

static constexpr char kChannelName[] = "flutter/keyboard";
static constexpr char kGetKeyboardStateMethod[] = "getKeyboardState";

struct _FlKeyboardPlugin {
GObject parent_instance;

FlMethodChannel* channel;

FlKeyboardPluginViewDelegate* view_delegate;
};

G_DEFINE_TYPE(FlKeyboardPlugin, fl_keyboard_plugin, G_TYPE_OBJECT)

// Returns the keyboard pressed state.
FlMethodResponse* get_keyboard_state(FlKeyboardPlugin* self) {
g_autoptr(FlValue) result = fl_value_new_map();

GHashTable* pressing_records =
fl_keyboard_plugin_view_delegate_get_keyboard_state(self->view_delegate);

g_hash_table_foreach(
pressing_records,
[](gpointer key, gpointer value, gpointer user_data) {
int64_t physical_key = reinterpret_cast<int64_t>(key);
int64_t logical_key = reinterpret_cast<int64_t>(value);
FlValue* fl_value_map = reinterpret_cast<FlValue*>(user_data);

fl_value_set_take(fl_value_map, fl_value_new_int(physical_key),
fl_value_new_int(logical_key));
},
result);
return FL_METHOD_RESPONSE(fl_method_success_response_new(result));
}

// Called when a method call is received from Flutter.
static void method_call_cb(FlMethodChannel* channel,
FlMethodCall* method_call,
gpointer user_data) {
FlKeyboardPlugin* self = FL_KEYBOARD_PLUGIN(user_data);

const gchar* method = fl_method_call_get_name(method_call);

g_autoptr(FlMethodResponse) response = nullptr;
if (strcmp(method, kGetKeyboardStateMethod) == 0) {
response = get_keyboard_state(self);
} else {
response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new());
}

g_autoptr(GError) error = nullptr;
if (!fl_method_call_respond(method_call, response, &error)) {
g_warning("Failed to send method call response: %s", error->message);
}
}

static void fl_keyboard_plugin_dispose(GObject* object);

static void fl_keyboard_plugin_class_init(FlKeyboardPluginClass* klass) {
G_OBJECT_CLASS(klass)->dispose = fl_keyboard_plugin_dispose;
}

static void fl_keyboard_plugin_init(FlKeyboardPlugin* self) {}

FlKeyboardPlugin* fl_keyboard_plugin_new(
FlBinaryMessenger* messenger,
FlKeyboardPluginViewDelegate* view_delegate) {
g_return_val_if_fail(FL_IS_BINARY_MESSENGER(messenger), nullptr);
g_return_val_if_fail(FL_IS_KEYBOARD_PLUGIN_VIEW_DELEGATE(view_delegate),
nullptr);

FlKeyboardPlugin* self =
FL_KEYBOARD_PLUGIN(g_object_new(fl_keyboard_plugin_get_type(), nullptr));

g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
self->channel =
fl_method_channel_new(messenger, kChannelName, FL_METHOD_CODEC(codec));
fl_method_channel_set_method_call_handler(self->channel, method_call_cb, self,
nullptr);
self->view_delegate = view_delegate;
g_object_add_weak_pointer(
G_OBJECT(view_delegate),
reinterpret_cast<gpointer*>(&(self->view_delegate)));

return self;
}

static void fl_keyboard_plugin_dispose(GObject* object) {
FlKeyboardPlugin* self = FL_KEYBOARD_PLUGIN(object);

g_clear_object(&self->channel);
if (self->view_delegate != nullptr) {
g_object_remove_weak_pointer(
G_OBJECT(self->view_delegate),
reinterpret_cast<gpointer*>(&(self->view_delegate)));
self->view_delegate = nullptr;
}

G_OBJECT_CLASS(fl_keyboard_plugin_parent_class)->dispose(object);
}
47 changes: 47 additions & 0 deletions shell/platform/linux/fl_keyboard_plugin.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_SHELL_PLATFORM_LINUX_FL_KEYBOARD_PLUGIN_H_
#define FLUTTER_SHELL_PLATFORM_LINUX_FL_KEYBOARD_PLUGIN_H_

#include <gdk/gdk.h>

#include "flutter/shell/platform/linux/fl_keyboard_plugin_view_delegate.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_view.h"

G_BEGIN_DECLS

#define FL_TYPE_KEYBOARD_PLUGIN fl_keyboard_plugin_get_type()
G_DECLARE_FINAL_TYPE(FlKeyboardPlugin,
fl_keyboard_plugin,
FL,
KEYBOARD_PLUGIN,
GObject);

/**
* FlKeyboardPlugin:
*
* #FlKeyboardPlugin is a keyboard channel that implements the shell side
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it's just a keyboard channel, should we call it FlKeyboardChannel? Anyway it's not very much a plugin and the name is a bit confusing.

Also I haven't thought it through but will it be simpler to merge this class with FlKeyboardManager, since it only contains one method?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also I haven't thought it through but will it be simpler to merge this class with FlKeyboardManager, since it only contains one method?

Yes, it will be probably simpler, I will try this next week.

* of SystemChannels.keyboard from the Flutter services library.
*/

/**
* fl_keyboard_plugin_new:
* @messenger: an #FlBinaryMessenger.
* @view_delegate: An interface that the plugin requires to communicate with
* the platform. Usually implemented by FlView.
*
* Creates a new plugin that implements SystemChannels.keyboard from the
* Flutter services library.
*
* Returns: a new #FlKeyboardPlugin.
*/
FlKeyboardPlugin* fl_keyboard_plugin_new(
FlBinaryMessenger* messenger,
FlKeyboardPluginViewDelegate* view_delegate);

G_END_DECLS

#endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_KEYBOARD_PLUGIN_H_
Loading