Capacitor Version
@capacitor/cli: 8.5.2
@capacitor/core: 8.5.2
@capacitor/android: 8.5.2
@capacitor/keyboard: 8.0.5
Also present in 8.5.1. Last version that behaves as expected: 8.2.0 (regression from #8384, released in 8.3.0).
Other API Details
Seen on a physical Android phone with viewport-fit=cover. From the code, it applies on API 35+ and on any device with WebView >= 140 and viewport-fit=cover.
Platforms Affected
Current Behavior
Since #8384, the insets listener in SystemBars pads for the keyboard whenever the IME is visible (both setPadding calls in initWindowInsetsListener use imeInsets.bottom). The WebView therefore shrinks by the keyboard height even when the activity declares android:windowSoftInputMode="adjustNothing".
Apps that keep content clear of the keyboard themselves, using the height from @capacitor/keyboard's keyboardWillShow as they do on iOS with resize: "none", now account for the keyboard twice. In our case a bottom padding equal to the keyboard height was applied inside a viewport that had already shrunk by that height, which left no room for the content at all.
There is no way to opt out short of insetsHandling: "disable", which also drops the safe area handling.
Removing only the padding is not enough on WebView >= 139: the listener still hands the IME insets to the WebView, which then resizes its visual viewport, and the whole page (including position: fixed elements) can be panned above the keyboard. See Understand window insets in WebView.
Expected Behavior
A way to keep the pre-8.3.0 behavior: the keyboard overlays the WebView and nothing is resized, e.g. when adjustNothing is set, or through an explicit option.
Proposal: an opt-in SystemBars option (for example keyboardInsetsHandling: "none", default unchanged) that
- leaves the IME out of the padding, and
- returns insets with
WindowInsetsCompat.Type.ime() set to Insets.NONE and not visible. That is the zeroing approach the Android guide recommends over CONSUMED, and what this listener already does for the system bar insets.
We verified exactly these two changes on a device as a local patch against 8.5.1: no resize, no panning, and the @capacitor/keyboard events still fire with the correct height (that plugin reads the root window insets). I'm happy to open a PR.
Project Reproduction
https://github.com/piotrblasiak/capacitor-keyboard-overlay-repro
A fresh npm init @capacitor/app where the only changes are src/index.html and android:windowSoftInputMode="adjustNothing" in the manifest. The page shows window.innerHeight, visualViewport.height and the keyboardWillShow height, plus a fixed bottom bar. Focus the input: window.innerHeight shrinks by the keyboard height and the bar jumps above the keyboard.
Additional Information
Related: this comment on #8384 asking for the same thing, and ionic-team/capacitor-keyboard#63, which tries to solve it from the keyboard plugin's side.
Capacitor Version
Also present in 8.5.1. Last version that behaves as expected: 8.2.0 (regression from #8384, released in 8.3.0).
Other API Details
Seen on a physical Android phone with
viewport-fit=cover. From the code, it applies on API 35+ and on any device with WebView >= 140 andviewport-fit=cover.Platforms Affected
Current Behavior
Since #8384, the insets listener in
SystemBarspads for the keyboard whenever the IME is visible (bothsetPaddingcalls ininitWindowInsetsListeneruseimeInsets.bottom). The WebView therefore shrinks by the keyboard height even when the activity declaresandroid:windowSoftInputMode="adjustNothing".Apps that keep content clear of the keyboard themselves, using the height from
@capacitor/keyboard'skeyboardWillShowas they do on iOS withresize: "none", now account for the keyboard twice. In our case a bottom padding equal to the keyboard height was applied inside a viewport that had already shrunk by that height, which left no room for the content at all.There is no way to opt out short of
insetsHandling: "disable", which also drops the safe area handling.Removing only the padding is not enough on WebView >= 139: the listener still hands the IME insets to the WebView, which then resizes its visual viewport, and the whole page (including
position: fixedelements) can be panned above the keyboard. See Understand window insets in WebView.Expected Behavior
A way to keep the pre-8.3.0 behavior: the keyboard overlays the WebView and nothing is resized, e.g. when
adjustNothingis set, or through an explicit option.Proposal: an opt-in
SystemBarsoption (for examplekeyboardInsetsHandling: "none", default unchanged) thatWindowInsetsCompat.Type.ime()set toInsets.NONEand not visible. That is the zeroing approach the Android guide recommends overCONSUMED, and what this listener already does for the system bar insets.We verified exactly these two changes on a device as a local patch against 8.5.1: no resize, no panning, and the
@capacitor/keyboardevents still fire with the correct height (that plugin reads the root window insets). I'm happy to open a PR.Project Reproduction
https://github.com/piotrblasiak/capacitor-keyboard-overlay-repro
A fresh
npm init @capacitor/appwhere the only changes aresrc/index.htmlandandroid:windowSoftInputMode="adjustNothing"in the manifest. The page showswindow.innerHeight,visualViewport.heightand thekeyboardWillShowheight, plus a fixed bottom bar. Focus the input:window.innerHeightshrinks by the keyboard height and the bar jumps above the keyboard.Additional Information
Related: this comment on #8384 asking for the same thing, and ionic-team/capacitor-keyboard#63, which tries to solve it from the keyboard plugin's side.