mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Cleanup refactoring in FlKeyboardManager (flutter/engine#56956)
Remove pending keyboard event ID and use the object directly. Use references to make sure FlKeyboardManagerData is freed. Refactor marking events as handled
This commit is contained in:
parent
a64a3fb367
commit
8cc75a926e
@ -21,10 +21,10 @@
|
||||
|
||||
/* Declarations of private classes */
|
||||
|
||||
G_DECLARE_FINAL_TYPE(FlKeyboardManagerUserData,
|
||||
fl_keyboard_manager_user_data,
|
||||
G_DECLARE_FINAL_TYPE(FlKeyboardManagerData,
|
||||
fl_keyboard_manager_data,
|
||||
FL,
|
||||
KEYBOARD_MANAGER_USER_DATA,
|
||||
KEYBOARD_MANAGER_DATA,
|
||||
GObject);
|
||||
|
||||
/* End declarations */
|
||||
@ -62,52 +62,50 @@ void debug_format_layout_data(std::string& debug_layout_data,
|
||||
|
||||
} // namespace
|
||||
|
||||
/* Define FlKeyboardManagerUserData */
|
||||
/* Define FlKeyboardManagerData */
|
||||
|
||||
/**
|
||||
* FlKeyboardManagerUserData:
|
||||
* FlKeyboardManagerData:
|
||||
* The user_data used when #FlKeyboardManager sends event to
|
||||
* responders.
|
||||
*/
|
||||
|
||||
struct _FlKeyboardManagerUserData {
|
||||
struct _FlKeyboardManagerData {
|
||||
GObject parent_instance;
|
||||
|
||||
// The owner manager.
|
||||
GWeakRef manager;
|
||||
uint64_t sequence_id;
|
||||
|
||||
FlKeyboardPendingEvent* pending;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE(FlKeyboardManagerUserData,
|
||||
fl_keyboard_manager_user_data,
|
||||
G_TYPE_OBJECT)
|
||||
G_DEFINE_TYPE(FlKeyboardManagerData, fl_keyboard_manager_data, G_TYPE_OBJECT)
|
||||
|
||||
static void fl_keyboard_manager_user_data_dispose(GObject* object) {
|
||||
g_return_if_fail(FL_IS_KEYBOARD_MANAGER_USER_DATA(object));
|
||||
FlKeyboardManagerUserData* self = FL_KEYBOARD_MANAGER_USER_DATA(object);
|
||||
static void fl_keyboard_manager_data_dispose(GObject* object) {
|
||||
g_return_if_fail(FL_IS_KEYBOARD_MANAGER_DATA(object));
|
||||
FlKeyboardManagerData* self = FL_KEYBOARD_MANAGER_DATA(object);
|
||||
|
||||
g_weak_ref_clear(&self->manager);
|
||||
|
||||
G_OBJECT_CLASS(fl_keyboard_manager_user_data_parent_class)->dispose(object);
|
||||
G_OBJECT_CLASS(fl_keyboard_manager_data_parent_class)->dispose(object);
|
||||
}
|
||||
|
||||
static void fl_keyboard_manager_user_data_class_init(
|
||||
FlKeyboardManagerUserDataClass* klass) {
|
||||
G_OBJECT_CLASS(klass)->dispose = fl_keyboard_manager_user_data_dispose;
|
||||
static void fl_keyboard_manager_data_class_init(
|
||||
FlKeyboardManagerDataClass* klass) {
|
||||
G_OBJECT_CLASS(klass)->dispose = fl_keyboard_manager_data_dispose;
|
||||
}
|
||||
|
||||
static void fl_keyboard_manager_user_data_init(
|
||||
FlKeyboardManagerUserData* self) {}
|
||||
static void fl_keyboard_manager_data_init(FlKeyboardManagerData* self) {}
|
||||
|
||||
// Creates a new FlKeyboardManagerUserData private class with all information.
|
||||
static FlKeyboardManagerUserData* fl_keyboard_manager_user_data_new(
|
||||
// Creates a new FlKeyboardManagerData private class with all information.
|
||||
static FlKeyboardManagerData* fl_keyboard_manager_data_new(
|
||||
FlKeyboardManager* manager,
|
||||
uint64_t sequence_id) {
|
||||
FlKeyboardManagerUserData* self = FL_KEYBOARD_MANAGER_USER_DATA(
|
||||
g_object_new(fl_keyboard_manager_user_data_get_type(), nullptr));
|
||||
FlKeyboardPendingEvent* pending) {
|
||||
FlKeyboardManagerData* self = FL_KEYBOARD_MANAGER_DATA(
|
||||
g_object_new(fl_keyboard_manager_data_get_type(), nullptr));
|
||||
|
||||
g_weak_ref_init(&self->manager, manager);
|
||||
self->sequence_id = sequence_id;
|
||||
self->pending = FL_KEYBOARD_PENDING_EVENT(g_object_ref(pending));
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -148,9 +146,6 @@ struct _FlKeyboardManager {
|
||||
// Its elements are unreferenced when removed.
|
||||
GPtrArray* pending_redispatches;
|
||||
|
||||
// The last sequence ID used. Increased by 1 by every use.
|
||||
uint64_t last_sequence_id;
|
||||
|
||||
// Record the derived layout.
|
||||
//
|
||||
// It is cleared when the platform reports a layout switch. Each entry,
|
||||
@ -205,15 +200,6 @@ static gboolean g_ptr_array_find_with_equal_func1(GPtrArray* haystack,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Compare a #FlKeyboardPendingEvent with the given sequence_id.
|
||||
static gboolean compare_pending_by_sequence_id(gconstpointer a,
|
||||
gconstpointer b) {
|
||||
FlKeyboardPendingEvent* pending =
|
||||
FL_KEYBOARD_PENDING_EVENT(const_cast<gpointer>(a));
|
||||
uint64_t sequence_id = *reinterpret_cast<const uint64_t*>(b);
|
||||
return fl_keyboard_pending_event_get_sequence_id(pending) == sequence_id;
|
||||
}
|
||||
|
||||
// Compare a #FlKeyboardPendingEvent with the given hash.
|
||||
static gboolean compare_pending_by_hash(gconstpointer a, gconstpointer b) {
|
||||
FlKeyboardPendingEvent* pending =
|
||||
@ -242,50 +228,23 @@ static bool fl_keyboard_manager_remove_redispatched(FlKeyboardManager* self,
|
||||
}
|
||||
|
||||
// The callback used by a responder after the event was dispatched.
|
||||
static void responder_handle_event_callback(bool handled,
|
||||
gpointer user_data_ptr,
|
||||
gboolean is_embedder) {
|
||||
g_return_if_fail(FL_IS_KEYBOARD_MANAGER_USER_DATA(user_data_ptr));
|
||||
FlKeyboardManagerUserData* user_data =
|
||||
FL_KEYBOARD_MANAGER_USER_DATA(user_data_ptr);
|
||||
|
||||
g_autoptr(FlKeyboardManager) self =
|
||||
FL_KEYBOARD_MANAGER(g_weak_ref_get(&user_data->manager));
|
||||
if (self == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
static void responder_handle_event_callback(FlKeyboardManager* self,
|
||||
FlKeyboardPendingEvent* pending) {
|
||||
g_autoptr(FlKeyboardViewDelegate) view_delegate =
|
||||
FL_KEYBOARD_VIEW_DELEGATE(g_weak_ref_get(&self->view_delegate));
|
||||
if (view_delegate == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
guint result_index = -1;
|
||||
gboolean found = g_ptr_array_find_with_equal_func1(
|
||||
self->pending_responds, &user_data->sequence_id,
|
||||
compare_pending_by_sequence_id, &result_index);
|
||||
g_return_if_fail(found);
|
||||
FlKeyboardPendingEvent* pending = FL_KEYBOARD_PENDING_EVENT(
|
||||
g_ptr_array_index(self->pending_responds, result_index));
|
||||
g_return_if_fail(pending != nullptr);
|
||||
if (is_embedder) {
|
||||
fl_keyboard_pending_event_mark_embedder_replied(pending, handled);
|
||||
} else {
|
||||
fl_keyboard_pending_event_mark_channel_replied(pending, handled);
|
||||
}
|
||||
// All responders have replied.
|
||||
if (fl_keyboard_pending_event_is_complete(pending)) {
|
||||
g_object_unref(user_data_ptr);
|
||||
gpointer removed =
|
||||
g_ptr_array_remove_index_fast(self->pending_responds, result_index);
|
||||
g_return_if_fail(removed == pending);
|
||||
g_ptr_array_remove(self->pending_responds, pending);
|
||||
bool should_redispatch =
|
||||
!fl_keyboard_pending_event_get_any_handled(pending) &&
|
||||
!fl_keyboard_view_delegate_text_filter_key_press(
|
||||
view_delegate, fl_keyboard_pending_event_get_event(pending));
|
||||
if (should_redispatch) {
|
||||
g_ptr_array_add(self->pending_redispatches, pending);
|
||||
g_ptr_array_add(self->pending_redispatches, g_object_ref(pending));
|
||||
FlKeyEvent* event = fl_keyboard_pending_event_get_event(pending);
|
||||
if (self->redispatch_handler != nullptr) {
|
||||
self->redispatch_handler(event, self->redispatch_handler_user_data);
|
||||
@ -296,20 +255,38 @@ static void responder_handle_event_callback(bool handled,
|
||||
event_type == GDK_KEY_RELEASE);
|
||||
gdk_event_put(fl_key_event_get_origin(event));
|
||||
}
|
||||
} else {
|
||||
g_object_unref(pending);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void responder_handle_embedder_event_callback(bool handled,
|
||||
gpointer user_data_ptr) {
|
||||
responder_handle_event_callback(handled, user_data_ptr, TRUE);
|
||||
gpointer user_data) {
|
||||
g_autoptr(FlKeyboardManagerData) data = FL_KEYBOARD_MANAGER_DATA(user_data);
|
||||
|
||||
fl_keyboard_pending_event_mark_embedder_replied(data->pending, handled);
|
||||
|
||||
g_autoptr(FlKeyboardManager) self =
|
||||
FL_KEYBOARD_MANAGER(g_weak_ref_get(&data->manager));
|
||||
if (self == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
responder_handle_event_callback(self, data->pending);
|
||||
}
|
||||
|
||||
static void responder_handle_channel_event_callback(bool handled,
|
||||
gpointer user_data_ptr) {
|
||||
responder_handle_event_callback(handled, user_data_ptr, FALSE);
|
||||
gpointer user_data) {
|
||||
g_autoptr(FlKeyboardManagerData) data = FL_KEYBOARD_MANAGER_DATA(user_data);
|
||||
|
||||
fl_keyboard_pending_event_mark_channel_replied(data->pending, handled);
|
||||
|
||||
g_autoptr(FlKeyboardManager) self =
|
||||
FL_KEYBOARD_MANAGER(g_weak_ref_get(&data->manager));
|
||||
if (self == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
responder_handle_event_callback(self, data->pending);
|
||||
}
|
||||
|
||||
static uint16_t convert_key_to_char(FlKeyboardManager* self,
|
||||
@ -459,8 +436,6 @@ static void fl_keyboard_manager_init(FlKeyboardManager* self) {
|
||||
self->pending_responds = g_ptr_array_new();
|
||||
self->pending_redispatches = g_ptr_array_new_with_free_func(g_object_unref);
|
||||
|
||||
self->last_sequence_id = 1;
|
||||
|
||||
self->keymap = gdk_keymap_get_for_display(gdk_display_get_default());
|
||||
self->keymap_keys_changed_cb_id = g_signal_connect_swapped(
|
||||
self->keymap, "keys-changed", G_CALLBACK(keymap_keys_changed_cb), self);
|
||||
@ -511,21 +486,20 @@ gboolean fl_keyboard_manager_handle_event(FlKeyboardManager* self,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FlKeyboardPendingEvent* pending =
|
||||
fl_keyboard_pending_event_new(event, ++self->last_sequence_id);
|
||||
FlKeyboardPendingEvent* pending = fl_keyboard_pending_event_new(event);
|
||||
|
||||
g_ptr_array_add(self->pending_responds, pending);
|
||||
FlKeyboardManagerUserData* user_data = fl_keyboard_manager_user_data_new(
|
||||
self, fl_keyboard_pending_event_get_sequence_id(pending));
|
||||
g_autoptr(FlKeyboardManagerData) data =
|
||||
fl_keyboard_manager_data_new(self, pending);
|
||||
uint64_t specified_logical_key = fl_keyboard_layout_get_logical_key(
|
||||
self->derived_layout, fl_key_event_get_group(event),
|
||||
fl_key_event_get_keycode(event));
|
||||
fl_key_embedder_responder_handle_event(
|
||||
self->key_embedder_responder, event, specified_logical_key,
|
||||
responder_handle_embedder_event_callback, user_data);
|
||||
responder_handle_embedder_event_callback, g_object_ref(data));
|
||||
fl_key_channel_responder_handle_event(
|
||||
self->key_channel_responder, event, specified_logical_key,
|
||||
responder_handle_channel_event_callback, user_data);
|
||||
responder_handle_channel_event_callback, g_object_ref(data));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -19,9 +19,6 @@ struct _FlKeyboardPendingEvent {
|
||||
// The target event.
|
||||
FlKeyEvent* event;
|
||||
|
||||
// Unique ID to identify pending responds.
|
||||
uint64_t sequence_id;
|
||||
|
||||
// True if the embedder responder has replied.
|
||||
bool embedder_replied;
|
||||
|
||||
@ -58,13 +55,11 @@ static void fl_keyboard_pending_event_init(FlKeyboardPendingEvent* self) {}
|
||||
|
||||
// Creates a new FlKeyboardPendingEvent by providing the target event,
|
||||
// the sequence ID, and the number of responders that will reply.
|
||||
FlKeyboardPendingEvent* fl_keyboard_pending_event_new(FlKeyEvent* event,
|
||||
uint64_t sequence_id) {
|
||||
FlKeyboardPendingEvent* fl_keyboard_pending_event_new(FlKeyEvent* event) {
|
||||
FlKeyboardPendingEvent* self = FL_KEYBOARD_PENDING_EVENT(
|
||||
g_object_new(fl_keyboard_pending_event_get_type(), nullptr));
|
||||
|
||||
self->event = FL_KEY_EVENT(g_object_ref(event));
|
||||
self->sequence_id = sequence_id;
|
||||
self->hash = fl_key_event_hash(self->event);
|
||||
|
||||
return self;
|
||||
@ -75,12 +70,6 @@ FlKeyEvent* fl_keyboard_pending_event_get_event(FlKeyboardPendingEvent* self) {
|
||||
return self->event;
|
||||
}
|
||||
|
||||
uint64_t fl_keyboard_pending_event_get_sequence_id(
|
||||
FlKeyboardPendingEvent* self) {
|
||||
g_return_val_if_fail(FL_IS_KEYBOARD_PENDING_EVENT(self), 0);
|
||||
return self->sequence_id;
|
||||
}
|
||||
|
||||
uint64_t fl_keyboard_pending_event_get_hash(FlKeyboardPendingEvent* self) {
|
||||
g_return_val_if_fail(FL_IS_KEYBOARD_PENDING_EVENT(self), 0);
|
||||
return self->hash;
|
||||
|
||||
@ -15,14 +15,10 @@ G_DECLARE_FINAL_TYPE(FlKeyboardPendingEvent,
|
||||
KEYBOARD_PENDING_EVENT,
|
||||
GObject);
|
||||
|
||||
FlKeyboardPendingEvent* fl_keyboard_pending_event_new(FlKeyEvent* event,
|
||||
uint64_t sequence_id);
|
||||
FlKeyboardPendingEvent* fl_keyboard_pending_event_new(FlKeyEvent* event);
|
||||
|
||||
FlKeyEvent* fl_keyboard_pending_event_get_event(FlKeyboardPendingEvent* event);
|
||||
|
||||
uint64_t fl_keyboard_pending_event_get_sequence_id(
|
||||
FlKeyboardPendingEvent* event);
|
||||
|
||||
uint64_t fl_keyboard_pending_event_get_hash(FlKeyboardPendingEvent* event);
|
||||
|
||||
void fl_keyboard_pending_event_mark_embedder_replied(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user