capacitor-plugin-status-bar 2.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -137,7 +137,7 @@ getSafeAreaInsets() => Promise<SafeAreaInsets>
137
137
 
138
138
  Get the safe area insets.
139
139
  Returns the insets for status bar, navigation bar, and notch areas.
140
- Values are in pixels on Android and points on iOS.
140
+ Values are in CSS pixels (dp) on all platforms.
141
141
 
142
142
  **Returns:** <code>Promise&lt;<a href="#safeareainsets">SafeAreaInsets</a>&gt;</code>
143
143
 
@@ -21,7 +21,6 @@ import androidx.core.view.WindowInsetsCompat;
21
21
 
22
22
  import com.getcapacitor.Plugin;
23
23
 
24
- import java.util.Objects;
25
24
 
26
25
  /**
27
26
  * Android Status Bar utilities with Android 10-15+ (API 29-35+) support.
@@ -279,60 +278,45 @@ public class StatusBar extends Plugin {
279
278
  * Returns the insets for status bar, navigation bar, and notch areas.
280
279
  *
281
280
  * @param activity The activity to get the insets from
282
- * @return A map containing top, bottom, left, and right inset values in pixels
281
+ * @return A map containing top, bottom, left, and right inset values in dp (density-independent pixels)
283
282
  */
284
283
  public java.util.Map<String, Integer> getSafeAreaInsets(Activity activity) {
285
284
  Log.d(TAG, "getSafeAreaInsets");
286
285
  java.util.Map<String, Integer> insets = new java.util.HashMap<>();
286
+ float density = activity.getResources().getDisplayMetrics().density;
287
287
 
288
- Window window = activity.getWindow();
289
- View decorView = window.getDecorView();
290
-
291
- WindowInsets windowInsets = decorView.getRootWindowInsets();
292
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
293
- // API 30+ (Android 11+) - Use WindowInsets API
294
- if (windowInsets != null) {
295
- android.graphics.Insets systemBarsInsets = windowInsets.getInsets(WindowInsets.Type.systemBars());
296
- android.graphics.Insets displayCutoutInsets = windowInsets.getInsets(WindowInsets.Type.displayCutout());
297
-
298
- // Combine system bars and display cutout insets (use maximum of both)
299
- insets.put("top", Math.max(systemBarsInsets.top, displayCutoutInsets.top));
300
- insets.put("bottom", Math.max(systemBarsInsets.bottom, displayCutoutInsets.bottom));
301
- insets.put("left", Math.max(systemBarsInsets.left, displayCutoutInsets.left));
302
- insets.put("right", Math.max(systemBarsInsets.right, displayCutoutInsets.right));
303
-
304
- Log.d(TAG, "getSafeAreaInsets (API 30+): top=" + insets.get("top")
305
- + ", bottom=" + insets.get("bottom")
306
- + ", left=" + insets.get("left")
307
- + ", right=" + insets.get("right"));
308
- } else {
309
- // Fallback to zero insets
310
- insets.put("top", 0);
311
- insets.put("bottom", 0);
312
- insets.put("left", 0);
313
- insets.put("right", 0);
314
- Log.w(TAG, "getSafeAreaInsets: windowInsets is null");
315
- }
288
+ View decorView = activity.getWindow().getDecorView();
289
+ WindowInsetsCompat windowInsets = ViewCompat.getRootWindowInsets(decorView);
290
+
291
+ if (windowInsets != null) {
292
+ // Use WindowInsetsCompat for accurate, type-specific insets across all API levels
293
+ androidx.core.graphics.Insets statusBars = windowInsets.getInsets(WindowInsetsCompat.Type.statusBars());
294
+ androidx.core.graphics.Insets navBars = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars());
295
+ androidx.core.graphics.Insets displayCutout = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout());
296
+
297
+ int topPx = Math.max(statusBars.top, displayCutout.top);
298
+ int bottomPx = Math.max(navBars.bottom, displayCutout.bottom);
299
+ int leftPx = Math.max(navBars.left, displayCutout.left);
300
+ int rightPx = Math.max(navBars.right, displayCutout.right);
301
+
302
+ // Convert physical pixels to dp (CSS pixels) for the WebView layer
303
+ insets.put("top", Math.round(topPx / density));
304
+ insets.put("bottom", Math.round(bottomPx / density));
305
+ insets.put("left", Math.round(leftPx / density));
306
+ insets.put("right", Math.round(rightPx / density));
307
+
308
+ Log.d(TAG, "getSafeAreaInsets: topPx=" + topPx + " bottomPx=" + bottomPx
309
+ + " density=" + density
310
+ + " -> top=" + insets.get("top") + "dp"
311
+ + " bottom=" + insets.get("bottom") + "dp"
312
+ + " left=" + insets.get("left") + "dp"
313
+ + " right=" + insets.get("right") + "dp");
316
314
  } else {
317
- // API 29 (Android 10) - Use deprecated system window insets
318
- if (windowInsets != null) {
319
- insets.put("top", windowInsets.getSystemWindowInsetTop());
320
- insets.put("bottom", windowInsets.getSystemWindowInsetBottom());
321
- insets.put("left", windowInsets.getSystemWindowInsetLeft());
322
- insets.put("right", windowInsets.getSystemWindowInsetRight());
323
-
324
- Log.d(TAG, "getSafeAreaInsets (API 29): top=" + insets.get("top")
325
- + ", bottom=" + insets.get("bottom")
326
- + ", left=" + insets.get("left")
327
- + ", right=" + insets.get("right"));
328
- } else {
329
- // Fallback to zero insets
330
- insets.put("top", 0);
331
- insets.put("bottom", 0);
332
- insets.put("left", 0);
333
- insets.put("right", 0);
334
- Log.w(TAG, "getSafeAreaInsets: windowInsets is null");
335
- }
315
+ insets.put("top", 0);
316
+ insets.put("bottom", 0);
317
+ insets.put("left", 0);
318
+ insets.put("right", 0);
319
+ Log.w(TAG, "getSafeAreaInsets: windowInsets is null");
336
320
  }
337
321
 
338
322
  return insets;
@@ -400,25 +384,17 @@ public class StatusBar extends Plugin {
400
384
 
401
385
  private void applyStatusBarBackground(Activity activity, @ColorInt int color) {
402
386
  Log.d(TAG, "applyStatusBarBackground: color=#" + Integer.toHexString(color) + ", API=" + Build.VERSION.SDK_INT);
403
- Window window = activity.getWindow();
404
- if (Build.VERSION.SDK_INT >= 35) {
405
- ensureStatusBarOverlay(activity, color);
406
- } else {
407
- removeStatusBarOverlayIfPresent(activity);
408
- window.setStatusBarColor(color);
409
- }
387
+ // Use overlay approach for all API levels since edge-to-edge mode
388
+ // (setDecorFitsSystemWindows=false) makes window.setStatusBarColor() ineffective
389
+ ensureStatusBarOverlay(activity, color);
410
390
  }
411
391
 
412
392
  private void applyNavigationBarBackground(Activity activity, @ColorInt int color) {
413
393
  Log.d(TAG, "applyNavigationBarBackground: color=#" + Integer.toHexString(color) + ", API="
414
394
  + Build.VERSION.SDK_INT);
415
- Window window = activity.getWindow();
416
- if (Build.VERSION.SDK_INT >= 35) {
417
- ensureNavBarOverlay(activity, color);
418
- } else {
419
- removeNavBarOverlayIfPresent(activity);
420
- window.setNavigationBarColor(color);
421
- }
395
+ // Use overlay approach for all API levels since edge-to-edge mode
396
+ // (setDecorFitsSystemWindows=false) makes window.setNavigationBarColor() ineffective
397
+ ensureNavBarOverlay(activity, color);
422
398
  }
423
399
 
424
400
  private void ensureStatusBarOverlay(Activity activity, @ColorInt int color) {
@@ -440,26 +416,37 @@ public class StatusBar extends Plugin {
440
416
  // Add to the top of the decor view
441
417
  decorView.addView(overlay);
442
418
 
443
- // Apply correct height from insets
444
- ViewCompat.setOnApplyWindowInsetsListener(overlay, (v, windowInsets) -> {
445
- int top;
446
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
447
- top = Objects.requireNonNull(windowInsets.toWindowInsets())
448
- .getInsets(WindowInsets.Type.statusBars()).top;
449
- } else {
450
- top = Objects.requireNonNull(windowInsets.toWindowInsets()).getSystemWindowInsetTop();
419
+ // Listen on decorView for reliable insets dispatch across all API levels,
420
+ // then use WindowInsetsCompat.Type.statusBars() for accurate status-bar-only height
421
+ ViewCompat.setOnApplyWindowInsetsListener(decorView, (v, windowInsets) -> {
422
+ int top = windowInsets.getInsets(WindowInsetsCompat.Type.statusBars()).top;
423
+ View statusOverlay = decorView.findViewWithTag(STATUS_BAR_OVERLAY_TAG);
424
+ if (statusOverlay != null) {
425
+ ViewGroup.LayoutParams params = statusOverlay.getLayoutParams();
426
+ if (params.height != top) {
427
+ params.height = top;
428
+ statusOverlay.setLayoutParams(params);
429
+ }
430
+ }
431
+
432
+ int bottom = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom;
433
+ View navOverlay = decorView.findViewWithTag(NAV_BAR_OVERLAY_TAG);
434
+ if (navOverlay != null) {
435
+ ViewGroup.LayoutParams params = navOverlay.getLayoutParams();
436
+ if (params.height != bottom) {
437
+ params.height = bottom;
438
+ navOverlay.setLayoutParams(params);
439
+ }
451
440
  }
452
- ViewGroup.LayoutParams params = v.getLayoutParams();
453
- params.height = top;
454
- v.setLayoutParams(params);
455
- // Don't set color here - it's set before listener and should not be overridden
441
+
442
+ ViewCompat.onApplyWindowInsets(v, windowInsets);
456
443
  return windowInsets;
457
444
  });
458
- overlay.requestApplyInsets();
445
+ decorView.requestApplyInsets();
459
446
  } else {
460
447
  Log.d(TAG, "ensureStatusBarOverlay: updating existing overlay");
461
448
  existing.setBackgroundColor(color);
462
- existing.requestApplyInsets();
449
+ decorView.requestApplyInsets();
463
450
  }
464
451
  }
465
452
 
@@ -491,25 +478,39 @@ public class StatusBar extends Plugin {
491
478
 
492
479
  decorView.addView(overlay);
493
480
 
494
- ViewCompat.setOnApplyWindowInsetsListener(overlay, (v, windowInsets) -> {
495
- int bottom;
496
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
497
- bottom = Objects.requireNonNull(windowInsets.toWindowInsets())
498
- .getInsets(WindowInsets.Type.navigationBars()).bottom;
499
- } else {
500
- bottom = Objects.requireNonNull(windowInsets.toWindowInsets()).getSystemWindowInsetBottom();
501
- }
502
- ViewGroup.LayoutParams params = v.getLayoutParams();
503
- params.height = bottom;
504
- v.setLayoutParams(params);
505
- // Don't set color here - it's set before listener and should not be overridden
506
- return windowInsets;
507
- });
508
- overlay.requestApplyInsets();
481
+ // Insets sizing is handled by the shared decorView listener in ensureStatusBarOverlay.
482
+ // If status bar overlay was not created yet, set up the listener here.
483
+ if (decorView.findViewWithTag(STATUS_BAR_OVERLAY_TAG) == null) {
484
+ ViewCompat.setOnApplyWindowInsetsListener(decorView, (v, windowInsets) -> {
485
+ int top = windowInsets.getInsets(WindowInsetsCompat.Type.statusBars()).top;
486
+ View statusOverlay = decorView.findViewWithTag(STATUS_BAR_OVERLAY_TAG);
487
+ if (statusOverlay != null) {
488
+ ViewGroup.LayoutParams params = statusOverlay.getLayoutParams();
489
+ if (params.height != top) {
490
+ params.height = top;
491
+ statusOverlay.setLayoutParams(params);
492
+ }
493
+ }
494
+
495
+ int bottom = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom;
496
+ View navOverlay = decorView.findViewWithTag(NAV_BAR_OVERLAY_TAG);
497
+ if (navOverlay != null) {
498
+ ViewGroup.LayoutParams params = navOverlay.getLayoutParams();
499
+ if (params.height != bottom) {
500
+ params.height = bottom;
501
+ navOverlay.setLayoutParams(params);
502
+ }
503
+ }
504
+
505
+ ViewCompat.onApplyWindowInsets(v, windowInsets);
506
+ return windowInsets;
507
+ });
508
+ }
509
+ decorView.requestApplyInsets();
509
510
  } else {
510
511
  Log.d(TAG, "ensureNavBarOverlay: updating existing overlay");
511
512
  existing.setBackgroundColor(color);
512
- existing.requestApplyInsets();
513
+ decorView.requestApplyInsets();
513
514
  }
514
515
  }
515
516
 
@@ -537,26 +538,19 @@ public class StatusBar extends Plugin {
537
538
  Log.d(TAG, "makeStatusBarBackgroundTransparent: API=" + Build.VERSION.SDK_INT);
538
539
  Window window = activity.getWindow();
539
540
 
540
- if (Build.VERSION.SDK_INT >= 35) {
541
- // API 35+ (Android 15+) - Make overlay views transparent
542
- ViewGroup decorView = (ViewGroup) window.getDecorView();
543
- View statusBarOverlay = decorView.findViewWithTag(STATUS_BAR_OVERLAY_TAG);
544
- View navBarOverlay = decorView.findViewWithTag(NAV_BAR_OVERLAY_TAG);
541
+ // Make overlay views transparent (used for all API levels)
542
+ ViewGroup decorView = (ViewGroup) window.getDecorView();
543
+ View statusBarOverlay = decorView.findViewWithTag(STATUS_BAR_OVERLAY_TAG);
544
+ View navBarOverlay = decorView.findViewWithTag(NAV_BAR_OVERLAY_TAG);
545
545
 
546
- if (statusBarOverlay != null) {
547
- statusBarOverlay.setBackgroundColor(Color.TRANSPARENT);
548
- Log.d(TAG, "makeStatusBarBackgroundTransparent: status bar overlay made transparent");
549
- }
546
+ if (statusBarOverlay != null) {
547
+ statusBarOverlay.setBackgroundColor(Color.TRANSPARENT);
548
+ Log.d(TAG, "makeStatusBarBackgroundTransparent: status bar overlay made transparent");
549
+ }
550
550
 
551
- if (navBarOverlay != null) {
552
- navBarOverlay.setBackgroundColor(Color.TRANSPARENT);
553
- Log.d(TAG, "makeStatusBarBackgroundTransparent: navigation bar overlay made transparent");
554
- }
555
- } else {
556
- // API 29-34 - Make window bars transparent
557
- window.setStatusBarColor(Color.TRANSPARENT);
558
- window.setNavigationBarColor(Color.TRANSPARENT);
559
- Log.d(TAG, "makeStatusBarBackgroundTransparent: window bars made transparent");
551
+ if (navBarOverlay != null) {
552
+ navBarOverlay.setBackgroundColor(Color.TRANSPARENT);
553
+ Log.d(TAG, "makeStatusBarBackgroundTransparent: navigation bar overlay made transparent");
560
554
  }
561
555
  }
562
556
 
package/dist/docs.json CHANGED
@@ -150,7 +150,7 @@
150
150
  "parameters": [],
151
151
  "returns": "Promise<SafeAreaInsets>",
152
152
  "tags": [],
153
- "docs": "Get the safe area insets.\nReturns the insets for status bar, navigation bar, and notch areas.\nValues are in pixels on Android and points on iOS.",
153
+ "docs": "Get the safe area insets.\nReturns the insets for status bar, navigation bar, and notch areas.\nValues are in CSS pixels (dp) on all platforms.",
154
154
  "complexTypes": [
155
155
  "SafeAreaInsets"
156
156
  ],
@@ -90,7 +90,7 @@ export interface StatusBarPlugin {
90
90
  /**
91
91
  * Get the safe area insets.
92
92
  * Returns the insets for status bar, navigation bar, and notch areas.
93
- * Values are in pixels on Android and points on iOS.
93
+ * Values are in CSS pixels (dp) on all platforms.
94
94
  */
95
95
  getSafeAreaInsets(): Promise<SafeAreaInsets>;
96
96
  }
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,KAIX;AAJD,WAAY,KAAK;IACf,wBAAe,CAAA;IACf,sBAAa,CAAA;IACb,0BAAiB,CAAA;AACnB,CAAC,EAJW,KAAK,KAAL,KAAK,QAIhB;AAWD,MAAM,CAAN,IAAY,kBAIX;AAJD,WAAY,kBAAkB;IAC5B,mCAAa,CAAA;IACb,mCAAa,CAAA;IACb,qCAAe,CAAA;AACjB,CAAC,EAJW,kBAAkB,KAAlB,kBAAkB,QAI7B","sourcesContent":["export enum Style {\n LIGHT = 'LIGHT',\n DARK = 'DARK',\n CUSTOM = 'CUSTOM',\n}\n\n/**\n * Full HEX color format only (6 or 8 digits).\n * - 6 digits: #RRGGBB (e.g., #FFFFFF, #000000, #FF5733)\n * - 8 digits: #RRGGBBAA with alpha channel (e.g., #FFFFFF00, #FF5733CC)\n *\n * Note: Short 3-digit format (#FFF) is NOT supported.\n */\nexport type StatusBarColor = `#${string}`;\n\nexport enum StatusBarAnimation {\n NONE = 'none',\n FADE = 'fade',\n SLIDE = 'slide',\n}\n\ntype StatusBarStyleNoDefaultOptions = {\n style: Style;\n};\n\ntype StatusBarStyleOptions =\n | StatusBarStyleNoDefaultOptions\n | {\n style: Style.CUSTOM;\n color: StatusBarColor;\n };\n\nexport type StatusBarOptions = StatusBarStyleOptions;\n\nexport type StatusBarShowOptions = {\n animated: boolean;\n};\n\nexport type StatusBarHideOptions = {\n /**\n * The animation type for hiding the status bar.\n * - 'fade': Makes the background transparent without removing the status bar and navigation bar.\n * - 'slide': Hides the status bar and navigation bar completely (default behavior).\n */\n animation: StatusBarAnimation;\n};\n\nexport type StatusBarSetOverlaysWebViewOptions = {\n value: boolean;\n};\n\nexport type StatusBarSetBackgroundOptions = {\n color: StatusBarColor;\n};\n\nexport type SafeAreaInsets = {\n top: number;\n bottom: number;\n left: number;\n right: number;\n};\n\nexport interface StatusBarPlugin {\n /**\n * Set the status bar and navigation bar style and color.\n * @param options - The options to set the status bar style and color.\n * @param options.style - The style of the status bar.\n * @param options.color - The color of the status bar.\n */\n setStyle(options: StatusBarOptions): Promise<void>;\n /**\n * Show the status bar.\n * @param options - The options to show the status bar.\n * @param options.animated - Whether to animate the status bar.\n */\n show(options: StatusBarShowOptions): Promise<void>;\n /**\n * Hide the status bar.\n * @param options - The options to hide the status bar.\n * @param options.animation - The animation type: 'fade' makes background transparent, 'slide' hides bars completely.\n */\n hide(options: StatusBarHideOptions): Promise<void>;\n /**\n * Set whether the status bar overlays the web view.\n *\n * **iOS only** - On Android this is a no-op (resolves without error).\n *\n * - `true`: Web content extends behind the status bar (transparent background),\n * allowing content to be visible through the status bar area on scroll.\n * - `false`: Restores the status bar background to the color set by `setStyle`\n * or falls back to the default style from Capacitor config.\n *\n * @param options - The options to set the status bar overlays web view.\n * @param options.value - Whether the status bar overlays the web view (required).\n */\n setOverlaysWebView(options: StatusBarSetOverlaysWebViewOptions): Promise<void>;\n /**\n * Set the window background color.\n * @param options - The options to set the window background color.\n * @param options.color - The background color in HEX format.\n */\n setBackground(options: StatusBarSetBackgroundOptions): Promise<void>;\n /**\n * Get the safe area insets.\n * Returns the insets for status bar, navigation bar, and notch areas.\n * Values are in pixels on Android and points on iOS.\n */\n getSafeAreaInsets(): Promise<SafeAreaInsets>;\n}\n"]}
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,KAIX;AAJD,WAAY,KAAK;IACf,wBAAe,CAAA;IACf,sBAAa,CAAA;IACb,0BAAiB,CAAA;AACnB,CAAC,EAJW,KAAK,KAAL,KAAK,QAIhB;AAWD,MAAM,CAAN,IAAY,kBAIX;AAJD,WAAY,kBAAkB;IAC5B,mCAAa,CAAA;IACb,mCAAa,CAAA;IACb,qCAAe,CAAA;AACjB,CAAC,EAJW,kBAAkB,KAAlB,kBAAkB,QAI7B","sourcesContent":["export enum Style {\n LIGHT = 'LIGHT',\n DARK = 'DARK',\n CUSTOM = 'CUSTOM',\n}\n\n/**\n * Full HEX color format only (6 or 8 digits).\n * - 6 digits: #RRGGBB (e.g., #FFFFFF, #000000, #FF5733)\n * - 8 digits: #RRGGBBAA with alpha channel (e.g., #FFFFFF00, #FF5733CC)\n *\n * Note: Short 3-digit format (#FFF) is NOT supported.\n */\nexport type StatusBarColor = `#${string}`;\n\nexport enum StatusBarAnimation {\n NONE = 'none',\n FADE = 'fade',\n SLIDE = 'slide',\n}\n\ntype StatusBarStyleNoDefaultOptions = {\n style: Style;\n};\n\ntype StatusBarStyleOptions =\n | StatusBarStyleNoDefaultOptions\n | {\n style: Style.CUSTOM;\n color: StatusBarColor;\n };\n\nexport type StatusBarOptions = StatusBarStyleOptions;\n\nexport type StatusBarShowOptions = {\n animated: boolean;\n};\n\nexport type StatusBarHideOptions = {\n /**\n * The animation type for hiding the status bar.\n * - 'fade': Makes the background transparent without removing the status bar and navigation bar.\n * - 'slide': Hides the status bar and navigation bar completely (default behavior).\n */\n animation: StatusBarAnimation;\n};\n\nexport type StatusBarSetOverlaysWebViewOptions = {\n value: boolean;\n};\n\nexport type StatusBarSetBackgroundOptions = {\n color: StatusBarColor;\n};\n\nexport type SafeAreaInsets = {\n top: number;\n bottom: number;\n left: number;\n right: number;\n};\n\nexport interface StatusBarPlugin {\n /**\n * Set the status bar and navigation bar style and color.\n * @param options - The options to set the status bar style and color.\n * @param options.style - The style of the status bar.\n * @param options.color - The color of the status bar.\n */\n setStyle(options: StatusBarOptions): Promise<void>;\n /**\n * Show the status bar.\n * @param options - The options to show the status bar.\n * @param options.animated - Whether to animate the status bar.\n */\n show(options: StatusBarShowOptions): Promise<void>;\n /**\n * Hide the status bar.\n * @param options - The options to hide the status bar.\n * @param options.animation - The animation type: 'fade' makes background transparent, 'slide' hides bars completely.\n */\n hide(options: StatusBarHideOptions): Promise<void>;\n /**\n * Set whether the status bar overlays the web view.\n *\n * **iOS only** - On Android this is a no-op (resolves without error).\n *\n * - `true`: Web content extends behind the status bar (transparent background),\n * allowing content to be visible through the status bar area on scroll.\n * - `false`: Restores the status bar background to the color set by `setStyle`\n * or falls back to the default style from Capacitor config.\n *\n * @param options - The options to set the status bar overlays web view.\n * @param options.value - Whether the status bar overlays the web view (required).\n */\n setOverlaysWebView(options: StatusBarSetOverlaysWebViewOptions): Promise<void>;\n /**\n * Set the window background color.\n * @param options - The options to set the window background color.\n * @param options.color - The background color in HEX format.\n */\n setBackground(options: StatusBarSetBackgroundOptions): Promise<void>;\n /**\n * Get the safe area insets.\n * Returns the insets for status bar, navigation bar, and notch areas.\n * Values are in CSS pixels (dp) on all platforms.\n */\n getSafeAreaInsets(): Promise<SafeAreaInsets>;\n}\n"]}
@@ -230,13 +230,19 @@ import Capacitor
230
230
 
231
231
  if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
232
232
  let window = windowScene.windows.first {
233
+ // Use statusBarManager for accurate status bar height
234
+ let statusBarHeight = windowScene.statusBarManager?.statusBarFrame.height ?? 0
233
235
  let safeAreaInsets = window.safeAreaInsets
234
- insets["top"] = safeAreaInsets.top
236
+
237
+ // top: status bar height specifically
238
+ insets["top"] = statusBarHeight
239
+ // bottom: home indicator / navigation bar area
235
240
  insets["bottom"] = safeAreaInsets.bottom
241
+ // left/right: safe area for landscape / display cutouts
236
242
  insets["left"] = safeAreaInsets.left
237
243
  insets["right"] = safeAreaInsets.right
238
244
 
239
- print("StatusBar: getSafeAreaInsets - top=\(safeAreaInsets.top), bottom=\(safeAreaInsets.bottom), left=\(safeAreaInsets.left), right=\(safeAreaInsets.right)")
245
+ print("StatusBar: getSafeAreaInsets - top=\(statusBarHeight), bottom=\(safeAreaInsets.bottom), left=\(safeAreaInsets.left), right=\(safeAreaInsets.right)")
240
246
  } else {
241
247
  print("StatusBar: getSafeAreaInsets - Unable to get window, returning zero insets")
242
248
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capacitor-plugin-status-bar",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "Capacitor plugin for managing the status bar style, visibility, and color on iOS and Android. Control overlay modes, background colors, and appearance for native mobile applications.",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",