Move FlKeyboardManager and FlKeyboardHandler from FlView to FlEngine. (#161925)
There can only be one handler that is shared between the views. Move event redispatch matcher back into FlKeyboardManager - if a redispatched event was moved between views due to a focus change it would not be matched against.
This commit is contained in:
parent
391fecdfac
commit
2d3beadffe
@ -14,6 +14,7 @@
|
||||
#include "flutter/shell/platform/linux/fl_dart_project_private.h"
|
||||
#include "flutter/shell/platform/linux/fl_display_monitor.h"
|
||||
#include "flutter/shell/platform/linux/fl_engine_private.h"
|
||||
#include "flutter/shell/platform/linux/fl_keyboard_handler.h"
|
||||
#include "flutter/shell/platform/linux/fl_pixel_buffer_texture_private.h"
|
||||
#include "flutter/shell/platform/linux/fl_platform_handler.h"
|
||||
#include "flutter/shell/platform/linux/fl_plugin_registrar_private.h"
|
||||
@ -57,6 +58,12 @@ struct _FlEngine {
|
||||
// Implements the flutter/platform channel.
|
||||
FlPlatformHandler* platform_handler;
|
||||
|
||||
// Process keyboard events.
|
||||
FlKeyboardManager* keyboard_manager;
|
||||
|
||||
// Implements the flutter/keyboard channel.
|
||||
FlKeyboardHandler* keyboard_handler;
|
||||
|
||||
// Implements the flutter/mousecursor channel.
|
||||
FlMouseCursorHandler* mouse_cursor_handler;
|
||||
|
||||
@ -381,6 +388,14 @@ static void fl_engine_update_semantics_cb(const FlutterSemanticsUpdate2* update,
|
||||
}
|
||||
}
|
||||
|
||||
static void setup_keyboard(FlEngine* self) {
|
||||
g_clear_object(&self->keyboard_manager);
|
||||
self->keyboard_manager = fl_keyboard_manager_new(self);
|
||||
g_clear_object(&self->keyboard_handler);
|
||||
self->keyboard_handler =
|
||||
fl_keyboard_handler_new(self->binary_messenger, self->keyboard_manager);
|
||||
}
|
||||
|
||||
// Called right before the engine is restarted.
|
||||
//
|
||||
// This method should reset states to as if the engine has just been started,
|
||||
@ -389,6 +404,8 @@ static void fl_engine_update_semantics_cb(const FlutterSemanticsUpdate2* update,
|
||||
static void fl_engine_on_pre_engine_restart_cb(void* user_data) {
|
||||
FlEngine* self = FL_ENGINE(user_data);
|
||||
|
||||
setup_keyboard(self);
|
||||
|
||||
g_signal_emit(self, fl_engine_signals[SIGNAL_ON_PRE_ENGINE_RESTART], 0);
|
||||
}
|
||||
|
||||
@ -455,6 +472,8 @@ static void fl_engine_dispose(GObject* object) {
|
||||
g_clear_object(&self->binary_messenger);
|
||||
g_clear_object(&self->settings_handler);
|
||||
g_clear_object(&self->platform_handler);
|
||||
g_clear_object(&self->keyboard_manager);
|
||||
g_clear_object(&self->keyboard_handler);
|
||||
g_clear_object(&self->mouse_cursor_handler);
|
||||
g_clear_object(&self->task_runner);
|
||||
|
||||
@ -646,6 +665,8 @@ gboolean fl_engine_start(FlEngine* self, GError** error) {
|
||||
self->mouse_cursor_handler =
|
||||
fl_mouse_cursor_handler_new(self->binary_messenger);
|
||||
|
||||
setup_keyboard(self);
|
||||
|
||||
result = self->embedder_api.UpdateSemanticsEnabled(self->engine, TRUE);
|
||||
if (result != kSuccess) {
|
||||
g_warning("Failed to enable accessibility features on Flutter engine");
|
||||
@ -1238,6 +1259,11 @@ void fl_engine_request_app_exit(FlEngine* self) {
|
||||
fl_platform_handler_request_app_exit(self->platform_handler);
|
||||
}
|
||||
|
||||
FlKeyboardManager* fl_engine_get_keyboard_manager(FlEngine* self) {
|
||||
g_return_val_if_fail(FL_IS_ENGINE(self), nullptr);
|
||||
return self->keyboard_manager;
|
||||
}
|
||||
|
||||
FlMouseCursorHandler* fl_engine_get_mouse_cursor_handler(FlEngine* self) {
|
||||
g_return_val_if_fail(FL_IS_ENGINE(self), nullptr);
|
||||
return self->mouse_cursor_handler;
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "flutter/shell/platform/embedder/embedder.h"
|
||||
#include "flutter/shell/platform/linux/fl_display_monitor.h"
|
||||
#include "flutter/shell/platform/linux/fl_keyboard_manager.h"
|
||||
#include "flutter/shell/platform/linux/fl_mouse_cursor_handler.h"
|
||||
#include "flutter/shell/platform/linux/fl_renderer.h"
|
||||
#include "flutter/shell/platform/linux/fl_task_runner.h"
|
||||
@ -563,6 +564,16 @@ void fl_engine_update_accessibility_features(FlEngine* engine, int32_t flags);
|
||||
*/
|
||||
void fl_engine_request_app_exit(FlEngine* engine);
|
||||
|
||||
/**
|
||||
* fl_engine_get_keyboard_manager:
|
||||
* @engine: an #FlEngine.
|
||||
*
|
||||
* Gets the keyboard manager used by this engine.
|
||||
*
|
||||
* Returns: a #FlKeyboardManager.
|
||||
*/
|
||||
FlKeyboardManager* fl_engine_get_keyboard_manager(FlEngine* engine);
|
||||
|
||||
/**
|
||||
* fl_engine_get_mouse_cursor_handler:
|
||||
* @engine: an #FlEngine.
|
||||
|
@ -95,6 +95,9 @@ struct _FlKeyboardManager {
|
||||
FlKeyboardManagerGetPressedStateHandler get_pressed_state_handler;
|
||||
gpointer get_pressed_state_handler_user_data;
|
||||
|
||||
// Key events that have been redispatched.
|
||||
GPtrArray* redispatched_key_events;
|
||||
|
||||
FlKeyEmbedderResponder* key_embedder_responder;
|
||||
|
||||
FlKeyChannelResponder* key_channel_responder;
|
||||
@ -126,6 +129,25 @@ struct _FlKeyboardManager {
|
||||
|
||||
G_DEFINE_TYPE(FlKeyboardManager, fl_keyboard_manager, G_TYPE_OBJECT);
|
||||
|
||||
static gboolean event_is_redispatched(FlKeyboardManager* self,
|
||||
FlKeyEvent* event) {
|
||||
guint32 time = fl_key_event_get_time(event);
|
||||
gboolean is_press = !!fl_key_event_get_is_press(event);
|
||||
guint16 keycode = fl_key_event_get_keycode(event);
|
||||
for (guint i = 0; i < self->redispatched_key_events->len; i++) {
|
||||
FlKeyEvent* e =
|
||||
FL_KEY_EVENT(g_ptr_array_index(self->redispatched_key_events, i));
|
||||
if (fl_key_event_get_time(e) == time &&
|
||||
!!fl_key_event_get_is_press(e) == is_press &&
|
||||
fl_key_event_get_keycode(e) == keycode) {
|
||||
g_ptr_array_remove_index(self->redispatched_key_events, i);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void keymap_keys_changed_cb(FlKeyboardManager* self) {
|
||||
g_clear_object(&self->derived_layout);
|
||||
self->derived_layout = fl_keyboard_layout_new();
|
||||
@ -292,6 +314,7 @@ static void fl_keyboard_manager_dispose(GObject* object) {
|
||||
self->keycode_to_goals.reset();
|
||||
self->logical_to_mandatory_goals.reset();
|
||||
|
||||
g_clear_pointer(&self->redispatched_key_events, g_ptr_array_unref);
|
||||
g_clear_object(&self->key_embedder_responder);
|
||||
g_clear_object(&self->key_channel_responder);
|
||||
g_clear_object(&self->derived_layout);
|
||||
@ -309,6 +332,8 @@ static void fl_keyboard_manager_class_init(FlKeyboardManagerClass* klass) {
|
||||
}
|
||||
|
||||
static void fl_keyboard_manager_init(FlKeyboardManager* self) {
|
||||
self->redispatched_key_events =
|
||||
g_ptr_array_new_with_free_func(g_object_unref);
|
||||
self->derived_layout = fl_keyboard_layout_new();
|
||||
|
||||
self->keycode_to_goals =
|
||||
@ -383,6 +408,13 @@ FlKeyboardManager* fl_keyboard_manager_new(FlEngine* engine) {
|
||||
return self;
|
||||
}
|
||||
|
||||
void fl_keyboard_manager_add_redispatched_event(FlKeyboardManager* self,
|
||||
FlKeyEvent* event) {
|
||||
g_return_if_fail(FL_IS_KEYBOARD_MANAGER(self));
|
||||
|
||||
g_ptr_array_add(self->redispatched_key_events, g_object_ref(event));
|
||||
}
|
||||
|
||||
void fl_keyboard_manager_handle_event(FlKeyboardManager* self,
|
||||
FlKeyEvent* event,
|
||||
GCancellable* cancellable,
|
||||
@ -399,6 +431,14 @@ void fl_keyboard_manager_handle_event(FlKeyboardManager* self,
|
||||
task, handle_event_data_new(event),
|
||||
reinterpret_cast<GDestroyNotify>(handle_event_data_free));
|
||||
|
||||
if (event_is_redispatched(self, event)) {
|
||||
HandleEventData* data =
|
||||
static_cast<HandleEventData*>(g_task_get_task_data(task));
|
||||
data->handled = TRUE;
|
||||
g_task_return_boolean(task, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
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));
|
||||
|
@ -45,6 +45,16 @@ G_DECLARE_FINAL_TYPE(FlKeyboardManager,
|
||||
*/
|
||||
FlKeyboardManager* fl_keyboard_manager_new(FlEngine* engine);
|
||||
|
||||
/** fl_keyboard_manager_add_redispatched_event:
|
||||
* @manager: an #FlKeyboardManager.
|
||||
* @event: an event that will be handled by the manager in the future.
|
||||
*
|
||||
* Add an event that will be redispatched and handled by the manager in the
|
||||
* future. When that event is received it will be ignored.
|
||||
*/
|
||||
void fl_keyboard_manager_add_redispatched_event(FlKeyboardManager* manager,
|
||||
FlKeyEvent* event);
|
||||
|
||||
/**
|
||||
* fl_keyboard_manager_handle_event:
|
||||
* @manager: an #FlKeyboardManager.
|
||||
|
@ -13,8 +13,6 @@
|
||||
#include "flutter/shell/platform/linux/fl_accessible_node.h"
|
||||
#include "flutter/shell/platform/linux/fl_engine_private.h"
|
||||
#include "flutter/shell/platform/linux/fl_key_event.h"
|
||||
#include "flutter/shell/platform/linux/fl_keyboard_handler.h"
|
||||
#include "flutter/shell/platform/linux/fl_keyboard_manager.h"
|
||||
#include "flutter/shell/platform/linux/fl_plugin_registrar_private.h"
|
||||
#include "flutter/shell/platform/linux/fl_pointer_manager.h"
|
||||
#include "flutter/shell/platform/linux/fl_renderer_gdk.h"
|
||||
@ -64,14 +62,7 @@ struct _FlView {
|
||||
// Manages touch events.
|
||||
FlTouchManager* touch_manager;
|
||||
|
||||
// Manages keyboard events.
|
||||
FlKeyboardManager* keyboard_manager;
|
||||
|
||||
// Key events that have been redispatched.
|
||||
GPtrArray* redispatched_key_events;
|
||||
|
||||
// Flutter system channel handlers.
|
||||
FlKeyboardHandler* keyboard_handler;
|
||||
FlTextInputHandler* text_input_handler;
|
||||
|
||||
// Accessible tree from Flutter, exposed as an AtkPlug.
|
||||
@ -134,12 +125,6 @@ static void init_keyboard(FlView* self) {
|
||||
g_clear_object(&self->text_input_handler);
|
||||
self->text_input_handler = fl_text_input_handler_new(
|
||||
messenger, im_context, FL_TEXT_INPUT_VIEW_DELEGATE(self));
|
||||
g_clear_object(&self->keyboard_manager);
|
||||
self->keyboard_manager = fl_keyboard_manager_new(self->engine);
|
||||
g_ptr_array_set_size(self->redispatched_key_events, 0);
|
||||
g_clear_object(&self->keyboard_handler);
|
||||
self->keyboard_handler =
|
||||
fl_keyboard_handler_new(messenger, self->keyboard_manager);
|
||||
}
|
||||
|
||||
static void init_scrolling(FlView* self) {
|
||||
@ -345,8 +330,8 @@ static void sync_modifier_if_needed(FlView* self, GdkEvent* event) {
|
||||
guint event_time = gdk_event_get_time(event);
|
||||
GdkModifierType event_state = static_cast<GdkModifierType>(0);
|
||||
gdk_event_get_state(event, &event_state);
|
||||
fl_keyboard_manager_sync_modifier_if_needed(self->keyboard_manager,
|
||||
event_state, event_time);
|
||||
fl_keyboard_manager_sync_modifier_if_needed(
|
||||
fl_engine_get_keyboard_manager(self->engine), event_state, event_time);
|
||||
}
|
||||
|
||||
static void set_scrolling_position(FlView* self, gdouble x, gdouble y) {
|
||||
@ -642,9 +627,6 @@ static void fl_view_dispose(GObject* object) {
|
||||
g_clear_object(&self->scrolling_manager);
|
||||
g_clear_object(&self->pointer_manager);
|
||||
g_clear_object(&self->touch_manager);
|
||||
g_clear_object(&self->keyboard_manager);
|
||||
g_clear_pointer(&self->redispatched_key_events, g_ptr_array_unref);
|
||||
g_clear_object(&self->keyboard_handler);
|
||||
g_clear_object(&self->view_accessible);
|
||||
g_clear_object(&self->cancellable);
|
||||
|
||||
@ -661,34 +643,12 @@ static void fl_view_realize(GtkWidget* widget) {
|
||||
gtk_widget_realize(GTK_WIDGET(self->gl_area));
|
||||
}
|
||||
|
||||
static gboolean event_is_redispatched(FlView* self, FlKeyEvent* event) {
|
||||
guint32 time = fl_key_event_get_time(event);
|
||||
gboolean is_press = !!fl_key_event_get_is_press(event);
|
||||
guint16 keycode = fl_key_event_get_keycode(event);
|
||||
for (guint i = 0; i < self->redispatched_key_events->len; i++) {
|
||||
FlKeyEvent* e =
|
||||
FL_KEY_EVENT(g_ptr_array_index(self->redispatched_key_events, i));
|
||||
if (fl_key_event_get_time(e) == time &&
|
||||
!!fl_key_event_get_is_press(e) == is_press &&
|
||||
fl_key_event_get_keycode(e) == keycode) {
|
||||
g_ptr_array_remove_index(self->redispatched_key_events, i);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean handle_key_event(FlView* self, GdkEventKey* key_event) {
|
||||
g_autoptr(FlKeyEvent) event = fl_key_event_new_from_gdk_event(
|
||||
gdk_event_copy(reinterpret_cast<GdkEvent*>(key_event)));
|
||||
|
||||
if (event_is_redispatched(self, event)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fl_keyboard_manager_handle_event(
|
||||
self->keyboard_manager, event, self->cancellable,
|
||||
fl_engine_get_keyboard_manager(self->engine), event, self->cancellable,
|
||||
[](GObject* object, GAsyncResult* result, gpointer user_data) {
|
||||
FlView* self = FL_VIEW(user_data);
|
||||
|
||||
@ -707,8 +667,8 @@ static gboolean handle_key_event(FlView* self, GdkEventKey* key_event) {
|
||||
if (redispatch_event != nullptr) {
|
||||
if (!fl_text_input_handler_filter_keypress(self->text_input_handler,
|
||||
redispatch_event)) {
|
||||
g_ptr_array_add(self->redispatched_key_events,
|
||||
g_object_ref(redispatch_event));
|
||||
fl_keyboard_manager_add_redispatched_event(
|
||||
fl_engine_get_keyboard_manager(self->engine), redispatch_event);
|
||||
gdk_event_put(fl_key_event_get_origin(redispatch_event));
|
||||
}
|
||||
}
|
||||
@ -761,9 +721,6 @@ static void fl_view_init(FlView* self) {
|
||||
.red = 0.0, .green = 0.0, .blue = 0.0, .alpha = 1.0};
|
||||
self->background_color = gdk_rgba_copy(&default_background);
|
||||
|
||||
self->redispatched_key_events =
|
||||
g_ptr_array_new_with_free_func(g_object_unref);
|
||||
|
||||
GtkWidget* event_box = gtk_event_box_new();
|
||||
gtk_widget_set_hexpand(event_box, TRUE);
|
||||
gtk_widget_set_vexpand(event_box, TRUE);
|
||||
|
Loading…
x
Reference in New Issue
Block a user