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

Advanced text input options #25

Open
wants to merge 17 commits into
base: master
Choose a base branch
from

Conversation

Swanseo0
Copy link
Contributor

@Swanseo0 Swanseo0 commented Feb 9, 2023

Support text input options

  • enableSuggestions
  • inputAction
  • autofillConfiguration

To support TextInput.requestAutofill, the following features have been implemented.

  • tizen autofill
  • nui, elementay type's popup for autofill (ecore wl2 type doesn't yet provide)

Related to issue #6

@Swanseo0 Swanseo0 force-pushed the advanced branch 2 times, most recently from cfd1f69 to b7946b2 Compare February 9, 2023 06:24
Signed-off-by: swan.seo <[email protected]>
@Swanseo0
Copy link
Contributor Author

Swanseo0 commented Feb 9, 2023

In order to compile NUI after this patch, need to use --system-cxx.

tools/generate_sysroot.py Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/nui_autofill_popup.cc Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/tizen_window_elementary.cc Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/tizen_window_elementary.cc Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/tizen_autofill.cc Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/tizen_autofill.cc Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/tizen_autofill.cc Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/tizen_autofill.h Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/tizen_window_elementary.cc Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/tizen_autofill.cc Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/tizen_autofill.cc Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/tizen_autofill.cc Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/tizen_window_elementary.cc Outdated Show resolved Hide resolved
Copy link

@bbrto21 bbrto21 left a comment

Choose a reason for hiding this comment

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

Could you kindly guide me on how to test this feature?
It would be even better if you could share the test app you used for development.

flutter/shell/platform/tizen/tizen_window_elementary.cc Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/tizen_view_elementary.h Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/channels/text_input_channel.h Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/nui_autofill_popup.cc Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/nui_autofill_popup.cc Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/nui_autofill_popup.cc Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/nui_autofill_popup.cc Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/nui_autofill_popup.cc Outdated Show resolved Hide resolved
Dali::Dimension::HEIGHT);
label.SetProperty(Dali::Toolkit::TextLabel::Property::TEXT_COLOR,
Dali::Color::WHITE_SMOKE);
label.SetProperty(Dali::Toolkit::TextLabel::Property::POINT_SIZE, 7.0f);
Copy link
Member

Choose a reason for hiding this comment

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

Q. Are there any default values for these properties? It'd be nice if we could avoid using magic numbers.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The default text color is black and the point size is about 15.
The background color of the pop-up window is dark blue, so I can't see the letters well, so I set it to white smoke.
The font size is set to an appropriate size because the default value is large, but we will modify it so that we do not use the magic number.
However, if we do not change the background color of popup, white smoke will be better than the basic color(black).

Copy link
Member

Choose a reason for hiding this comment

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

Does "white background" and "7.0f font size" look good for both tv and common (rpi) profiles?

+) NUI popup may differ from Dali popup. It might be better to set it equal to that value.
https://docs.tizen.org/application/dotnet/guides/user-interface/nui/nui-components/Popup/

flutter/shell/platform/tizen/nui_autofill_popup.h Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/nui_autofill_popup.h Outdated Show resolved Hide resolved

#include <dali-toolkit/devel-api/controls/popup/popup.h>

#include <functional>
Copy link
Member

Choose a reason for hiding this comment

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

Missing includes?

#include <dali/public-api/dali-core.h>

#include <string>

Please consult me or @bbrto21 on how to organize includes in the implementation file (nui_autofill_popup.cc) in a consistent way.

int ret = autofill_connect(
autofill_,
[](autofill_h autofill, autofill_connection_status_e status,
void* user_data) {},
Copy link
Member

Choose a reason for hiding this comment

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

Is this deliberately no-op? No need to check the current connection status?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

connected_ have been added to check connection status.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

You shouldn't need the extra SetConnected method. You can directly access private member fields via user_data.

Also you shouldn't assume the status is always AUTOFILL_CONNECTION_STATUS_CONNECTED.

Copy link
Member

Choose a reason for hiding this comment

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

The if (!connected_) check will fail if it comes immediately after Initailize() and autofill_connect is not a synchronous call.

Related to the comment #25 (comment).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

is_connected_ is usually better than just connected_.

Modified to use is_connected_.

You shouldn't need the extra SetConnected method. You can directly access private member fields via user_data.

Can I access the private region by casting user_data to TizenAutofill?

Also you shouldn't assume the status is always AUTOFILL_CONNECTION_STATUS_CONNECTED.

Changed to call SetConnected according to state.

The if (!connected_) check will fail if it comes immediately after Initailize() and autofill_connect is not a synchronous call.

Autofill will not work until connected. So we need to make sure it's connected.

Copy link
Member

@swift-kim swift-kim Feb 20, 2023

Choose a reason for hiding this comment

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

Can I access the private region by casting user_data to TizenAutofill?

In class methods, yes, you can. Also please do not rename user_data to data unless it is appropriate. We often use self as the name of the casted pointer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank you for advice.
The data was changed to user_data again and use self as the name of the casted pointer.

flutter/shell/platform/tizen/tizen_autofill.cc Outdated Show resolved Hide resolved
FT_LOG(Error) << "connect_autofill_daemon error";
}

