Bug Report
Capacitor Version
Latest Dependencies:
@capacitor/cli: 8.5.0
@capacitor/core: 8.5.0
@capacitor/android: 8.5.0
@capacitor/ios: 8.5.0
Installed Dependencies:
@capacitor/cli: 8.3.4
@capacitor/android: 8.3.4
@capacitor/core: 8.3.4
@capacitor/ios: 8.3.4
[success] iOS looking great! 👌
[success] Android looking great! 👌
Platform(s)
Android (Pixel 8a)
Current Behavior
When keyboard is open and android has gesture navigation mode, if user swipes right from left edge (back swipe), but doesn't release and goes back to cancel back action, the keyboard plugin emits "willHide" and "didHide" events, but the keyboard stays open. Tapping or moving caret inside input area doesn't emit "willShow" event
Expected Behavior
"willHide" and "didHide" events shouldn't emit until user actually releases back swipe and activates "go back" action
Code Reproduction
Just have any input / contenteditable element, tap it to open keyboard, then swipe from any edge to go back, but don't release and cancel the swipe
Other Technical Details
Additional Context
Why the plugin gets it wrong
Keyboard.java:76-130 derives everything from a WindowInsetsAnimationCompat.Callback, sampling getRootWindowInsets(rootView).isVisible(ime()) at exactly two instants: onStart → will, onEnd → did.
A back gesture that gets cancelled is one insets animation, not two. ImeBackAnimationController takes control of the IME inset when the swipe starts, drags it out, and on cancel animates it back and finishes the same animation. So:
onStart fires while the IME is on its way out → visibility reads false → keyboardWillHide. Fair enough.
onEnd fires once at the very end, and getRootWindowInsets still reports the IME hidden — your listener, which reads the insets actually being dispatched, sees visible: true 1–2ms earlier. So the plugin emits keyboardDidHide.
Nothing follows, because no new animation ever runs — the keyboard never moved again. That's also why tapping the editor or moving the caret emits no willShow: from Android's point of view the IME is already up, so there's nothing to animate.
Bug Report
Capacitor Version
Platform(s)
Android (Pixel 8a)
Current Behavior
When keyboard is open and android has gesture navigation mode, if user swipes right from left edge (back swipe), but doesn't release and goes back to cancel back action, the keyboard plugin emits "willHide" and "didHide" events, but the keyboard stays open. Tapping or moving caret inside input area doesn't emit "willShow" event
Expected Behavior
"willHide" and "didHide" events shouldn't emit until user actually releases back swipe and activates "go back" action
Code Reproduction
Just have any input / contenteditable element, tap it to open keyboard, then swipe from any edge to go back, but don't release and cancel the swipe
Other Technical Details
Additional Context
Why the plugin gets it wrong
Keyboard.java:76-130 derives everything from a WindowInsetsAnimationCompat.Callback, sampling getRootWindowInsets(rootView).isVisible(ime()) at exactly two instants: onStart → will, onEnd → did.
A back gesture that gets cancelled is one insets animation, not two. ImeBackAnimationController takes control of the IME inset when the swipe starts, drags it out, and on cancel animates it back and finishes the same animation. So:
onStart fires while the IME is on its way out → visibility reads false → keyboardWillHide. Fair enough.
onEnd fires once at the very end, and getRootWindowInsets still reports the IME hidden — your listener, which reads the insets actually being dispatched, sees visible: true 1–2ms earlier. So the plugin emits keyboardDidHide.
Nothing follows, because no new animation ever runs — the keyboard never moved again. That's also why tapping the editor or moving the caret emits no willShow: from Android's point of view the IME is already up, so there's nothing to animate.