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
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