Skip to content

[Bug]: Android SystemBars.show({ bar: StatusBar }) also shows the navigation bar #8479

@fallintoplace

Description

@fallintoplace

Capacitor Version

Current main (e456de08). I checked history as well: this behavior appears to have been present since the SystemBars plugin was introduced in a32216ac on November 12, 2025.

Platforms Affected

  • iOS
  • Android
  • Web

Current Behavior

On Android, SystemBars.show({ bar: SystemBarType.StatusBar }) also shows the navigation bar.

The hide() path treats the two bars separately, but the show() path does not:

  • hide(StatusBar) -> WindowInsetsCompat.Type.statusBars()
  • hide(NavigationBar) -> WindowInsetsCompat.Type.navigationBars()
  • show(StatusBar) -> WindowInsetsCompat.Type.systemBars()
  • show(NavigationBar) -> WindowInsetsCompat.Type.navigationBars()

Since systemBars() includes both status and navigation bars, a status-only show request reveals both bars.

Expected Behavior

SystemBars.show({ bar: SystemBarType.StatusBar }) should only show the status bar, leaving the navigation bar unchanged.

Reproduction

import { SystemBars, SystemBarType } from '@capacitor/core';

await SystemBars.hide({ bar: SystemBarType.NavigationBar });
await SystemBars.show({ bar: SystemBarType.StatusBar });

Expected:
The status bar appears and the navigation bar stays hidden.

Actual:
The navigation bar appears too.

Why this looks like a bug

The public API/docs describe bar as "The system bar to hide or show", which implies StatusBar and NavigationBar should be handled independently.

The Android implementation already does that correctly in the hide() path, and iOS also behaves symmetrically. The Android show() path is the odd one out.

Relevant code

android/capacitor/src/main/java/com/getcapacitor/plugin/SystemBars.java

Current show() branch:

if (bar.isEmpty() || bar.equals(BAR_STATUS_BAR)) {
    windowInsetsControllerCompat.show(WindowInsetsCompat.Type.systemBars());
}
if (bar.isEmpty() || bar.equals(BAR_GESTURE_BAR)) {
    windowInsetsControllerCompat.show(WindowInsetsCompat.Type.navigationBars());
}

Suggested fix

if (bar.isEmpty()) {
    windowInsetsControllerCompat.show(WindowInsetsCompat.Type.systemBars());
} else if (bar.equals(BAR_STATUS_BAR)) {
    windowInsetsControllerCompat.show(WindowInsetsCompat.Type.statusBars());
} else if (bar.equals(BAR_GESTURE_BAR)) {
    windowInsetsControllerCompat.show(WindowInsetsCompat.Type.navigationBars());
}

Additional Information

I did not find a recent commit that introduced this. git blame points back to the original SystemBars plugin implementation, so this looks like an original Android mapping bug rather than a regression from the recent inset work.

Metadata

Metadata

Assignees

Type

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions