diff --git a/apps/chanora_flutter/lib/main.dart b/apps/chanora_flutter/lib/main.dart index 21b3c74..4eeb489 100644 --- a/apps/chanora_flutter/lib/main.dart +++ b/apps/chanora_flutter/lib/main.dart @@ -1267,12 +1267,38 @@ class _ConnectFormState extends State<_ConnectForm> { final FocusNode _passwordFocus = FocusNode(); Widget _focusOnTap(Widget child, FocusNode node) { + // iOS first-tap-not-focusing workaround. + // + // Symptom: the user taps a TextField the first time after the + // app launches (or after the field has not held focus this + // session); the cursor doesn't appear and the on-screen keyboard + // doesn't slide up. A second tap then works normally. + // + // Root cause: Flutter's EditableText opens the platform + // TextInput channel (which is what actually slides the iOS + // keyboard up) only after a TapGestureRecognizer **wins** the + // gesture arena. Our outer Listener (HitTestBehavior.translucent, + // onPointerDown) used to call node.requestFocus() pre-arena, + // which marks the node focused in Flutter's tree but does not + // open the TextInput channel \u2014 so the OS keyboard stays hidden + // until the EditableText's own tap recognizer wins on a second + // tap. + // + // Fix: in addition to requestFocus(), invoke 'TextInput.show' + // on the SystemChannels.textInput method channel. This is the + // same private RPC EditableText uses internally; calling it + // ourselves forces the OS keyboard up regardless of arena state. + // Belt-and-braces with the Listener guarantees keyboard-on-first- + // tap on iPhone / iPad and is harmless on Android (the platform + // ignores the redundant show call when the keyboard is already + // up) and on desktop (no soft keyboard exists). return Listener( behavior: HitTestBehavior.translucent, onPointerDown: (_) { if (!node.hasFocus) { node.requestFocus(); } + SystemChannels.textInput.invokeMethod('TextInput.show'); }, child: child, );