Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Conversation

@franciscojma86
Copy link
Contributor

@franciscojma86 franciscojma86 commented Jun 19, 2019

Sends GLFW keyboard data as Linux key data, as opposed to Android. Includes the unmodified unicode character generated by the key.

Depends on flutter/flutter#34752

Fixes flutter/flutter#33395

@stuartmorgan-g
Copy link
Contributor

stuartmorgan-g commented Jun 20, 2019

Please be sure to update the FDE testbed app's raw key event test page to expect Linux rather than Android at the same time as landing this.

@pchampio
Copy link
Contributor

GLFW has a key event action named GLFW_REPEAT for repeated keys that are held down.

We had a discussion about it in go-flutter-desktop/go-flutter#136 (comment)
TLDR; we choose to interpret the GLFW_REPEAT action as GLFW_DOWN action.

What is your take on this?

@stuartmorgan-g
Copy link
Contributor

What is your take on this?

I don't see any reason for desktop to deviate from the existing Android behavior at this point. If someone files an issue with a use case for adding Repeat as a separate event type, that can be revisited across all platforms.

@franciscojma86 Feel free to add repeat handling to this PR since it's a minor change.

@cbracken
Copy link
Member

cbracken commented Aug 5, 2019

@franciscojma86 what's the status of this PR?

@franciscojma86
Copy link
Contributor Author

Will be ready once the flutter/flutter#34752 is landed, which I'll finish right after my rotation.

Copy link
Contributor

@stuartmorgan-g stuartmorgan-g left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (although per above I'd suggest adding repeat-as-down to this since you're changing this code anyway and that's a simple change).

@franciscojma86
Copy link
Contributor Author

@stuartmorgan sorry for the re-review. Added a function to convert the utf8 encoded code point to GLFW to an int, which is what the framework accepts.

masks[2] = 0x1F;
masks[1] = 0xFF;

// The number of bits to shift a byte depending on it's position.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/it's/its/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

int shift = length;

// All possible masks for a 4 byte utf8 code point.
std::map<int, int> masks;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use a vector for these rather than a map, since you are always only using the first 4 positions? (You'd want to zero-index rather than one-index, obviously)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


// Converts a utf8 const char* to a 32 bit int. The Flutter framework accepts
// only one 32 bit int, therefore, only up to 4 bytes are accepted. If it's
// larger than 4 bytes, only the first 4 will be used.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if a multi-byte character straddles position 4? I didn't see any obvious handling of that; if I missed it maybe it just needs clear commenting at that point.

int current_byte = utf8[current_byte_index];
int mask = current_byte_index == 0 ? masks[length] : complement_mask;
current_byte_index++;
result += (current_byte & mask) << bits[shift--];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is there a mask for each individual byte? I think I'm not understanding the role the mask plays in this algorithm, so it would be helpful if you could expand on the algorithm in comments in the implementation. It's non-obvious to me why there's a mask at all.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the documentation with a run through. LMK if it answers your question.

@franciscojma86 franciscojma86 force-pushed the keydata branch 2 times, most recently from 6aa2051 to 7670985 Compare August 12, 2019 21:43
Copy link
Contributor

@stuartmorgan-g stuartmorgan-g left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes a lot more sense now; just small comments.


namespace flutter {

// Information about the UTF-8 encoded code point.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrap this and the helper function in an anonymous namespace so they have internal linkage.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


// Queries GLFW for the printable key name given a [key] and [scan_code] and
// converts it to UTF-32. The Flutter framework accepts only one 32 bit
// int, therefore, if the [code_point]'s length is > 4 (e.g. has two code
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// The Flutter framework accepts only one 32 bit
// int, therefore, if the [code_point]'s length is > 4 (e.g. has two code
// points)

This comment is misleading. First, it always sends only the first point, regardless of length (consider "ab"). Second, the reason isn't that it accepts "one 32-bit int" ("ab"'s UTF-8 encoding fits in a 32-bit int), but that the Flutter framework is expecting exactly one code point.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

// int, therefore, if the [code_point]'s length is > 4 (e.g. has two code
// points), only the first will be used. This unlikely but there is no guarantee
// that it won't happen.
bool GetGLFWCodePoint(int key, int scan_code, uint32_t& code_point) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's call this GetUTF32CodePointFromGLFWKey so it's more obvious what exactly it's doing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

// int, therefore, if the [code_point]'s length is > 4 (e.g. has two code
// points), only the first will be used. This unlikely but there is no guarantee
// that it won't happen.
bool GetGLFWCodePoint(int key, int scan_code, uint32_t& code_point) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uint32_t*. The C++ style guide forbids using references for out-params.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

int shift = length - 1;

// The number of bits to shift a byte depending on its position.
std::vector<int> bits = {0, 6, 12, 18};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this a lookup table rather than just a multiplication by 6?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

// The number of bits to shift a byte depending on its position.
std::vector<int> bits = {0, 6, 12, 18};

int complement_mask = 0x3F;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const int

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

return false;
}
// The first byte determines the length of the whole code point.
auto byte_info = GetUTF8CodePointInfo(utf8[0]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const auto

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

}
// The first byte determines the length of the whole code point.
auto byte_info = GetUTF8CodePointInfo(utf8[0]);
size_t length = byte_info.length;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider just using byte_info.length in the two places it's used, rather than adding another variable that the reader needs to keep track of.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

@stuartmorgan-g stuartmorgan-g left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM


// Queries GLFW for the printable key name given a [key] and [scan_code] and
// converts it to UTF-32. The Flutter framework accepts only one code point,
// therefore, only the first code point will be used. This unlikely but there is
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/This is unlikely/There is unlikely to be more than one/ (the "This" currently doesn't refer to anything that was actually said before.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@franciscojma86 franciscojma86 merged commit a79a31a into flutter:master Aug 20, 2019
@franciscojma86 franciscojma86 deleted the keydata branch August 20, 2019 22:55
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Aug 21, 2019
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Aug 21, 2019
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Aug 21, 2019
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Aug 21, 2019
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Aug 21, 2019
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Aug 21, 2019
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Aug 21, 2019
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Aug 21, 2019
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Aug 21, 2019
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Aug 21, 2019
engine-flutter-autoroll added a commit to flutter/flutter that referenced this pull request Aug 21, 2019
[email protected]:flutter/engine.git/compare/c43739ba53ce...51bdf83

git log c43739b..51bdf83 --no-merges --oneline
2019-08-21 [email protected] Migrate Embedder API documentation to Doxygen format. (flutter/engine#11255)
2019-08-21 [email protected] Do not add null task observers (flutter/engine#11315)
2019-08-21 [email protected] When using a custom compositor, ensure the root canvas is flushed. (flutter/engine#11310)
2019-08-20 [email protected] [glfw] Send the glfw key data to the framework. (flutter/engine#9386)

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 ([email protected]), and stop
the roller if necessary.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Send more complete key event data from GLFW shell

6 participants