Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose pointer type and buttons in embedder.h #9034

Merged
merged 2 commits into from May 22, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
66 changes: 44 additions & 22 deletions shell/platform/embedder/embedder.cc
Expand Up @@ -699,6 +699,19 @@ inline flutter::PointerData::Change ToPointerDataChange(
return flutter::PointerData::Change::kCancel;
}

// Returns the flutter::PointerData::DeviceKind for the given
// FlutterPointerDeviceKind.
inline flutter::PointerData::DeviceKind ToPointerDataKind(
FlutterPointerDeviceKind device_kind) {
switch (device_kind) {
case kFlutterPointerDeviceKindMouse:
return flutter::PointerData::DeviceKind::kMouse;
case kFlutterPointerDeviceKindTouch:
return flutter::PointerData::DeviceKind::kTouch;
}
return flutter::PointerData::DeviceKind::kMouse;
}

// Returns the flutter::PointerData::SignalKind for the given
// FlutterPointerSignaKind.
inline flutter::PointerData::SignalKind ToPointerDataSignalKind(
Expand All @@ -712,33 +725,24 @@ inline flutter::PointerData::SignalKind ToPointerDataSignalKind(
return flutter::PointerData::SignalKind::kNone;
}

// Returns the buttons for PointerData for the given buttons and change from a
// FlutterPointerEvent.
inline int64_t ToPointerDataButtons(int64_t buttons,
flutter::PointerData::Change change) {
// Returns the buttons to synthesize for a PointerData from a
// FlutterPointerEvent with no type or buttons set.
inline int64_t PointerDataButtonsForLegacyEvent(
flutter::PointerData::Change change) {
switch (change) {
case flutter::PointerData::Change::kDown:
case flutter::PointerData::Change::kMove:
// These kinds of change must have a non-zero `buttons`, otherwise gesture
// recognizers will ignore these events. To avoid breaking legacy
// embedders, it synthesizes a primary button when seeing `button = 0` and
// logs a warning to inform them to update.
if (buttons == 0) {
// TODO: Log a warning to inform the embedder to send the
// correct buttons. See
// https://github.com/flutter/flutter/issues/32052#issuecomment-489278965
return flutter::kPointerButtonMousePrimary;
}
return buttons;

// recognizers will ignore these events.
return flutter::kPointerButtonMousePrimary;
case flutter::PointerData::Change::kCancel:
case flutter::PointerData::Change::kAdd:
case flutter::PointerData::Change::kRemove:
case flutter::PointerData::Change::kHover:
case flutter::PointerData::Change::kUp:
return buttons;
return 0;
}
return buttons;
return 0;
}

FlutterEngineResult FlutterEngineSendPointerEvent(
Expand All @@ -759,18 +763,36 @@ FlutterEngineResult FlutterEngineSendPointerEvent(
pointer_data.time_stamp = SAFE_ACCESS(current, timestamp, 0);
pointer_data.change = ToPointerDataChange(
SAFE_ACCESS(current, phase, FlutterPointerPhase::kCancel));
pointer_data.kind = flutter::PointerData::DeviceKind::kMouse;
pointer_data.physical_x = SAFE_ACCESS(current, x, 0.0);
pointer_data.physical_y = SAFE_ACCESS(current, y, 0.0);
pointer_data.device = SAFE_ACCESS(current, device, 0);
pointer_data.signal_kind = ToPointerDataSignalKind(
SAFE_ACCESS(current, signal_kind, kFlutterPointerSignalKindNone));
pointer_data.scroll_delta_x = SAFE_ACCESS(current, scroll_delta_x, 0.0);
pointer_data.scroll_delta_y = SAFE_ACCESS(current, scroll_delta_y, 0.0);
// TODO: Change 0 to a SAFE_ACCESS to current.buttons once this
// field is added. See
// https://github.com/flutter/flutter/issues/32052#issuecomment-489278965
pointer_data.buttons = ToPointerDataButtons(0, pointer_data.change);
FlutterPointerDeviceKind device_kind = SAFE_ACCESS(current, device_kind, 0);
// For backwards compatibilty with embedders written before the device kind
// and buttons were exposed, if the device kind is not set treat it as a
// mouse, with a synthesized primary button state based on the phase.
if (device_kind == 0) {
pointer_data.kind = flutter::PointerData::DeviceKind::kMouse;
pointer_data.buttons =
PointerDataButtonsForLegacyEvent(pointer_data.change);

} else {
pointer_data.kind = ToPointerDataKind(device_kind);
if (pointer_data.kind == flutter::PointerData::DeviceKind::kTouch) {
// For touch events, set the button internally rather than requiring
// it at the API level, since it's a confusing construction to expose.
if (pointer_data.change == flutter::PointerData::Change::kDown ||
pointer_data.change == flutter::PointerData::Change::kMove) {
pointer_data.buttons = flutter::kPointerButtonTouchContact;
}
} else {
// Buttons use the same mask values, so pass them through directly.
pointer_data.buttons = SAFE_ACCESS(current, buttons, 0);
}
}
packet->SetPointerData(i, pointer_data);
current = reinterpret_cast<const FlutterPointerEvent*>(
reinterpret_cast<const uint8_t*>(current) + current->struct_size);
Expand Down
48 changes: 48 additions & 0 deletions shell/platform/embedder/embedder.h
Expand Up @@ -280,14 +280,54 @@ typedef struct {
// The phase of the pointer event.
typedef enum {
kCancel,
// The pointer, which must have been down (see kDown), is now up.
//
// For touch, this means that the pointer is no longer in contact with the
// screen. For a mouse, it means the last button was released. Note that if
// any other buttons are still pressed when one button is released, that
// should be sent as a kMove rather than a kUp.
kUp,
// The pointer, which must have been been up, is now up.
stuartmorgan marked this conversation as resolved.
Show resolved Hide resolved
//
// For touch, this means that the pointer has come into contact with the
// screen. For a mouse, it means a button is now pressed. Note that if any
// other buttons are already pressed when a new button is pressed, that should
// be sent as a kMove rather than a kDown.
kDown,
// The pointer moved while down.
stuartmorgan marked this conversation as resolved.
Show resolved Hide resolved
kMove,
// The pointer is now sending input to Flutter. For instance, a mouse has
// entered the area where the Flutter content is displayed.
//
// A pointer should always be added before sending any other events.
kAdd,
// The pointer is no longer sending input to Flutter. For instance, a mouse
// has left the area where the Flutter content is displayed.
//
// A removed pointer should no longer send events until sending a new kAdd.
kRemove,
// The pointer moved while up.
kHover,
} FlutterPointerPhase;

// The device type that created a pointer event.
typedef enum {
kFlutterPointerDeviceKindMouse = 1,
kFlutterPointerDeviceKindTouch,
} FlutterPointerDeviceKind;

// Flags for the |buttons| field of |FlutterPointerEvent| when |device_kind|
// is |kFlutterPointerDeviceKindMouse|.
typedef enum {
kFlutterPointerButtonMousePrimary = 1 << 0,
kFlutterPointerButtonMouseSecondary = 1 << 1,
kFlutterPointerButtonMouseMiddle = 1 << 2,
kFlutterPointerButtonMouseBack = 1 << 3,
kFlutterPointerButtonMouseForward = 1 << 4,
// If a mouse has more than five buttons, send higher bit shifted values
// corresponding to the button number: 1 << 5 for the 6th, etc.
} FlutterPointerMouseButtons;

// The type of a pointer signal.
typedef enum {
kFlutterPointerSignalKindNone,
Expand All @@ -307,6 +347,14 @@ typedef struct {
FlutterPointerSignalKind signal_kind;
double scroll_delta_x;
double scroll_delta_y;
// The type of the device generating this event.
// Backwards compatibility note: If this is not set, the device will be
// treated as a mouse, with the primary button set for |kDown| and |kMove|.
// If set explicitly to |kFlutterPointerDeviceKindMouse|, you must set the
// correct buttons.
FlutterPointerDeviceKind device_kind;
// The buttons currently pressed, if any.
int64_t buttons;
} FlutterPointerEvent;

struct _FlutterPlatformMessageResponseHandle;
Expand Down