Open
Conversation
…callbacks - Null-check getRootWindowInsets() in setOnApplyWindowInsetsListener to prevent NPE when view is detached - Null-check getRootWindowInsets() in onStart() and refactor to single call - Null-check getRootWindowInsets() in onEnd() to prevent NPE when view is detached - Null-check keyboardEventListener (@nullable) before invoking in onStart() and onEnd() - Remove unused imports (Build, TypedValue, Insets)
… mode is none Capacitor 8.3.0 introduced bridge-level IME inset handling that causes the WebView to shrink when the software keyboard appears, regardless of the resize mode configured via setResizeMode(). Changes: - Replace the constructor-captured boolean resizeOnFullScreen with a mutable resizeEnabled field so the policy can be toggled at runtime. - When resizeEnabled is false and the keyboard becomes visible, consume IME WindowInsetsCompat so the WebView and its siblings never receive the inset, counteracting the new bridge behaviour introduced in 8.3.0. - Use Keyboard.this.resizeEnabled in the WindowInsetsAnimationCompat callback so the animation path also respects runtime changes. - Expose setResizeEnabled(boolean) and isResizeEnabled() API for KeyboardPlugin to call. - Implement setResizeMode() and getResizeMode() plugin methods; they were previously unimplemented. The initial value of currentResizeMode is derived from the resizeOnFullScreen config at load() time.
Capacitor 8.3.0 added resize logic in the bridge that resizes the
WebView frame and/or raises additionalSafeAreaInsets.bottom when the
software keyboard appears. This bypassed the ResizeNone policy that the
plugin is supposed to enforce via setResizeMode("none").
Add an explicit case ResizeNone branch in _updateFrame that:
- Restores the WebView to its full-screen frame (no keyboard padding).
- Resets additionalSafeAreaInsets.bottom to 0 on the bridge
view controller if the bridge raised it, so that the content inset
is fully suppressed while resize mode is none.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fix setResizeMode("none") (and the resize: "none" plugin config) not preventing the WebView from being resized when the software keyboard appears, after upgrading to Capacitor 8.3.0.
Change Type
Fix
Rationale / Problems Fixed
Capacitor 8.3.0 introduced bridge-level IME inset handling on both iOS and Android that resizes the WebView when the software keyboard is shown. This change bypasses the resize policy that this plugin is supposed to enforce, making setResizeMode("none") (and resize: "none" in plugin config) completely ineffective after upgrading from 8.1.x.
iOS: _updateFrame had no case ResizeNone: branch, so the bridge was free to shrink the WebView frame and raise additionalSafeAreaInsets.bottom unchecked.
Android: setResizeMode and getResizeMode were always returning call.unimplemented(). Additionally, the resize policy was captured in the constructor as an effectively-final local variable (resizeOnFullScreen), making it impossible to change at runtime even if the methods had been implemented.
Tests or Reproductions
Create a Capacitor 8.3.0 app with this plugin configured as resize: "none" in capacitor.config.ts:
Focus any text input to trigger the software keyboard.
Before this fix: the WebView shrinks to push content above the keyboard.
After this fix: the WebView stays full-screen and the keyboard overlaps the content as expected.
Same reproduction applies when calling Keyboard.setResizeMode({ mode: 'none' }) at runtime.
Platforms Affected
Android
iOS
Notes / Comments
iOS changes (Keyboard.m):
Added explicit case ResizeNone: in _updateFrame that restores the WebView to its full-screen frame and resets additionalSafeAreaInsets.bottom to 0 if the bridge raised it.
Android changes (android/.../Keyboard.java):
Replaced the constructor-captured resizeOnFullScreen boolean with a mutable resizeEnabled field so the policy can be toggled at runtime via setResizeEnabled(boolean).
When resizeEnabled is false and the keyboard is visible, IME WindowInsetsCompat are consumed before being dispatched to the WebView, counteracting the new bridge inset handling introduced in 8.3.0.
Android changes (android/.../KeyboardPlugin.java):
Implemented setResizeMode() and getResizeMode() plugin methods (previously unimplemented()).
currentResizeMode is initialised at load() time from the resizeOnFullScreen config value.