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 7 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
4 changes: 4 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -44800,6 +44800,8 @@ ORIGIN: ../../../flutter/shell/platform/linux/fl_key_responder.h + ../../../flut
ORIGIN: ../../../flutter/shell/platform/linux/fl_keyboard_handler.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/linux/fl_keyboard_handler.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/linux/fl_keyboard_handler_test.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/linux/fl_keyboard_pending_event.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/linux/fl_keyboard_pending_event.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 @@ -47697,6 +47699,8 @@ FILE: ../../../flutter/shell/platform/linux/fl_key_responder.h
FILE: ../../../flutter/shell/platform/linux/fl_keyboard_handler.cc
FILE: ../../../flutter/shell/platform/linux/fl_keyboard_handler.h
FILE: ../../../flutter/shell/platform/linux/fl_keyboard_handler_test.cc
FILE: ../../../flutter/shell/platform/linux/fl_keyboard_pending_event.cc
FILE: ../../../flutter/shell/platform/linux/fl_keyboard_pending_event.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
2 changes: 2 additions & 0 deletions shell/platform/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ source_set("flutter_linux_sources") {
"fl_dart_project_private.h",
"fl_engine_private.h",
"fl_keyboard_handler.h",
"fl_keyboard_pending_event.h",
"fl_keyboard_view_delegate.h",
"fl_key_event.h",
"fl_key_responder.h",
Expand Down Expand Up @@ -116,6 +117,7 @@ source_set("flutter_linux_sources") {
"fl_key_event.cc",
"fl_key_responder.cc",
"fl_keyboard_handler.cc",
"fl_keyboard_pending_event.cc",
"fl_keyboard_view_delegate.cc",
"fl_message_codec.cc",
"fl_method_call.cc",
Expand Down
21 changes: 12 additions & 9 deletions shell/platform/linux/fl_key_channel_responder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,11 @@ static void fl_key_channel_responder_handle_event(
g_return_if_fail(event != nullptr);
g_return_if_fail(callback != nullptr);

const gchar* type = event->is_press ? kTypeValueDown : kTypeValueUp;
int64_t scan_code = event->keycode;
int64_t unicode_scarlar_values = gdk_keyval_to_unicode(event->keyval);
const gchar* type =
fl_key_event_get_is_press(event) ? kTypeValueDown : kTypeValueUp;
int64_t scan_code = fl_key_event_get_keycode(event);
int64_t unicode_scarlar_values =
gdk_keyval_to_unicode(fl_key_event_get_keyval(event));

// For most modifier keys, GTK keeps track of the "pressed" state of the
// modifier keys. Flutter uses this information to keep modifier keys from
Expand All @@ -239,20 +241,21 @@ static void fl_key_channel_responder_handle_event(
// interactions (for example, if shift-lock is on, tab traversal is broken).

// Remove lock states from state mask.
guint state = event->state & ~(GDK_LOCK_MASK | GDK_MOD2_MASK);
guint state =
fl_key_event_get_state(event) & ~(GDK_LOCK_MASK | GDK_MOD2_MASK);

static bool shift_lock_pressed = FALSE;
static bool caps_lock_pressed = FALSE;
static bool num_lock_pressed = FALSE;
switch (event->keyval) {
switch (fl_key_event_get_keyval(event)) {
case GDK_KEY_Num_Lock:
num_lock_pressed = event->is_press;
num_lock_pressed = fl_key_event_get_is_press(event);
break;
case GDK_KEY_Caps_Lock:
caps_lock_pressed = event->is_press;
caps_lock_pressed = fl_key_event_get_is_press(event);
break;
case GDK_KEY_Shift_Lock:
shift_lock_pressed = event->is_press;
shift_lock_pressed = fl_key_event_get_is_press(event);
break;
}

Expand All @@ -269,7 +272,7 @@ static void fl_key_channel_responder_handle_event(
fl_value_set_string_take(message, kToolkitKey,
fl_value_new_string(kGtkToolkit));
fl_value_set_string_take(message, kKeyCodeKey,
fl_value_new_int(event->keyval));
fl_value_new_int(fl_key_event_get_keyval(event)));
fl_value_set_string_take(message, kModifiersKey, fl_value_new_int(state));
if (unicode_scarlar_values != 0) {
fl_value_set_string_take(message, kUnicodeScalarValuesKey,
Expand Down
76 changes: 19 additions & 57 deletions shell/platform/linux/fl_key_channel_responder_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,33 +29,6 @@ static void responder_callback(bool handled, gpointer user_data) {
g_main_loop_quit(static_cast<GMainLoop*>(user_data));
}

namespace {
// A global variable to store new event. It is a global variable so that it can
// be returned by #fl_key_event_new_by_mock for easy use.
FlKeyEvent _g_key_event;
} // namespace

// Create a new #FlKeyEvent with the given information.
//
// This event is passed to #fl_key_responder_handle_event,
// which assumes that the event is managed by callee.
// Therefore #fl_key_event_new_by_mock doesn't need to
// dynamically allocate, but reuses the same global object.
static FlKeyEvent* fl_key_event_new_by_mock(guint32 time_in_milliseconds,
bool is_press,
guint keyval,
guint16 keycode,
GdkModifierType state,
gboolean is_modifier) {
_g_key_event.is_press = is_press;
_g_key_event.time = time_in_milliseconds;
_g_key_event.state = state;
_g_key_event.keyval = keyval;
_g_key_event.keycode = keycode;
_g_key_event.origin = nullptr;
return &_g_key_event;
}

// Test sending a letter "A";
TEST(FlKeyChannelResponderTest, SendKeyEvent) {
g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0);
Expand All @@ -69,11 +42,9 @@ TEST(FlKeyChannelResponderTest, SendKeyEvent) {
g_autoptr(FlKeyResponder) responder =
FL_KEY_RESPONDER(fl_key_channel_responder_new(messenger, &mock));

fl_key_responder_handle_event(
responder,
fl_key_event_new_by_mock(12345, true, GDK_KEY_A, 0x04,
static_cast<GdkModifierType>(0), false),
responder_callback, loop);
g_autoptr(FlKeyEvent) event1 = fl_key_event_new(
12345, TRUE, 0x04, GDK_KEY_A, static_cast<GdkModifierType>(0), 0);
fl_key_responder_handle_event(responder, event1, responder_callback, loop);
expected_value =
"{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, keyCode: 65, "
"modifiers: 0, unicodeScalarValues: 65}";
Expand All @@ -82,11 +53,9 @@ TEST(FlKeyChannelResponderTest, SendKeyEvent) {
// Blocks here until echo_response_cb is called.
g_main_loop_run(loop);

fl_key_responder_handle_event(
responder,
fl_key_event_new_by_mock(23456, false, GDK_KEY_A, 0x04,
static_cast<GdkModifierType>(0), false),
responder_callback, loop);
g_autoptr(FlKeyEvent) event2 = fl_key_event_new(
23456, FALSE, 0x04, GDK_KEY_A, static_cast<GdkModifierType>(0), 0);
fl_key_responder_handle_event(responder, event2, responder_callback, loop);
expected_value =
"{type: keyup, keymap: linux, scanCode: 4, toolkit: gtk, keyCode: 65, "
"modifiers: 0, unicodeScalarValues: 65}";
Expand All @@ -110,11 +79,9 @@ void test_lock_event(guint key_code,
g_autoptr(FlKeyResponder) responder =
FL_KEY_RESPONDER(fl_key_channel_responder_new(messenger, &mock));

fl_key_responder_handle_event(
responder,
fl_key_event_new_by_mock(12345, true, key_code, 0x04,
static_cast<GdkModifierType>(0), false),
responder_callback, loop);
g_autoptr(FlKeyEvent) event1 = fl_key_event_new(
12345, TRUE, 0x04, key_code, static_cast<GdkModifierType>(0), 0);
fl_key_responder_handle_event(responder, event1, responder_callback, loop);
expected_value = down_expected;
expected_handled = FALSE;

Expand All @@ -123,11 +90,9 @@ void test_lock_event(guint key_code,

expected_value = up_expected;
expected_handled = FALSE;
fl_key_responder_handle_event(
responder,
fl_key_event_new_by_mock(12346, false, key_code, 0x04,
static_cast<GdkModifierType>(0), false),
responder_callback, loop);
g_autoptr(FlKeyEvent) event2 = fl_key_event_new(
12346, FALSE, 0x04, key_code, static_cast<GdkModifierType>(0), 0);
fl_key_responder_handle_event(responder, event2, responder_callback, loop);

// Blocks here until echo_response_cb is called.
g_main_loop_run(loop);
Expand Down Expand Up @@ -172,11 +137,9 @@ TEST(FlKeyChannelResponderTest, TestKeyEventHandledByFramework) {
g_autoptr(FlKeyResponder) responder =
FL_KEY_RESPONDER(fl_key_channel_responder_new(messenger, &mock));

fl_key_responder_handle_event(
responder,
fl_key_event_new_by_mock(12345, true, GDK_KEY_A, 0x04,
static_cast<GdkModifierType>(0), false),
responder_callback, loop);
g_autoptr(FlKeyEvent) event = fl_key_event_new(
12345, TRUE, 0x04, GDK_KEY_A, static_cast<GdkModifierType>(0), 0);
fl_key_responder_handle_event(responder, event, responder_callback, loop);
expected_handled = TRUE;
expected_value =
"{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, "
Expand All @@ -198,11 +161,10 @@ TEST(FlKeyChannelResponderTest, UseSpecifiedLogicalKey) {
g_autoptr(FlKeyResponder) responder =
FL_KEY_RESPONDER(fl_key_channel_responder_new(messenger, &mock));

fl_key_responder_handle_event(
responder,
fl_key_event_new_by_mock(12345, true, GDK_KEY_A, 0x04,
static_cast<GdkModifierType>(0), false),
responder_callback, loop, 888);
g_autoptr(FlKeyEvent) event = fl_key_event_new(
12345, TRUE, 0x04, GDK_KEY_A, static_cast<GdkModifierType>(0), 0);
fl_key_responder_handle_event(responder, event, responder_callback, loop,
888);
expected_handled = TRUE;
expected_value =
"{type: keydown, keymap: linux, scanCode: 4, toolkit: gtk, "
Expand Down
27 changes: 14 additions & 13 deletions shell/platform/linux/fl_key_embedder_responder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -297,16 +297,16 @@ static uint64_t apply_id_plane(uint64_t logical_id, uint64_t plane) {
return (logical_id & kValueMask) | plane;
}

static uint64_t event_to_physical_key(const FlKeyEvent* event) {
auto found = xkb_to_physical_key_map.find(event->keycode);
static uint64_t event_to_physical_key(FlKeyEvent* event) {
auto found = xkb_to_physical_key_map.find(fl_key_event_get_keycode(event));
if (found != xkb_to_physical_key_map.end()) {
return found->second;
}
return apply_id_plane(event->keycode, kGtkPlane);
return apply_id_plane(fl_key_event_get_keycode(event), kGtkPlane);
}

static uint64_t event_to_logical_key(const FlKeyEvent* event) {
guint keyval = event->keyval;
static uint64_t event_to_logical_key(FlKeyEvent* event) {
guint keyval = fl_key_event_get_keyval(event);
auto found = gtk_keyval_to_logical_key_map.find(keyval);
if (found != gtk_keyval_to_logical_key_map.end()) {
return found->second;
Expand All @@ -319,14 +319,15 @@ static uint64_t event_to_logical_key(const FlKeyEvent* event) {
return apply_id_plane(keyval, kGtkPlane);
}

static uint64_t event_to_timestamp(const FlKeyEvent* event) {
return kMicrosecondsPerMillisecond * static_cast<double>(event->time);
static uint64_t event_to_timestamp(FlKeyEvent* event) {
return kMicrosecondsPerMillisecond *
static_cast<double>(fl_key_event_get_time(event));
}

// Returns a newly accocated UTF-8 string from event->keyval that must be
// freed later with g_free().
static char* event_to_character(const FlKeyEvent* event) {
gunichar unicodeChar = gdk_keyval_to_unicode(event->keyval);
// Returns a newly accocated UTF-8 string from fl_key_event_get_keyval(event)
// that must be freed later with g_free().
static char* event_to_character(FlKeyEvent* event) {
gunichar unicodeChar = gdk_keyval_to_unicode(fl_key_event_get_keyval(event));
glong items_written;
gchar* result = g_ucs4_to_utf8(&unicodeChar, 1, NULL, &items_written, NULL);
if (items_written == 0) {
Expand Down Expand Up @@ -790,11 +791,11 @@ static void fl_key_embedder_responder_handle_event_impl(
const uint64_t physical_key = corrected_modifier_physical_key(
self->modifier_bit_to_checked_keys, physical_key_from_event, logical_key);
const double timestamp = event_to_timestamp(event);
const bool is_down_event = event->is_press;
const bool is_down_event = fl_key_event_get_is_press(event);

SyncStateLoopContext sync_state_context;
sync_state_context.self = self;
sync_state_context.state = event->state;
sync_state_context.state = fl_key_event_get_state(event);
sync_state_context.timestamp = timestamp;
sync_state_context.is_down = is_down_event;
sync_state_context.event_logical_key = logical_key;
Expand Down
Loading