-
Notifications
You must be signed in to change notification settings - Fork 6k
Synthesize buttons for embedders #8873
Conversation
lib/ui/window/pointer_data.h
Outdated
| namespace flutter { | ||
|
|
||
| // Must match the button constants in events.dart. | ||
| const int64_t kPrimaryButton = 0x01; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this a free constant rather than an enum class like the others below? In my experience it's standard in C++ to use enums for flags.
It would also be good to just go ahead and add the other mouse button constants from events.dart at the same time so the list here matches, rather than being a subset.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if it's ok to use enum as bitfield.
The reason I chose not to add other button constants is that only kPrimaryButton is used in code, since only it is used synthesis. When other buttons are involved they are directly copied from FlutterPointerEvent.buttons to PointerData.buttons.
I'll fix them if they're not a concern.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if it's ok to use enum as bitfield.
See https://github.com/flutter/engine/blob/master/lib/ui/semantics/semantics_node.h#L21 and later in the same file for example.
only kPrimaryButton is used in code
We'll need all of them when it becomes part of the embedding API, since we'll need to translate each public constant to the corresponding internal constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: Stuart and I discussed privately about whether to use enum types or int64_t.
Pros of enum class:
- Type safe, such as preventing
kMousePrimaryButton | kStylusSecondaryButton. - Grouping comes more natively than explicit namespace.
Cons:
- Require to define
operator&andoperator|. It is magnified if we're to define all 4 sets of constants. - Combined values no longer fall into enum options, which might be confusing.
The cost to implement all operators is considerable, while the benefit seems insignificant because it's hard to predict the usage of the constants without knowing how they'll be used in engine. Therefore I might go forward with int64_t constants.
shell/platform/embedder/embedder.cc
Outdated
| inline int64_t ToPointerDataButtons( | ||
| int64_t buttons, | ||
| flutter::PointerData::Change change) { | ||
| // `buttons` should be non-zero when and only when the pointer is down. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the "and only when" actually true? For instance, is sending a cancel with a button set actually an error? I can think of cases where I would expect that to be the event created by the platform on desktop, unless it were explicitly worked around at the platform level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cancel is kind of special being the state of "termination". I can add it to the list (down, move or cancel), but other events should really not involve buttons.
For other events, there is a set of restrictions we hope the list of PointerData should obey, and the engine should regularize them before sending to framework. It is currently handled by PointerEventConverter . There was a plan to move them to the engine (leaving framework with only 1-to-1 converting) but was cancelled. I'm not sure we're still going this way though.
|
@stuartmorgan I fixed all issues you raised. Notes:
|
lib/ui/window/pointer_data.h
Outdated
| // Must match the button constants in events.dart. | ||
| namespace PointerButton { | ||
| const int64_t kPrimary = 1 << 0; | ||
| const int64_t kSecondary = 1 << 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are the raw values in event.dart actually used? I wouldn't expose them unless there's a need; it seemed like they were more for defining the device-specific constants.
Having them here encourages confusing usage (e.g., your use of PointerButton::kPrimary rather than PointerButton::kMousePrimary in this PR even though it's a mouse), and especially so given that they don't line up with the stylus names.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. In fact, the general series of buttons are used more often, because most widgets are defined for cross-device behaviors, and by grouping the same "cross-device behavior" into the same value, more often than not widgets do not need to check the device kind. For example, primary mouse button, stylus contact, and touch contact are supposed to behave the same for most cases, so they share the same value 0x01, while secondary mouse button and primary stylus button share the same value 0x02. In this way, a button click will respond to kPrimaryButton, instead of kPrimaryMouseButton or kStylusContact, while a context menu will respond to kSecondaryButton.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, makes sense.
I still think we shouldn't expose them in the C++ code absent a reason though; we're creating device-specific data structs, rather than consuming data in a device-agnostic way. For creating them, using the device-specific values makes much more sense to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. However I still need a value when synthesizing the primary button. Currently I'm using kPrimaryMouseButton but it's a little awkward. I wonder if you think it's acceptable. https://github.com/flutter/engine/pull/8873/files#diff-3784eecbfe20523d62f0a4c19cd363ebR730
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is that awkward? The device type is hard-coded to mouse, so the primary mouse button seems like the right constant to me.
|
@stuartmorgan I fixed the requested changes. However,
|
stuartmorgan-g
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some nits, but LGTM otherwise.
I'm using the "no default" strategy you suggested in ToPointerDataButtons. I'm sure I listed all 7 options but still got warning C4715: 'ToPointerDataButtons': not all control paths return a value.
You need a final return outside the switch; there's no actual guarantee that the value you're switching on is a valid enum value (consider someone passing (flutter::PointerData::Change)9999, for instance), so without a default reaching the end of the switch without returning is a possible code path.
lib/ui/window/pointer_data.h
Outdated
| // Must match the button constants in events.dart. | ||
| namespace PointerButton { | ||
| const int64_t kPrimary = 1 << 0; | ||
| const int64_t kSecondary = 1 << 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is that awkward? The device type is hard-coded to mouse, so the primary mouse button seems like the right constant to me.
flutter/engine@3822aec...6e3c043 git log 3822aec..6e3c043 --no-merges --oneline 6e3c043 Synthesize buttons for embedders (flutter/engine#8873) The AutoRoll server is located here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+/master/autoroll/README.md If the roll is causing failures, please contact the current sheriff (chinmaygarde@google.com), and stop the roller if necessary.
* Synthesize a buttons = kPrimaryButton for events of down and move * Add PointerEventButtons
Description
This PR is a placeholder for button support for embedders. Currently the embedder API does not have button information at all, which leads to
PointerData.buttons = 0and blocks the corresponding framework change. This PR synthesizes abuttons = kPrimaryButtonfor events of down and move.In the future when we have added
FlutterPointerEvent::buttons(without breaking existing binaries), make sure to fix these 2 TODOs.Related issues