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

[embedder][glfw] Add support for locales to glfw shell #22657

Merged
merged 10 commits into from
Nov 24, 2020

Conversation

rokob
Copy link
Contributor

@rokob rokob commented Nov 20, 2020

The other linux shell (and all the other embedding) have support for
getting the locales from the system and sending them over the
flutter/localization channel. The glfw shell does not have that which is
causing us to crash on an assert now that Locale is no longer nullable
in Platform.

This adds a similar approach to what is going on over in the other linux
shell to this one.

The GLFW shell also has no tests. I added tests for this change which required adding a new target and hooking that up where the other linux tests go. I took a bit of a guess at some of that because I'm not entirely sure what the build_glfw_shell configuration is used for. GLFW seems to be difficult to test so I added a private header to expose the functions for working with locales and tested those. Some of the code isn't tested because of environment variable things or calling into the engine, but those functions are small wrappers around the logic which is tested.

Related

The other linux shell (and all the other embedding) have support for
getting the locales from the system and sending them over the
flutter/localization channel. The glfw shell does not have that which is
causing us to crash on an assert now that Locale is no longer nullable
in Platform.

This adds a similar approach to what is going on over in the other linux
shell to this one.

I haven't added tests or anything yet, just wanted to get this out there
to see if this is reasonable.
@flutter-dashboard
Copy link

It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat.

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

Copy link
Contributor

@stuartmorgan stuartmorgan left a comment

Choose a reason for hiding this comment

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

Mostly looks good; some small comments. Thanks for setting up the unit tests target!

shell/platform/glfw/BUILD.gn Outdated Show resolved Hide resolved
shell/platform/glfw/BUILD.gn Outdated Show resolved Hide resolved
shell/platform/glfw/flutter_glfw.cc Outdated Show resolved Hide resolved
shell/platform/glfw/flutter_glfw.cc Outdated Show resolved Hide resolved
shell/platform/glfw/flutter_glfw.cc Outdated Show resolved Hide resolved
shell/platform/glfw/flutter_glfw.cc Outdated Show resolved Hide resolved
const char* locale_string,
std::list<std::string>& locale_storage) {
if (!locale_string || locale_string[0] == '\0') {
locale_string = "C";
Copy link
Contributor

Choose a reason for hiding this comment

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

Why "C"?

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 found somewhere in some posix docs about locales that "ISO C says that all programs start by default in the standard ‘C’ locale." And looking around at other things that parse these strings, they use "C" as the fallback.

shell/platform/glfw/flutter_glfw.cc Outdated Show resolved Hide resolved
// Passes locale information to the Flutter engine.
static void SetUpLocales(FlutterDesktopEngineState* state) {
// Helper to extend lifetime of the strings passed to Flutter.
std::list<std::string> locale_storage;
Copy link
Contributor

Choose a reason for hiding this comment

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

This construction seems more confusing than just inlining the conversion to C strings (as we do on other platforms IIRC).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You need something to extend the lifetimes based on the calling convention, and this is basically how the other linux shell does it. I didn't think to look at the windows code, that is a much better way to handle it, I will mirror that over here.

std::vector<std::unique_ptr<FlutterLocale>> GetLocales(
const char* locale_string,
std::list<std::string>& locale_storage);

Copy link
Contributor

Choose a reason for hiding this comment

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

The reason there are multiple exposed helpers on Windows is that we can't easily mock out what the OS returns; that's not the case here, since you can easily set environment variables in tests, so I would expect there to only be one visible function for getting locales even if it has helper functions internally.

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 was trying to not set environment variables in tests and instead make more pure functions for testability, but that is more noise than its worth here so I will collapse things.

Copy link
Contributor

@stuartmorgan stuartmorgan left a comment

Choose a reason for hiding this comment

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

Looks great, thanks!

if (lang_was_set) {
setenv("LANG", old_lang.c_str(), 1);
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Optional nit: it seems like you could simplify this code substantially by using a map of values to set, and a map of previous values, so that you wouldn't need four copies of all of the logic and could instead just iterate through maps.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea, done.

@rokob rokob merged commit 176a2c0 into flutter:master Nov 24, 2020
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 25, 2020
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 25, 2020
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 25, 2020
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Nov 25, 2020
chaselatta pushed a commit to chaselatta/engine that referenced this pull request Nov 30, 2020
The other linux shell (and all the other embedding) have support for
getting the locales from the system and sending them over the
flutter/localization channel. The glfw shell does not have that which is
causing a crash on an assert now that Locale is no longer nullable
in Platform.

This adds a similar approach to what is going on over in the other linux
shell.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants