-
Notifications
You must be signed in to change notification settings - Fork 6k
[iOS][Keyboard] Wait vsync on UI thread and update viewport inset to avoid jitter. #42312
Conversation
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 (don't just cc him here, he won't see it! He's on Discord!). If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix? Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
Can you cross reference issues here and perhaps describe how to test this? |
Is there an issue describing what you're trying to fix here? Can you add a test that fails without this change? |
Sorry my bad. Here is the issue this PR try to fix. And The technical problem is: if setViewportMetrics called before framework's vsync process callback (rebuild & layout & paint), will cause jitter keyboard animation.So this PR is to keep the time when updateViewportMetrics call to framework side legal. A previous naive solution is #41201. And I m still figuring how to write the test for this PR... But seems very triky to write test...... |
I made the So If use old way, current code in auto callback = [keyboardAnimationCallback](
std::unique_ptr<flutter::FrameTimingsRecorder> recorder) {
fml::TimeDelta frameInterval = recorder->GetVsyncTargetTime() - recorder->GetVsyncStartTime();
fml::TimePoint keyboardAnimationTargetTime = recorder->GetVsyncTargetTime() + frameInterval;
keyboardAnimationCallback(keyboardAnimationTargetTime);
};
_keyboardAnimationVSyncClient =
[[VSyncClient alloc] initWithTaskRunner:shell.GetTaskRunners().GetPlatformTaskRunner()
callback:callback]; And new test And if use the code in the patch, the new test will pass. |
How to test this patch: Here is video zip can show the effect better Demo codevoid main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: DemoScreen(),
);
}
}
class DemoScreen extends StatefulWidget {
const DemoScreen({Key? key}) : super(key: key);
@override
State<DemoScreen> createState() => _DemoScreenState();
}
class _DemoScreenState extends State<DemoScreen> with TickerProviderStateMixin {
final TextEditingController _messageController = TextEditingController();
final FocusNode _focusNode = FocusNode();
late final _messageNotifier = ValueNotifier(_messageController.text.isEmpty);
bool hasFocus = false;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
_focusNode.unfocus();
},
child: Scaffold(
appBar: AppBar(
title: const Text('Chat screen'),
),
body: Column(
children: <Widget>[
const Spacer(),
const Text(
'keyboard animation',
style: TextStyle(fontSize: 30),
),
const Spacer(),
Container(
padding: EdgeInsets.only(
bottom: MediaQuery.paddingOf(context).bottom + 10,
top: 6.0,
left: 15.0,
right: 15.0,
),
constraints: const BoxConstraints(
minHeight: 36,
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: DecoratedBox(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(19),
border: Border.all(
width: 0.5,
color: const Color(0xffCFCFCF),
),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Container(
margin: const EdgeInsets.fromLTRB(7, 6, 7, 6),
decoration: const BoxDecoration(
color: Color(0xFF007AEA),
shape: BoxShape.circle,
),
width: 24,
height: 24,
child: const Icon(
Icons.add,
color: Colors.white,
),
),
const SizedBox(width: 9.0),
Expanded(
child: Padding(
padding: const EdgeInsets.only(left: 0, right: 8),
child: TextFormField(
controller: _messageController,
minLines: 1,
textCapitalization: TextCapitalization.sentences,
focusNode: _focusNode,
decoration: const InputDecoration(
border: InputBorder.none,
isDense: true,
hintText: "Message",
),
),
),
),
ValueListenableBuilder<bool>(
valueListenable: _messageNotifier,
builder: (ctx, value, child) {
if (value) {
return const Padding(
padding: EdgeInsets.fromLTRB(7, 6, 7, 6),
child: Icon(
Icons.emoji_emotions_outlined,
color: Color(0xFF9E9E9E),
),
);
}
return const SizedBox.shrink();
},
)
],
),
),
),
const SizedBox(
width: 8,
),
Container(
height: 36,
width: 36,
decoration: const BoxDecoration(
color: Color(0xFF007AEA),
shape: BoxShape.circle,
),
child: ValueListenableBuilder<bool>(
valueListenable: _messageNotifier,
builder: (ctx, value, child) {
return GestureDetector(
onTap: () {
_focusNode.unfocus();
hasFocus = false;
},
child: const Icon(
Icons.send,
color: Colors.white,
),
);
},
),
),
],
),
),
],
),
),
);
}
}
|
Could you explain more about the solution in the PR description? |
Done |
Golden file changes have been found for this pull request. Click here to view and triage (e.g. because this is an intentional change). If you are still iterating on this change and are not ready to resolve the images on the Flutter Gold dashboard, consider marking this PR as a draft pull request above. You will still be able to view image results on the dashboard, commenting will be silenced, and the check will not try to resolve itself until marked ready for review. |
I am eagerly awaiting the implementation of this improvement. Presently, the management of the iOS keyboard's upper widget has been a source of considerable frustration due to issues of jank, jitter, and lack of synchronized animation |
I have changed the code for nits.
But I locally run the test and success without error 🤔 |
shell/platform/darwin/ios/framework/Source/FlutterViewController.mm
Outdated
Show resolved
Hide resolved
shell/platform/darwin/ios/framework/Source/FlutterViewController.mm
Outdated
Show resolved
Hide resolved
Still not sure why bot doesn't happy about the interface
|
I think I have solved the issue. Because the test |
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
… inset to avoid jitter. (flutter/engine#42312)
…128841) flutter/engine@66a5761...727b441 2023-06-13 [email protected] Reland "[ios_platform_view] only recycle maskView when the view is applying mutators #42115" (flutter/engine#42823) 2023-06-13 [email protected] Roll Dart SDK from 41234fa4b22d to 2465228c0c21 (1 revision) (flutter/engine#42822) 2023-06-13 [email protected] [Impeller] Added cache for command buffers in vulkan (flutter/engine#42793) 2023-06-13 [email protected] setupDefultFontManager correctly clear out cache (flutter/engine#42178) 2023-06-13 [email protected] [Impeller] Reland attempt Vulkan setup and fallback to GLES. (flutter/engine#42820) 2023-06-13 [email protected] Added CI step for building with validation layers (flutter/engine#42724) 2023-06-13 [email protected] [Impeller] Null check for the device holder in the Vulkan context destructor (flutter/engine#42821) 2023-06-13 [email protected] Add missing includes (flutter/engine#42812) 2023-06-13 [email protected] Roll Dart SDK from 4dce1093ad94 to 41234fa4b22d (1 revision) (flutter/engine#42810) 2023-06-13 [email protected] [iOS][Keyboard] Wait vsync on UI thread and update viewport inset to avoid jitter. (flutter/engine#42312) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC [email protected],[email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
@luckysmg @chinmaygarde thx so much for this 🎉 |
…nset to avoid jitter." (#43422) Reverts #42312 Original PR caused crash flutter/flutter#130028 Will reopen flutter/flutter#120555
…nset to avoid jitter." (flutter#43422) Reverts flutter#42312 Original PR caused crash flutter/flutter#130028 Will reopen flutter/flutter#120555
…nset to avoid jitter." (flutter#43422) Reverts flutter#42312 Original PR caused crash flutter/flutter#130028 Will reopen flutter/flutter#120555
Fixes flutter/flutter#120555.
Video for after and before this patch:
videos.zip
The technical problem is: if setViewportMetrics called before framework's vsync process callback (rebuild & layout & paint), will cause jitter keyboard animation.So this PR is to keep the time when updateViewportMetrics call to framework side legal.
Before
After
Pre-launch Checklist
///
).