autofill_fill_response_set_received_cb(
Copy link
Member

Choose a reason for hiding this comment

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

No need to check the return value in this case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed it to check the return value of this case.
Additionally, i have added a intialized_ variable to save whether the initialization process has all been successfully performed.

Copy link
Member

Choose a reason for hiding this comment

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

You should not immediately return after Initailize.

Also InitailizeInitialize.

Copy link
Contributor Author

@Swanseo0 Swanseo0 Feb 16, 2023

Choose a reason for hiding this comment

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

You should not immediately return after Initailize.

The reason for immediate return after Initialize is that connect is asynchronous.
If proceed with the autofill request immediately after initialize, it will fail because it is not connected.

Also InitailizeInitialize.

Modified.

Copy link
Member

Choose a reason for hiding this comment

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

That's the point of my comment above. The RequestAutofill method has indeterminate behavior depending on whether the TizenAutofill is initialized or not. If it's not initialized (although it's unlikely in normal situations), the method will simply call Initialize and exit. If it is already initialized, the rest of the method body will be executed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry for the late reply.
The reason you said "You should not immediate return after initiation" is because the connection is asynchronous, and we need to wait for the connection instead of return right away? Or should we not call the Initialize function at RequestAutofill function?

Copy link
Member

Choose a reason for hiding this comment

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

The reason you said "You should not immediate return after initiation" is because the connection is asynchronous, and we need to wait for the connection instead of return right away?

Kind of yes.

Or should we not call the Initialize function at RequestAutofill function?

I don't know. That's what you have to think in the design phase.

@Swanseo0 Swanseo0 force-pushed the advanced branch 2 times, most recently from 41b4629 to 695b8b6 Compare February 10, 2023 15:18
Dali::Dimension::HEIGHT);
label.SetProperty(Dali::Toolkit::TextLabel::Property::TEXT_COLOR,
Dali::Color::WHITE_SMOKE);
label.SetProperty(Dali::Toolkit::TextLabel::Property::POINT_SIZE, 7.0f);
Copy link
Member

Choose a reason for hiding this comment

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

Does "white background" and "7.0f font size" look good for both tv and common (rpi) profiles?

+) NUI popup may differ from Dali popup. It might be better to set it equal to that value.
https://docs.tizen.org/application/dotnet/guides/user-interface/nui/nui-components/Popup/

flutter/shell/platform/tizen/nui_autofill_popup.cc Outdated Show resolved Hide resolved
@Swanseo0
Copy link
Contributor Author

We can test using this autofill sample.
Yu can follow the steps below for the test method.

  • autofill_service app install
  • Settings - Language and input(System) - Autofill Service(INPUT ASSISTANCE) - autofill_service 선택
  • Running the app
  • text input field click

Four items with AUTOFILL_HINT_ID have been added from runner.cc in autofill_service.
Please refer to the creator of TizenAutofillService.

