registerExtensions method
void
registerExtensions()
Registers the extension. Call once, before runApp.
One extension, read and written through the same name — the shape
ext.flutterware.watch already uses. No arguments reads; any argument
writes and then reads, so a host never has to make two calls to find out
what its own write did.
Implementation
void registerExtensions() {
GuestExtensions.register('ext.flutterware.keyboard', (_, args) async {
if (args['dismiss'] == 'true') {
// The platform-closed path, not a mode change: the app is told its
// connection went away and unfocuses, which brings the keyboard down
// *because the view dismissed it*. A forced-up keyboard also lets go,
// since pressing dismiss on a keyboard you raised by hand plainly
// means take it away.
if (_mode == KeyboardMode.up) apply(mode: KeyboardMode.auto);
GuestTextInput.instance.dismiss();
}
var applied = apply(
mode: switch (args['mode']) {
String name => keyboardModeById(name),
_ => null,
},
deviceHeight: switch (args['height']) {
String height => double.tryParse(height),
_ => null,
},
deviceKeypadHeight: switch (args['keypadHeight']) {
String height => double.tryParse(height),
_ => null,
},
// The empty string is how a host says *this device does not shrink*,
// which is a different fact from saying nothing at all.
clearKeypad: args['keypadHeight'] == '',
);
// Answered only once the frame it caused has been painted, so a host
// that captures straight afterwards photographs the screen it asked for
// rather than the one before it. Bounded, because a guest that has
// stopped drawing should make this late rather than stuck.
if (applied) {
await WidgetsBinding.instance.endOfFrame.timeout(
const Duration(seconds: 2),
onTimeout: () {},
);
}
return developer.ServiceExtensionResponse.result(
jsonEncode(state.toJson()),
);
});
}