-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Ensure "text boxes" preserve cursor location #15099
Conversation
[Theory] | ||
[InlineData(2)] | ||
public async Task CursorPositionInitializesCorrectlyWithUpdateCursorPositionLast(int initialPosition) | ||
{ | ||
var entry = new TView | ||
{ | ||
Text = "This is TEXT!", | ||
CursorPosition = initialPosition | ||
}; | ||
|
||
var value = await GetValueAsync<int, THandler>(entry, handler => | ||
{ | ||
handler.UpdateValue(nameof(ITextInput.CursorPosition)); | ||
return GetPlatformCursorPosition(handler); | ||
}); | ||
|
||
Assert.Equal(initialPosition, value); | ||
} | ||
|
||
[Theory] | ||
[InlineData(2)] | ||
public async Task CursorPositionInitializesCorrectlyWithUpdateTextLast(int initialPosition) | ||
{ | ||
var entry = new TView | ||
{ | ||
Text = "This is TEXT!", | ||
CursorPosition = initialPosition | ||
}; | ||
|
||
var value = await GetValueAsync<int, THandler>(entry, handler => | ||
{ | ||
handler.UpdateValue(nameof(ITextInput.Text)); | ||
return GetPlatformCursorPosition(handler); | ||
}); | ||
|
||
Assert.Equal(initialPosition, value); | ||
} |
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.
These 2 tests cause failures depending on the order of properties in the mapper table. Currently if Text is first, then it is passing, but if it happens to have Text after the CursorPosition (which will be the case in my other PRs because I am fixing the mappers) then it fails.
|
||
platformControl.Select(cursorPosition, 0); | ||
platformControl.Select(cursorPosition, 0); |
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.
This is the change for Windows.
textView.Text = newText; | ||
|
||
textView.SetTextRange(cursorPosition, 0); | ||
textView.SetTextRange(cursorPosition, 0); |
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.
This is the change for iOS.
@mattleibow can you see if it helps with this issue. #11512 ? |
@rmarinho this does not seem to make any difference. I think your conclusions on the other issue are correct, so maybe we need to do less of something so the code that runs in the events actually stick. |
src/Controls/src/Core/Platform/iOS/Extensions/TextExtensions.cs
Outdated
Show resolved
Hide resolved
/rebase |
d797992
to
4192bd5
Compare
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.
UPDATE: After some offline discussion, we learned this PR isn't exactly meant to modify the behavior I annotated below, although it is still useful context to have.
I tested some of the different scenarios on Windows and Android via keyboard tab / shift+tab navigation. Here's what I'm seeing on this PR branch at this point in time:
Scenario | Behavior |
---|---|
1. Entry/Editor blank with text updated after | Cursor position remains wherever it was left last. The platform "remembers" wherever it is, even if the cursor is in the middle of a word. |
2a. Entry/Editor with pre-filled text | Cursor position remains at the beginning of the input field. |
2b. 2a with text updated after | Same as 1 |
3a. Entry/Editor with pre-filled text via binding | Same as 2a |
3b. 3a with text updated after | Same as 1 |
Interestingly, the behavior on Windows and Android was exactly the same for all of the scenarios. Shift+Tab didn't appear to work on Android emulator for me though (unclear why, as I do think it was working before and/or on device, but anyhow, that's a separate issue).
This behavior is also exactly the same on main, so it doesn't seem that keyboard focus was affected by the work you've done so far on this PR.
Based on what I'm seeing here, my thinking is that we should update so that for scenarios 2a and 3a, cursor position is at the END of the text in input field.
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.
LGTM on Windows!
need to test on iOS still, and left a couple comments
src/Controls/tests/DeviceTests/Elements/TextInput/TextInputTests.cs
Outdated
Show resolved
Hide resolved
src/Controls/tests/DeviceTests/Elements/TextInput/TextInputTests.cs
Outdated
Show resolved
Hide resolved
src/Controls/tests/DeviceTests/Elements/TextInput/TextInputTests.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: Rachel Kang <rachelkang@microsoft.com>
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.
Looks good, couple of minor change requests.
src/Controls/src/Core/Platform/iOS/Extensions/TextExtensions.cs
Outdated
Show resolved
Hide resolved
src/Controls/src/Core/Platform/iOS/Extensions/TextExtensions.cs
Outdated
Show resolved
Hide resolved
Updating table to record my findings on macios:
|
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.
Tested on mac, iOS as well and LGTM!
(There are some behavior quirks, but no new quirks. We should definitely investigate more in the future, but that's outside the scope of what this PR aims to do).
Left a nitpick comment on a var name, but approving as all else LGTM!
textField.Text = newText; | ||
{ | ||
// Re-calculate the cursor offset position if the text was modified by a Converter. | ||
// but if the text is being set by code, let's just move the cursor to the end. |
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.
We should reevaluate this behavior in the future as it's inconsistent with Windows and Android. And we should check to see if it's consistent with iOS platform behavior, as it seems like it might not be. Could you log an issue to capture this, or update existing related issue?
where TType : IView, new() | ||
where THandler : class, IPlatformViewHandler, IElementHandler, new() | ||
{ | ||
Func<THandler, Task> boop = (handler) => |
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.
nitpick: can we rename boop to be more descriptive :p
Description of Change
This PR adds some tests to make sure all the platforms are consistent with regards to how the cursor position changes (or not) when text is changed.
It is just 2 small changes:
There is a code change for iOS and Windows to only update selection start/length if the text has changed: