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

Conversation

@LongCatIsLooong
Copy link
Contributor

Fixes flutter/flutter#132548

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide and the C++, Objective-C, Java style guides.
  • I listed at least one issue that this PR fixes in the description above.
  • I added new tests to check the change I am making or feature I am adding, or the PR is test-exempt. See testing the engine for instructions on writing and running engine tests.
  • I updated/added relevant documentation (doc comments with ///).
  • I signed the CLA.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@LongCatIsLooong LongCatIsLooong force-pushed the fix-first-IME-candidate-invisible branch from 35ce1ca to 8ec60f5 Compare September 28, 2023 17:54
@LongCatIsLooong LongCatIsLooong force-pushed the fix-first-IME-candidate-invisible branch from 8ec60f5 to 05f8e8a Compare September 28, 2023 18:09
@LongCatIsLooong LongCatIsLooong force-pushed the fix-first-IME-candidate-invisible branch from ed47e43 to 900069b Compare September 28, 2023 18:54
// the screen.
//
// These are not documened methods. On iOS 17, the insertion point color is also
// used to paint the highlighted background of the selected IME candidate:
Copy link
Contributor

Choose a reason for hiding this comment

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

what else do we use this function for?

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 paragraph above says that it's used to make sure the system caret / selection handles aren't visible.

// because Scribble interactions require the view to have it's actual frame on
// the screen.
//
// These are not documened methods. On iOS 17, the insertion point color is also
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: documented

// used to paint the highlighted background of the selected IME candidate:
// https://github.com/flutter/flutter/issues/132548
// So the respondsToSelector method is overridden to return NO for this method
// on iOS 17+.
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm confused as to why we are both implementing it but claiming not to. Are we relying on an implementation detail of some system code calling this unconditionally and other code checking whether its implemented first, and relying on that distinction to make things work? If so, that seems incredibly fragile, and the sort of thing that's likely to cause another round of fire drills in a subsequent iOS version.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

UIKit falls back to UIColor.insertionPointColor if the receiver doesn't respond to insertionPointColor. That color is unfortunately private.

some system code calling this unconditionally

The method is actually private (but it's in the codebase for a while and no complains from app store) and it's not part of any protocols, so UIKit has to check respondsToSelector first.

Copy link
Contributor

Choose a reason for hiding this comment

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

The method is actually private (but it's in the codebase for a while and no complains from app store) and it's not part of any protocols, so UIKit has to check respondsToSelector first.

Then how does this change not break the "Prevent UIKit from showing selection handles or highlights" use case that the implementation is documented as being for?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

On iOS 17 there's new API for adding system UI for text selection/cursor/highlights: https://developer.apple.com/documentation/uikit/uitextselectiondisplayinteraction?language=objc . Without adding that interaction to the input view (and we don't add UIITextInteraction to the view unless the framework is currently sending editing state updates, as a hack to fix a different bug), UIKit doesn't seem to add selection handles or highlights automatically on iOS 17.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see; please update the comments on this method then to explain this, and that it's bypassed on iOS 17+ by a respondsToSelector: check.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi @fbcouch do you remember when is insertionPointColor called during scribble? I'd like to verify if this is still needed on iOS17.

Copy link
Contributor

Choose a reason for hiding this comment

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

If I recall correctly, it was basically during any text interaction – since we changed to show the frame in it's proper place on the screen, iPadOS was able to draw it's own selection handles, etc

return NO;
}
}
return [FlutterTextInputView instancesRespondToSelector:selector];
Copy link
Contributor

Choose a reason for hiding this comment

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

Why isn't this just calling super?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

According to the documentation [super respondsToSelector:] is equivalent to [self respondsToSelector:] https://developer.apple.com/documentation/objectivec/1418956-nsobject/1418583-respondstoselector#discussion, so i thought there was going to be an infinite loop. Let me try it out.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well that worked. Changed to calling super.

Copy link
Contributor

Choose a reason for hiding this comment

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

The context there is important:

You cannot test whether an object inherits a method from its superclass by sending respondsToSelector: to the object using the super keyword. This method will still be testing the object as a whole, not just the superclass’s implementation. Therefore, sending respondsToSelector: to super is equivalent to sending it to self.

For the purposes of testing where a method's implementation lives, it's equivalent. That doesn't mean it doesn't follow actual method dispatch rules.

@LongCatIsLooong LongCatIsLooong force-pushed the fix-first-IME-candidate-invisible branch from 900069b to 2f0c506 Compare September 28, 2023 20:01
if (@available(iOS 17.0, *)) {
// See the comment on this method.
if (selector == @selector(insertionPointColor)) {
return NO;
Copy link
Contributor

Choose a reason for hiding this comment

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

We need to be careful if this breaks other functionalities that uses insertionPointColor.

@LongCatIsLooong
Copy link
Contributor Author

I did some basic IME input testing and didn't notice any UI weirdness.

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 as long as we're reasonably confident that we've manually tested all of the cases that the code being bypassed was originally intended to fix.

@LongCatIsLooong LongCatIsLooong added the autosubmit Merge PR when tree becomes green via auto submit App label Oct 17, 2023
@auto-submit auto-submit bot merged commit 289f29b into flutter:main Oct 17, 2023
@LongCatIsLooong LongCatIsLooong deleted the fix-first-IME-candidate-invisible branch October 17, 2023 19:21
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Oct 17, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

autosubmit Merge PR when tree becomes green via auto submit App platform-ios

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[iOS][iOS 17] The first candidate in IME is not displayed on iPad + iOS 17 + hardware keyboard

4 participants