Flutter Engine
fl_key_event_plugin.h File Reference
#include "flutter/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h"
#include <gdk/gdk.h>

Go to the source code of this file.

Functions

G_BEGIN_DECLS G_DECLARE_FINAL_TYPE (FlKeyEventPlugin, fl_key_event_plugin, FL, KEY_EVENT_PLUGIN, GObject)
 
FlKeyEventPlugin * fl_key_event_plugin_new (FlBinaryMessenger *messenger, GAsyncReadyCallback response_callback=nullptr, const char *channel_name=nullptr)
 
void fl_key_event_plugin_send_key_event (FlKeyEventPlugin *plugin, GdkEventKey *event, gpointer user_data=nullptr)
 

Function Documentation

◆ fl_key_event_plugin_new()

FlKeyEventPlugin* fl_key_event_plugin_new ( FlBinaryMessenger *  messenger,
GAsyncReadyCallback  response_callback = nullptr,
const char *  channel_name = nullptr 
)

FlKeyEventPlugin:

#FlKeyEventPlugin is a plugin that implements the shell side of SystemChannels.keyEvent from the Flutter services library. fl_key_event_plugin_new: : an #FlBinaryMessenger. : the callback to call when a response is received. If not given (nullptr), then the default response callback is used. : the name of the channel to send key events on. If not given (nullptr), then the standard key event channel name is used. Typically used for tests to send on a test channel.

Creates a new plugin that implements SystemChannels.keyEvent from the Flutter services library.

Returns: a new #FlKeyEventPlugin.

Definition at line 46 of file fl_key_event_plugin.cc.

References fl_basic_message_channel_new(), fl_json_message_codec_new(), kChannelName, and _FlKeyEventPlugin::response_callback.

Referenced by fl_view_constructed(), TEST(), and test_lock_event().

48  {
49  g_return_val_if_fail(FL_IS_BINARY_MESSENGER(messenger), nullptr);
50 
51  FlKeyEventPlugin* self = FL_KEY_EVENT_PLUGIN(
52  g_object_new(fl_key_event_plugin_get_type(), nullptr));
53 
54  g_autoptr(FlJsonMessageCodec) codec = fl_json_message_codec_new();
55  self->channel = fl_basic_message_channel_new(
56  messenger, channel_name == nullptr ? kChannelName : channel_name,
57  FL_MESSAGE_CODEC(codec));
58  self->response_callback = response_callback;
59 
60  return self;
61 }
G_MODULE_EXPORT FlBasicMessageChannel * fl_basic_message_channel_new(FlBinaryMessenger *messenger, const gchar *name, FlMessageCodec *codec)
G_MODULE_EXPORT FlJsonMessageCodec * fl_json_message_codec_new()
static constexpr char kChannelName[]

◆ fl_key_event_plugin_send_key_event()

void fl_key_event_plugin_send_key_event ( FlKeyEventPlugin *  plugin,
GdkEventKey *  event,
gpointer  user_data = nullptr 
)

fl_key_event_plugin_send_key_event: : an #FlKeyEventPlugin. : a #GdkEventKey. : a pointer to user data to send to the response callback via the messenger.

Sends a key event to Flutter.

Definition at line 63 of file fl_key_event_plugin.cc.

References fl_basic_message_channel_send(), fl_value_new_int(), fl_value_new_map(), fl_value_new_string(), fl_value_set_string_take(), kGtkToolkit, kKeyCodeKey, kKeymapKey, kLinuxKeymap, kModifiersKey, kScanCodeKey, kToolkitKey, kTypeKey, kTypeValueDown, kTypeValueUp, and kUnicodeScalarValuesKey.

Referenced by fl_view_key_press_event(), fl_view_key_release_event(), TEST(), and test_lock_event().

65  {
66  g_return_if_fail(FL_IS_KEY_EVENT_PLUGIN(self));
67  g_return_if_fail(event != nullptr);
68 
69  const gchar* type;
70  switch (event->type) {
71  case GDK_KEY_PRESS:
72  type = kTypeValueDown;
73  break;
74  case GDK_KEY_RELEASE:
75  type = kTypeValueUp;
76  break;
77  default:
78  return;
79  }
80 
81  int64_t scan_code = event->hardware_keycode;
82  int64_t unicodeScalarValues = gdk_keyval_to_unicode(event->keyval);
83 
84  // For most modifier keys, GTK keeps track of the "pressed" state of the
85  // modifier keys. Flutter uses this information to keep modifier keys from
86  // being "stuck" when a key-up event is lost because it happens after the app
87  // loses focus.
88  //
89  // For Lock keys (ShiftLock, CapsLock, NumLock), however, GTK keeps track of
90  // the state of the locks themselves, not the "pressed" state of the key.
91  //
92  // Since Flutter expects the "pressed" state of the modifier keys, the lock
93  // state for these keys is discarded here, and it is substituted for the
94  // pressed state of the key.
95  //
96  // This code has the flaw that if a key event is missed due to the app losing
97  // focus, then this state will still think the key is pressed when it isn't,
98  // but that is no worse than for "regular" keys until we implement the
99  // sync/cancel events on app focus changes.
100  //
101  // This is necessary to do here instead of in the framework because Flutter
102  // does modifier key syncing in the framework, and will turn on/off these keys
103  // as being "pressed" whenever the lock is on, which breaks a lot of
104  // interactions (for example, if shift-lock is on, tab traversal is broken).
105  //
106  // TODO(gspencergoog): get rid of this tracked state when we are tracking the
107  // state of all keys and sending sync/cancel events when focus is gained/lost.
108 
109  // Remove lock states from state mask.
110  guint state = event->state & ~(GDK_LOCK_MASK | GDK_MOD2_MASK);
111 
112  static bool shift_lock_pressed = false;
113  static bool caps_lock_pressed = false;
114  static bool num_lock_pressed = false;
115  switch (event->keyval) {
116  case GDK_KEY_Num_Lock:
117  num_lock_pressed = event->type == GDK_KEY_PRESS;
118  break;
119  case GDK_KEY_Caps_Lock:
120  caps_lock_pressed = event->type == GDK_KEY_PRESS;
121  break;
122  case GDK_KEY_Shift_Lock:
123  shift_lock_pressed = event->type == GDK_KEY_PRESS;
124  break;
125  }
126 
127  // Add back in the state matching the actual pressed state of the lock keys,
128  // not the lock states.
129  state |= (shift_lock_pressed || caps_lock_pressed) ? GDK_LOCK_MASK : 0x0;
130  state |= num_lock_pressed ? GDK_MOD2_MASK : 0x0;
131 
132  g_autoptr(FlValue) message = fl_value_new_map();
140  fl_value_new_int(event->keyval));
142  if (unicodeScalarValues != 0) {
144  fl_value_new_int(unicodeScalarValues));
145  }
146 
147  fl_basic_message_channel_send(self->channel, message, nullptr,
148  self->response_callback, user_data);
149 }
static constexpr char kKeyCodeKey[]
static constexpr char kTypeValueDown[]
static constexpr char kLinuxKeymap[]
static constexpr char kKeymapKey[]
static constexpr char kModifiersKey[]
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition: fl_value.h:39
G_MODULE_EXPORT FlValue * fl_value_new_map()
Definition: fl_value.cc:327
static constexpr char kUnicodeScalarValuesKey[]
G_BEGIN_DECLS FlValue gpointer user_data
static constexpr char kGtkToolkit[]
GdkEventButton * event
Definition: fl_view.cc:62
G_MODULE_EXPORT FlValue * fl_value_new_int(int64_t value)
Definition: fl_value.cc:233
static constexpr char kScanCodeKey[]
G_MODULE_EXPORT FlValue * fl_value_new_string(const gchar *value)
Definition: fl_value.cc:247
G_MODULE_EXPORT void fl_basic_message_channel_send(FlBasicMessageChannel *self, FlValue *message, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
static constexpr char kTypeValueUp[]
G_MODULE_EXPORT void fl_value_set_string_take(FlValue *self, const gchar *key, FlValue *value)
Definition: fl_value.cc:564
static constexpr char kToolkitKey[]
static constexpr char kTypeKey[]

◆ G_DECLARE_FINAL_TYPE()

G_BEGIN_DECLS G_DECLARE_FINAL_TYPE ( FlKeyEventPlugin  ,
fl_key_event_plugin  ,
FL  ,
KEY_EVENT_PLUGIN  ,
GObject   
)