Skip to content

Fix/resize mode none capacitor 8 3#63

Open
Franjanko wants to merge 4 commits intoionic-team:mainfrom
spaghetti-interactive:fix/resize-mode-none-capacitor-8-3
Open

Fix/resize mode none capacitor 8 3#63
Franjanko wants to merge 4 commits intoionic-team:mainfrom
spaghetti-interactive:fix/resize-mode-none-capacitor-8-3

Conversation

@Franjanko
Copy link
Copy Markdown

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.

Gabriele Mangiavacchi and others added 4 commits April 15, 2026 18:02
…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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant