| Flutter Linux Embedder |

Classes | Functions
fl_key_channel_responder.cc File Reference
`#include "flutter/shell/platform/linux/fl_key_channel_responder.h"`
`#include <gtk/gtk.h>`
`#include <cinttypes>`
`#include "flutter/shell/platform/linux/fl_key_event_channel.h"`

Go to the source code of this file.

## Classes
struct | _FlKeyChannelResponder

## Functions
static void | handle_response (GObject *object, GAsyncResult *result, gpointer user_data)
static void | fl_key_channel_responder_dispose (GObject *object)
static void | fl_key_channel_responder_class_init (FlKeyChannelResponderClass *klass)
static void | fl_key_channel_responder_init (FlKeyChannelResponder *self)
FlKeyChannelResponder * | fl_key_channel_responder_new (FlBinaryMessenger *messenger)
void | fl_key_channel_responder_handle_event (FlKeyChannelResponder *self, FlKeyEvent *event, uint64_t specified_logical_key, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
gboolean | fl_key_channel_responder_handle_event_finish (FlKeyChannelResponder *self, GAsyncResult *result, gboolean *handled, GError **error)

## Function Documentation

## ◆ fl_key_channel_responder_class_init()

static void fl_key_channel_responder_class_init | ( | FlKeyChannelResponderClass * | klass | ) |
| static

Definition at line 48 of file fl_key_channel_responder.cc.

49 {
50 G_OBJECT_CLASS(klass)->dispose = fl_key_channel_responder_dispose;
51 }

References fl_key_channel_responder_dispose().

## ◆ fl_key_channel_responder_dispose()

static void fl_key_channel_responder_dispose | ( | GObject * | object | ) |
| static

Definition at line 39 of file fl_key_channel_responder.cc.

39 {
40 FlKeyChannelResponder* self = FL_KEY_CHANNEL_RESPONDER(object);
41
42 g_clear_object(&self->channel);
43
44 G_OBJECT_CLASS(fl_key_channel_responder_parent_class)->dispose(object);
45 }

Referenced by fl_key_channel_responder_class_init().

## ◆ fl_key_channel_responder_handle_event()

void fl_key_channel_responder_handle_event | ( | FlKeyChannelResponder * | responder,
|  | FlKeyEvent * | event,
|  | uint64_t | specified_logical_key,
|  | GCancellable * | cancellable,
|  | GAsyncReadyCallback | callback,
|  | gpointer | user_data
| ) |  |

fl_key_channel_responder_handle_event: @responder: the #FlKeyChannelResponder self. @event: the event to be handled. Must not be null. The object is managed by callee and must not be assumed available after this function. @specified_logical_key: @cancellable: (allow-none): a #GCancellable or NULL. @callback: (scope async): a #GAsyncReadyCallback to call when the event has been processed. @user_data: (closure): user data to pass to @callback.

Let the responder handle an event.

Definition at line 71 of file fl_key_channel_responder.cc.

76 {
77 g_return_if_fail(event != nullptr);
78 g_return_if_fail(callback != nullptr);
79
80 FlKeyEventType type = fl_key_event_get_is_press(event)
81 ? FL_KEY_EVENT_TYPE_KEYDOWN
82 : FL_KEY_EVENT_TYPE_KEYUP;
83 int64_t scan_code = fl_key_event_get_keycode(event);
84 int64_t unicode_scalar_values =
85 gdk_keyval_to_unicode(fl_key_event_get_keyval(event));
86
87 // For most modifier keys, GTK keeps track of the "pressed" state of the
88 // modifier keys. Flutter uses this information to keep modifier keys from
89 // being "stuck" when a key-up event is lost because it happens after the app
90 // loses focus.
91 //
92 // For Lock keys (ShiftLock, CapsLock, NumLock), however, GTK keeps track of
93 // the state of the locks themselves, not the "pressed" state of the key.
94 //
95 // Since Flutter expects the "pressed" state of the modifier keys, the lock
96 // state for these keys is discarded here, and it is substituted for the
97 // pressed state of the key.
98 //
99 // This code has the flaw that if a key event is missed due to the app losing
100 // focus, then this state will still think the key is pressed when it isn't,
101 // but that is no worse than for "regular" keys until we implement the
102 // sync/cancel events on app focus changes.
103 //
104 // This is necessary to do here instead of in the framework because Flutter
105 // does modifier key syncing in the framework, and will turn on/off these keys
106 // as being "pressed" whenever the lock is on, which breaks a lot of
107 // interactions (for example, if shift-lock is on, tab traversal is broken).
108
109 // Remove lock states from state mask.
110 guint state =
111 fl_key_event_get_state(event) & ~(GDK_LOCK_MASK | GDK_MOD2_MASK);
112
113 static bool shift_lock_pressed = FALSE;
114 static bool caps_lock_pressed = FALSE;
115 static bool num_lock_pressed = FALSE;
116 switch (fl_key_event_get_keyval(event)) {
117 case GDK_KEY_Num_Lock:
118 num_lock_pressed = fl_key_event_get_is_press(event);
119 break;
120 case GDK_KEY_Caps_Lock:
121 caps_lock_pressed = fl_key_event_get_is_press(event);
122 break;
123 case GDK_KEY_Shift_Lock:
124 shift_lock_pressed = fl_key_event_get_is_press(event);
125 break;
126 }
127
128 // Add back in the state matching the actual pressed state of the lock keys,
129 // not the lock states.
130 state |= (shift_lock_pressed || caps_lock_pressed) ? GDK_LOCK_MASK : 0x0;
131 state |= num_lock_pressed ? GDK_MOD2_MASK : 0x0;
132
133 fl_key_event_channel_send(
134 self->channel, type, scan_code, fl_key_event_get_keyval(event), state,
135 unicode_scalar_values, specified_logical_key, nullptr, handle_response,
136 g_task_new(self, cancellable, callback, user_data));
137 }

References fl_key_event_channel_send(), fl_key_event_get_is_press(), fl_key_event_get_keycode(), fl_key_event_get_keyval(), fl_key_event_get_state(), FL_KEY_EVENT_TYPE_KEYDOWN, FL_KEY_EVENT_TYPE_KEYUP, handle_response(), state, type, and user_data.

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

## ◆ fl_key_channel_responder_handle_event_finish()

gboolean fl_key_channel_responder_handle_event_finish | ( | FlKeyChannelResponder * | responder,
|  | GAsyncResult * | result,
|  | gboolean * | handled,
|  | GError ** | error
| ) |  |

fl_key_channel_responder_handle_event_finish: @responder: an #FlKeyChannelResponder.

Returns
  : a #GAsyncResult. @handled: location to write if this event was handled by the platform. @error: (allow-none): #GError location to store the error occurring, or NULL to ignore.

Completes request started with fl_key_channel_responder_handle_event().

Returns TRUE on success.

Definition at line 139 of file fl_key_channel_responder.cc.

143 {
144 g_return_val_if_fail(g_task_is_valid(result, self), FALSE);
145
146 g_autofree gboolean* return_value =
147 static_cast<gboolean*>(g_task_propagate_pointer(G_TASK(result), error));
148 if (return_value == nullptr) {
149 return FALSE;
150 }
151
152 *handled = *return_value;
153 return TRUE;
154 }

References error, and TRUE.

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

## ◆ fl_key_channel_responder_init()

static void fl_key_channel_responder_init | ( | FlKeyChannelResponder * | self | ) |
| static

Definition at line 54 of file fl_key_channel_responder.cc.

54 {}

## ◆ fl_key_channel_responder_new()

FlKeyChannelResponder* fl_key_channel_responder_new | ( | FlBinaryMessenger * | messenger | ) |

FlKeyChannelResponder:

A #FlKeyResponder that handles events by sending the raw event data in JSON through the message channel.

This class communicates with the RawKeyboard API in the framework. fl_key_channel_responder_new: @messenger: the messenger that the message channel should be built on.

Creates a new #FlKeyChannelResponder.

Returns: a new #FlKeyChannelResponder.

Definition at line 59 of file fl_key_channel_responder.cc.

60 {
61 g_return_val_if_fail(FL_IS_BINARY_MESSENGER(messenger), nullptr);
62
63 FlKeyChannelResponder* self = FL_KEY_CHANNEL_RESPONDER(
64 g_object_new(fl_key_channel_responder_get_type(), nullptr));
65
66 self->channel = fl_key_event_channel_new(messenger);
67
68 return self;
69 }

References fl_key_event_channel_new().

Referenced by TEST(), and test_lock_event().

## ◆ handle_response()

static void handle_response | ( | GObject * | object,
|  | GAsyncResult * | result,
|  | gpointer | user_data
| ) |  |
| static

Definition at line 22 of file fl_key_channel_responder.cc.

24 {
25 g_autoptr(GTask) task = G_TASK(user_data);
26
27 gboolean handled = FALSE;
28 g_autoptr(GError) error = nullptr;
29 if (!fl_key_event_channel_send_finish(object, result, &handled, &error)) {
30 g_warning("Unable to retrieve framework response: %s", error->message);
31 }
32
33 gboolean* return_value = g_new0(gboolean, 1);
34 *return_value = handled;
35 g_task_return_pointer(task, return_value, g_free);
36 }

References error, fl_key_event_channel_send_finish(), and user_data.

Referenced by fl_key_channel_responder_handle_event().

FL_KEY_EVENT_TYPE_KEYUP
@ FL_KEY_EVENT_TYPE_KEYUP
Definition: fl_key_event_channel.h:26
type
uint8_t type
Definition: fl_standard_message_codec_test.cc:1115
FlKeyEventType
FlKeyEventType
Definition: fl_key_event_channel.h:25
handle_response
static void handle_response(GObject *object, GAsyncResult *result, gpointer user_data)
Definition: fl_key_channel_responder.cc:22
fl_key_channel_responder_dispose
static void fl_key_channel_responder_dispose(GObject *object)
Definition: fl_key_channel_responder.cc:39
state
AtkStateType state
Definition: fl_accessible_node.cc:10
FL_KEY_EVENT_TYPE_KEYDOWN
@ FL_KEY_EVENT_TYPE_KEYDOWN
Definition: fl_key_event_channel.h:27
user_data
G_BEGIN_DECLS G_MODULE_EXPORT FlValue gpointer user_data
Definition: fl_event_channel.h:90
fl_key_event_get_keyval
guint fl_key_event_get_keyval(FlKeyEvent *self)
Definition: fl_key_event.cc:94
fl_key_event_channel_new
FlKeyEventChannel * fl_key_event_channel_new(FlBinaryMessenger *messenger)
Definition: fl_key_event_channel.cc:50
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
fl_key_event_channel_send_finish
gboolean fl_key_event_channel_send_finish(GObject *object, GAsyncResult *result, gboolean *handled, GError **error)
Definition: fl_key_event_channel.cc:108
fl_key_event_get_state
GdkModifierType fl_key_event_get_state(FlKeyEvent *self)
Definition: fl_key_event.cc:99
fl_key_event_get_keycode
guint16 fl_key_event_get_keycode(FlKeyEvent *self)
Definition: fl_key_event.cc:89
error
const uint8_t uint32_t uint32_t GError ** error
Definition: fl_pixel_buffer_texture_test.cc:40
fl_key_event_get_is_press
gboolean fl_key_event_get_is_press(FlKeyEvent *self)
Definition: fl_key_event.cc:84
fl_key_event_channel_send
void fl_key_event_channel_send(FlKeyEventChannel *self, FlKeyEventType type, int64_t scan_code, int64_t key_code, int64_t modifiers, int64_t unicode_scalar_values, int64_t specified_logical_key, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
Definition: fl_key_event_channel.cc:63