void TizenAutofill::RequestAutofill(std::vector<std::string> hints,
std::string id) {
if (!initailzed_) {
Initailize();
Copy link
Member

Choose a reason for hiding this comment

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

Initialize has already been requested in the constructor. Do you need to initialize again in case of initialization failure?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Initialize failed case is when autofill_create or autofill_connet failed.
In this case, TizenAutofill is not expected to work at all, so I think it needs to be reinitialized.

Copy link
Member

Choose a reason for hiding this comment

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

Isn't Initialize likely to fail again if it failed 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.

When it fails and tries again, it seems likely to fail again. So I changed it so that it doesn't try Initialize again.

void* data) {
int count = 0;
autofill_fill_response_get_group_count(fill_response, &count);
autofill_fill_response_foreach_group(
Copy link
Member

Choose a reason for hiding this comment

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

You could make each nested callback into a private static method (or a named lambda expression) to reduce the level of indentation.

very long nested anonymous functions can make code harder to understand.

Otherwise, you could wrap some of the C functions into individual methods (in the sense of OOP) but I'm not sure if it's appropriate. You may redesign this entire class if you feel it's appropriate.

Also is it okay to just ignore the return values (ret) of these functions?

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 could make each nested callback into a private static method (or a named lambda expression) to reduce the level of indentation.

Reduced the level of identation.

Otherwise, you could wrap some of the C functions into individual methods (in the sense of OOP) but I'm not sure if it's appropriate. You may redesign this entire class if you feel it's appropriate.

C functions with specific purposes were made into static functions.

Also is it okay to just ignore the return values (ret) of these functions?

Added conditions for functions that need to be checked for ret.
I think other functions doesn't need to be checked, but is there anything I missed?

Copy link
Member

Choose a reason for hiding this comment

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

Reduced the level of identation.

You may prefer static member methods over static functions, to allow accessing non-public members within callbacks.

I think other functions doesn't need to be checked,

Is it because you think you can simply "ignore" if they fail? Well, that's quite uncommon.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The function that does not check the return value based on the current code is if the return value is AUTOFILL_ERROR_NONE or AUTOFILL_ERROR_INVALID_PARAMETER.
In the case of AUTOFILL_ERROR_INVALID_PARAMETER, I thought it could be ignored because the appropriate function was called with the appropriate parameters. Do I need to check this case?

Copy link
Member

Choose a reason for hiding this comment

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

It depends. If you're sure the functions won't raise any errors or the errors can be ignored, error checking might not be necessary.

flutter/shell/platform/tizen/tizen_autofill.cc Outdated Show resolved Hide resolved
Comment on lines 103 to 104
void TizenAutofill::RequestAutofill(std::vector<std::string> hints,
std::string id) {
Copy link
Member

Choose a reason for hiding this comment

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

Always prefer const & types if the arguments are immutable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added. Thank you!

Copy link
Member

Choose a reason for hiding this comment

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

You don't have to apply this to pointer types like autofill_view_info_h.

Also you missed an & in line 136.

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 modified it. Thank you

flutter/shell/platform/tizen/tizen_autofill.cc Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/tizen_autofill.h Outdated Show resolved Hide resolved
@Swanseo0 Swanseo0 force-pushed the advanced branch 3 times, most recently from 12bb752 to 932e62c Compare February 16, 2023 05:12
Ecore_IMF_Input_Panel_Return_Key_Type return_key_type =
ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT;

// Not support : none, previous, continueAction, route, emergencycall, newline
Copy link
Member

Choose a reason for hiding this comment

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

In English, a colon should not be preceded by a space.

Suggested change
// Not support : none, previous, continueAction, route, emergencycall, newline
// Not supported: none, previous, continueAction, route, emergencyCall, newline

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Modified.

void TizenInputMethodContext::SetEnableSuggestions(bool enable) {
FT_ASSERT(imf_context_);
ecore_imf_context_prediction_allow_set(imf_context_,
enable ? EINA_TRUE : EINA_FALSE);
Copy link
Member

Choose a reason for hiding this comment

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

We may need to organize redundant function calls in SetContextOptions and SetInputPanelOptions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

SetContextOptions was removed. and redundant function calls in SetInputPanelOptions function were removed and renamed to SetInputPanelOption.

Comment on lines 85 to 93
void SetOnPopupAutofillContext(OnPopupAutofillContext callback) {
on_popup_autofill_context_ = callback;
}

void PopupAutofillItems() {
if (on_popup_autofill_context_) {
on_popup_autofill_context_();
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Does this code have anything to do with TizenInputMethodContext? I'm not sure why this callback is registered in this class. In fact the names are a bit confusing (OnPopup, SetOnPopup, SetOnPopupAutofillContext, PopupAutofillItems, ...) and I had a hard time understanding the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry for the confusion. This functions were deleted because it was confirmed that the operation was operating normally even without this callback registration part.

flutter/shell/platform/tizen/tizen_view_elementary.cc Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/tizen_view_elementary.cc Outdated Show resolved Hide resolved
flutter/shell/platform/tizen/tizen_autofill.cc Outdated Show resolved Hide resolved
}

void TizenAutofill::RegisterItem(const std::string& view_id,
const AutofillItem& item) {
Copy link
Member

Choose a reason for hiding this comment

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

RegisterItem is never used.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is not currently in use, but it is a function that was implemented because I thought it would be needed someday. Was it an unnecessary implementation?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

RegisterItem function was deleted.

Comment on lines 18 to 24
struct AutofillItem {
autofill_hint_e hint_;
bool sensitive_data_;
std::string label_;
std::string id_;
std::string value_;
};
Copy link
Member

Choose a reason for hiding this comment

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

Struct members should not be named like class members.

https://google.github.io/styleguide/cppguide.html#Variable_Names

Also, are the values other than value_ ever used?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Mainly used are hint, label, and value.
sensitive_data and id are variable that are not used in RequestAutoflll. I think it will only be used in RegisterItem.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Deleted obsolete hint_, sensitive_data_, and id_ while deleting the RegisterItem function.

}
}
// TODO(Swanseo0): Change ctxpopup's position to focused input field.
evas_object_move(ctxpopup_, 0, 0);
Copy link
Member

Choose a reason for hiding this comment

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

Isn't the popup supposed to appear just above the keyboard?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can set it to appear just above the input panel. Should I temporarily set it to appear just above the input panel?

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 changed it to be located above the input window as much as possible. view nui could be placed completely above, but in the case of window elementary and view elementary, it can be misplaced depending on the anchor point.

tools/generate_sysroot.py Outdated Show resolved Hide resolved
@bbrto21
Copy link

bbrto21 commented Feb 23, 2023

We can test using this autofill sample.

This link is broken.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants