@capgo/capacitor-inappbrowser 8.19.0 → 8.20.1
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 +117 -4
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/CapgoInAppBrowserPlugin.java +63 -3
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/FullscreenWindowState.java +72 -0
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/Options.java +10 -0
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewDialog.java +271 -21
- package/android/src/main/res/drawable/ic_fullscreen_exit.xml +10 -0
- package/android/src/main/res/layout/fullscreen_exit_button.xml +24 -0
- package/android/src/main/res/values/fullscreen_exit.xml +10 -0
- package/android/src/main/res/values/strings.xml +1 -0
- package/android/src/main/res/xml/fullscreen_exit_shape.xml +6 -0
- package/dist/docs.json +95 -0
- package/dist/esm/definitions.d.ts +59 -0
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +9 -0
- package/dist/esm/web.js +11 -0
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +11 -0
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +11 -0
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/InAppBrowserPlugin/BrowserFullscreenSupport.swift +178 -0
- package/ios/Sources/InAppBrowserPlugin/InAppBrowserPlugin.swift +83 -4
- package/ios/Sources/InAppBrowserPlugin/WKWebViewController.swift +36 -6
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -217,7 +217,7 @@ All CCT options are Android-only and safely ignored on iOS. See [`OpenOptions`](
|
|
|
217
217
|
|
|
218
218
|
### Open WebView with Custom Dimensions
|
|
219
219
|
|
|
220
|
-
By default, the
|
|
220
|
+
By default, the WebView fills the available screen and retains its configured toolbar. You can set custom dimensions to control the size and position:
|
|
221
221
|
|
|
222
222
|
```js
|
|
223
223
|
import { InAppBrowser } from '@capgo/capacitor-inappbrowser';
|
|
@@ -259,9 +259,44 @@ InAppBrowser.openWebView({
|
|
|
259
259
|
|
|
260
260
|
Web platform is not supported. Use `window.open` instead.
|
|
261
261
|
|
|
262
|
-
###
|
|
262
|
+
### Fullscreen at launch and during a session
|
|
263
263
|
|
|
264
|
-
|
|
264
|
+
Set `fullscreen: true` to present a native WebView in fullscreen from its first visible frame:
|
|
265
|
+
|
|
266
|
+
```ts
|
|
267
|
+
import { InAppBrowser, ToolBarType } from '@capgo/capacitor-inappbrowser';
|
|
268
|
+
|
|
269
|
+
const listener = await InAppBrowser.addListener('fullscreenChange', ({ id, enabled }) => {
|
|
270
|
+
console.log('Fullscreen changed', id, enabled);
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
const { id } = await InAppBrowser.openWebView({
|
|
274
|
+
url: 'https://example.com',
|
|
275
|
+
toolbarType: ToolBarType.NAVIGATION,
|
|
276
|
+
fullscreen: true,
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
await InAppBrowser.setFullscreen({ id, enabled: false });
|
|
280
|
+
await InAppBrowser.setFullscreen({ id, enabled: true });
|
|
281
|
+
const { enabled } = await InAppBrowser.getFullscreen({ id });
|
|
282
|
+
|
|
283
|
+
// When the host no longer needs updates:
|
|
284
|
+
await listener.remove();
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Fullscreen hides native navigation and system bars. A native exit button stays above the page at the top-right safe-area inset. Android Back exits fullscreen before navigating page history. Exiting restores the configured toolbar and safe-area settings. Entry and exit keep the same WebView, including its JavaScript state, cookies, and history.
|
|
288
|
+
|
|
289
|
+
The opening option defaults to `false`. It also works with `isPresentAfterPageLoad: true` and `hidden: true`. An initially hidden WebView applies fullscreen when first shown; until then, `getFullscreen()` reports `false` and the host's system bars stay unchanged. Calling `setFullscreen({ id, enabled: false })` cancels that pending startup request.
|
|
290
|
+
|
|
291
|
+
Backgrounding, hiding, closing, cross-origin navigation, and renderer termination exit fullscreen through native cleanup. Showing or resuming the WebView afterward does not enter fullscreen again. The host receives a `fullscreenChange` event for each applied change, including native exit controls. Register the listener before opening to observe initial entry.
|
|
292
|
+
|
|
293
|
+
These APIs control the browser's presentation independently of HTML/video fullscreen. They support full-size, frontmost `openWebView` presentations on iOS and Android. Runtime entry into a hidden WebView, custom dimensions, behind-host presentations, and missing target IDs reject. Web usage is unsupported. Permission prompts are the host application's responsibility.
|
|
294
|
+
|
|
295
|
+
The example app's Fullscreen section includes launch options and an interactive page for runtime entry, exit, hide/show, history, form, cookie, and counter checks.
|
|
296
|
+
|
|
297
|
+
### Extend content behind the status bar
|
|
298
|
+
|
|
299
|
+
To extend content behind the status bar, set `enabledSafeTopMargin` to `false`:
|
|
265
300
|
|
|
266
301
|
```js
|
|
267
302
|
import { InAppBrowser } from '@capgo/capacitor-inappbrowser';
|
|
@@ -277,7 +312,7 @@ This option works independently of the toolbar type:
|
|
|
277
312
|
- **iOS**: The webview extends behind the status bar, providing true edge-to-edge content
|
|
278
313
|
- **Android**: The top margin is disabled, allowing content to fill the entire screen
|
|
279
314
|
|
|
280
|
-
|
|
315
|
+
This setting controls the content inset. Use `fullscreen` to hide native navigation and system bars as well.
|
|
281
316
|
|
|
282
317
|
### Proxy examples
|
|
283
318
|
|
|
@@ -632,6 +667,7 @@ await InAppBrowser.openWebView({
|
|
|
632
667
|
* [`takeScreenshot(...)`](#takescreenshot)
|
|
633
668
|
* [`setUrl(...)`](#seturl)
|
|
634
669
|
* [`addListener('urlChangeEvent', ...)`](#addlistenerurlchangeevent-)
|
|
670
|
+
* [`addListener('fullscreenChange', ...)`](#addlistenerfullscreenchange-)
|
|
635
671
|
* [`addListener('buttonNearDoneClick', ...)`](#addlistenerbuttonneardoneclick-)
|
|
636
672
|
* [`addListener('closeEvent', ...)`](#addlistenercloseevent-)
|
|
637
673
|
* [`addListener('hideEvent', ...)`](#addlistenerhideevent-)
|
|
@@ -652,6 +688,8 @@ await InAppBrowser.openWebView({
|
|
|
652
688
|
* [`removeAllListeners()`](#removealllisteners)
|
|
653
689
|
* [`reload(...)`](#reload)
|
|
654
690
|
* [`updateDimensions(...)`](#updatedimensions)
|
|
691
|
+
* [`setFullscreen(...)`](#setfullscreen)
|
|
692
|
+
* [`getFullscreen(...)`](#getfullscreen)
|
|
655
693
|
* [`setEnabledSafeTopMargin(...)`](#setenabledsafetopmargin)
|
|
656
694
|
* [`setEnabledSafeBottomMargin(...)`](#setenabledsafebottommargin)
|
|
657
695
|
* [`openSecureWindow(...)`](#opensecurewindow)
|
|
@@ -1029,6 +1067,27 @@ Listen for url change, only for openWebView
|
|
|
1029
1067
|
--------------------
|
|
1030
1068
|
|
|
1031
1069
|
|
|
1070
|
+
### addListener('fullscreenChange', ...)
|
|
1071
|
+
|
|
1072
|
+
```typescript
|
|
1073
|
+
addListener(eventName: 'fullscreenChange', listenerFunc: (event: FullscreenChangeEvent) => void) => Promise<PluginListenerHandle>
|
|
1074
|
+
```
|
|
1075
|
+
|
|
1076
|
+
Listen for applied fullscreen changes, including startup entry, the native exit button,
|
|
1077
|
+
Android Back, and native lifecycle cleanup. Register before opening to observe startup entry.
|
|
1078
|
+
Repeated requests for the current state do not emit duplicate events.
|
|
1079
|
+
This event describes host-controlled fullscreen, not HTML/video fullscreen.
|
|
1080
|
+
|
|
1081
|
+
| Param | Type |
|
|
1082
|
+
| ------------------ | ------------------------------------------------------------------------------------------- |
|
|
1083
|
+
| **`eventName`** | <code>'fullscreenChange'</code> |
|
|
1084
|
+
| **`listenerFunc`** | <code>(event: <a href="#fullscreenchangeevent">FullscreenChangeEvent</a>) => void</code> |
|
|
1085
|
+
|
|
1086
|
+
**Returns:** <code>Promise<<a href="#pluginlistenerhandle">PluginListenerHandle</a>></code>
|
|
1087
|
+
|
|
1088
|
+
--------------------
|
|
1089
|
+
|
|
1090
|
+
|
|
1032
1091
|
### addListener('buttonNearDoneClick', ...)
|
|
1033
1092
|
|
|
1034
1093
|
```typescript
|
|
@@ -1425,6 +1484,49 @@ When `id` is omitted, targets the active webview.
|
|
|
1425
1484
|
--------------------
|
|
1426
1485
|
|
|
1427
1486
|
|
|
1487
|
+
### setFullscreen(...)
|
|
1488
|
+
|
|
1489
|
+
```typescript
|
|
1490
|
+
setFullscreen(options: { enabled: boolean; id?: string; }) => Promise<void>
|
|
1491
|
+
```
|
|
1492
|
+
|
|
1493
|
+
Enter or exit immersive fullscreen without recreating or reloading the webview.
|
|
1494
|
+
When `id` is omitted, targets the active webview. Repeated calls are idempotent.
|
|
1495
|
+
Entry requires a visible, frontmost, full-size `openWebView` on iOS or Android.
|
|
1496
|
+
Missing webviews, invalid arguments, custom dimensions, behind-host presentations,
|
|
1497
|
+
and the Web platform reject. Use the opening `fullscreen` option for an initially hidden webview.
|
|
1498
|
+
Disabling also cancels any pending fullscreen-at-launch request.
|
|
1499
|
+
|
|
1500
|
+
Native exit controls, backgrounding, hiding, closing, cross-origin navigation, and renderer
|
|
1501
|
+
termination restore the original chrome even when host JavaScript cannot respond.
|
|
1502
|
+
|
|
1503
|
+
| Param | Type |
|
|
1504
|
+
| ------------- | ----------------------------------------------- |
|
|
1505
|
+
| **`options`** | <code>{ enabled: boolean; id?: string; }</code> |
|
|
1506
|
+
|
|
1507
|
+
--------------------
|
|
1508
|
+
|
|
1509
|
+
|
|
1510
|
+
### getFullscreen(...)
|
|
1511
|
+
|
|
1512
|
+
```typescript
|
|
1513
|
+
getFullscreen(options?: { id?: string | undefined; } | undefined) => Promise<{ enabled: boolean; }>
|
|
1514
|
+
```
|
|
1515
|
+
|
|
1516
|
+
Read the applied host-controlled fullscreen state of an `openWebView`.
|
|
1517
|
+
When `id` is omitted, targets the active webview. Initially hidden fullscreen webviews
|
|
1518
|
+
report `false` until their first presentation. Missing webviews and Web usage reject.
|
|
1519
|
+
HTML/video fullscreen does not change this value.
|
|
1520
|
+
|
|
1521
|
+
| Param | Type |
|
|
1522
|
+
| ------------- | ----------------------------- |
|
|
1523
|
+
| **`options`** | <code>{ id?: string; }</code> |
|
|
1524
|
+
|
|
1525
|
+
**Returns:** <code>Promise<{ enabled: boolean; }></code>
|
|
1526
|
+
|
|
1527
|
+
--------------------
|
|
1528
|
+
|
|
1529
|
+
|
|
1428
1530
|
### setEnabledSafeTopMargin(...)
|
|
1429
1531
|
|
|
1430
1532
|
```typescript
|
|
@@ -1574,6 +1676,7 @@ See the README section "openSecureWindow (OAuth)" for full setup examples.
|
|
|
1574
1676
|
|
|
1575
1677
|
| Prop | Type | Description | Default | Since |
|
|
1576
1678
|
| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | ------ |
|
|
1679
|
+
| **`fullscreen`** | <code>boolean</code> | Present this webview in immersive fullscreen from its first visible frame. Hides native navigation and system bars and provides a native exit-fullscreen button. The same webview, page state, cookies, and history are retained on entry and exit. Exiting restores the configured toolbar and safe-area settings. Applies before presentation, including when `isPresentAfterPageLoad` is true. With `hidden: true`, waits for the first `show()` without changing the host's system bars. Subsequent hide/show or background/resume cycles do not re-enter fullscreen automatically. Only supported on iOS and Android for full-size, frontmost `openWebView` presentations. Custom dimensions and `toBack: true` are unsupported. The Web implementation rejects `true`. Permission prompts, if needed, are the host application's responsibility. | <code>false</code> | |
|
|
1577
1680
|
| **`url`** | <code>string</code> | Target URL to load. Remote `http://` and `https://` URLs are loaded as-is. To open bundled web assets from the app bundle without running a local HTTP server, pass a relative path such as `/index.html` or `assets/page.html`. The plugin resolves it to the Capacitor local URL for the current platform (defaults: `capacitor://localhost/...` on iOS, `https://localhost/...` on Android; actual scheme and host follow the app's configured Capacitor local URL) and serves files from the packaged `public/` directory, or `www/` on iOS when `public/` is absent. | | 0.1.0 |
|
|
1578
1681
|
| **`headers`** | <code><a href="#headers">Headers</a></code> | <a href="#headers">Headers</a> to send with the request. | | 0.1.0 |
|
|
1579
1682
|
| **`customUserAgent`** | <code>string</code> | Custom User-Agent string for the webview. When set, replaces the system default webview User-Agent on iOS and Android. Takes precedence over a `User-Agent` entry in `headers`. | | 8.13.0 |
|
|
@@ -1726,6 +1829,16 @@ Any regex property that is omitted is treated as a wildcard.
|
|
|
1726
1829
|
| **`url`** | <code>string</code> | Emit when the url changes | 0.0.1 |
|
|
1727
1830
|
|
|
1728
1831
|
|
|
1832
|
+
#### FullscreenChangeEvent
|
|
1833
|
+
|
|
1834
|
+
A change to host-controlled fullscreen; independent of HTML/video fullscreen.
|
|
1835
|
+
|
|
1836
|
+
| Prop | Type | Description |
|
|
1837
|
+
| ------------- | -------------------- | --------------------------------------------------------------- |
|
|
1838
|
+
| **`id`** | <code>string</code> | Webview instance id. |
|
|
1839
|
+
| **`enabled`** | <code>boolean</code> | Whether fullscreen is currently applied to the visible webview. |
|
|
1840
|
+
|
|
1841
|
+
|
|
1729
1842
|
#### ButtonNearDoneEvent
|
|
1730
1843
|
|
|
1731
1844
|
| Prop | Type | Description | Since |
|
|
@@ -339,6 +339,7 @@ public class CapgoInAppBrowserPlugin extends Plugin implements WebViewDialog.Per
|
|
|
339
339
|
}
|
|
340
340
|
|
|
341
341
|
private WebViewDialog createManagedDialog(String webViewId, Options options, boolean makeActive) {
|
|
342
|
+
if (fullscreenPaused) options.setFullscreen(false);
|
|
342
343
|
WebViewDialog dialog = new WebViewDialog(
|
|
343
344
|
getContext(),
|
|
344
345
|
android.R.style.Theme_NoTitleBar,
|
|
@@ -346,6 +347,12 @@ public class CapgoInAppBrowserPlugin extends Plugin implements WebViewDialog.Per
|
|
|
346
347
|
CapgoInAppBrowserPlugin.this,
|
|
347
348
|
getBridge().getWebView()
|
|
348
349
|
);
|
|
350
|
+
dialog.setFullscreenChangeListener((enabled) -> {
|
|
351
|
+
JSObject event = new JSObject();
|
|
352
|
+
event.put("id", webViewId);
|
|
353
|
+
event.put("enabled", enabled);
|
|
354
|
+
notifyListeners("fullscreenChange", event);
|
|
355
|
+
});
|
|
349
356
|
dialog.setInstanceId(webViewId);
|
|
350
357
|
dialog.activity = CapgoInAppBrowserPlugin.this.getActivity();
|
|
351
358
|
dialog.bindToHostActivity();
|
|
@@ -1367,9 +1374,14 @@ public class CapgoInAppBrowserPlugin extends Plugin implements WebViewDialog.Per
|
|
|
1367
1374
|
options.setY(y);
|
|
1368
1375
|
}
|
|
1369
1376
|
|
|
1377
|
+
options.setFullscreen(Boolean.TRUE.equals(call.getBoolean("fullscreen", false)));
|
|
1370
1378
|
options.setHidden(Boolean.TRUE.equals(call.getBoolean("hidden", false)));
|
|
1371
1379
|
options.setToBack(Boolean.TRUE.equals(call.getBoolean("toBack", false)));
|
|
1372
1380
|
options.setTransparentBackground(call.getBoolean("transparentBackground", true));
|
|
1381
|
+
if (options.isFullscreen() && (options.isToBack() || width != null || height != null || x != null || y != null)) {
|
|
1382
|
+
call.reject("Fullscreen requires a full-size front WebView");
|
|
1383
|
+
return;
|
|
1384
|
+
}
|
|
1373
1385
|
boolean allowWebViewJsVisibilityControl = getConfig().getBoolean("allowWebViewJsVisibilityControl", false);
|
|
1374
1386
|
options.setAllowWebViewJsVisibilityControl(allowWebViewJsVisibilityControl);
|
|
1375
1387
|
options.setInvisibilityMode(Options.InvisibilityMode.fromString(call.getString("invisibilityMode", "AWARE")));
|
|
@@ -1460,6 +1472,50 @@ public class CapgoInAppBrowserPlugin extends Plugin implements WebViewDialog.Per
|
|
|
1460
1472
|
);
|
|
1461
1473
|
}
|
|
1462
1474
|
|
|
1475
|
+
private boolean fullscreenPaused;
|
|
1476
|
+
|
|
1477
|
+
@PluginMethod
|
|
1478
|
+
public void setFullscreen(PluginCall call) {
|
|
1479
|
+
Object enabled = call.getData().opt("enabled");
|
|
1480
|
+
if (!(enabled instanceof Boolean)) {
|
|
1481
|
+
call.reject("enabled must be a boolean");
|
|
1482
|
+
return;
|
|
1483
|
+
}
|
|
1484
|
+
String id = resolveTargetId(call);
|
|
1485
|
+
getActivity().runOnUiThread(() -> {
|
|
1486
|
+
WebViewDialog dialog = resolveDialog(id);
|
|
1487
|
+
if (dialog == null) {
|
|
1488
|
+
call.reject("WebView is not initialized");
|
|
1489
|
+
return;
|
|
1490
|
+
}
|
|
1491
|
+
if ((Boolean) enabled && (!dialog.isShowing() || fullscreenPaused)) {
|
|
1492
|
+
call.reject("Application is in background");
|
|
1493
|
+
return;
|
|
1494
|
+
}
|
|
1495
|
+
try {
|
|
1496
|
+
dialog.setFullscreen((Boolean) enabled);
|
|
1497
|
+
call.resolve();
|
|
1498
|
+
} catch (IllegalStateException error) {
|
|
1499
|
+
call.reject(error.getMessage());
|
|
1500
|
+
}
|
|
1501
|
+
});
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
@PluginMethod
|
|
1505
|
+
public void getFullscreen(PluginCall call) {
|
|
1506
|
+
String id = resolveTargetId(call);
|
|
1507
|
+
getActivity().runOnUiThread(() -> {
|
|
1508
|
+
WebViewDialog dialog = resolveDialog(id);
|
|
1509
|
+
if (dialog == null) {
|
|
1510
|
+
call.reject("WebView is not initialized");
|
|
1511
|
+
return;
|
|
1512
|
+
}
|
|
1513
|
+
JSObject result = new JSObject();
|
|
1514
|
+
result.put("enabled", dialog.isFullscreen());
|
|
1515
|
+
call.resolve(result);
|
|
1516
|
+
});
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1463
1519
|
@PluginMethod
|
|
1464
1520
|
public void hide(PluginCall call) {
|
|
1465
1521
|
String targetId = resolveTargetId(call);
|
|
@@ -1478,6 +1534,7 @@ public class CapgoInAppBrowserPlugin extends Plugin implements WebViewDialog.Per
|
|
|
1478
1534
|
call.reject("WebView is not initialized");
|
|
1479
1535
|
return;
|
|
1480
1536
|
}
|
|
1537
|
+
dialog.clearFullscreen();
|
|
1481
1538
|
dialog.setHidden(true);
|
|
1482
1539
|
call.resolve();
|
|
1483
1540
|
}
|
|
@@ -1503,6 +1560,9 @@ public class CapgoInAppBrowserPlugin extends Plugin implements WebViewDialog.Per
|
|
|
1503
1560
|
call.reject("WebView is not initialized");
|
|
1504
1561
|
return;
|
|
1505
1562
|
}
|
|
1563
|
+
if (dialog.getInstanceId() != null) {
|
|
1564
|
+
setActiveWebView(dialog.getInstanceId(), dialog);
|
|
1565
|
+
}
|
|
1506
1566
|
dialog.setHidden(false);
|
|
1507
1567
|
Options options = dialog.getOptions();
|
|
1508
1568
|
if (options != null && options.isToBack()) {
|
|
@@ -1513,9 +1573,6 @@ public class CapgoInAppBrowserPlugin extends Plugin implements WebViewDialog.Per
|
|
|
1513
1573
|
} else {
|
|
1514
1574
|
dialog.bringToFrontLayer();
|
|
1515
1575
|
}
|
|
1516
|
-
if (dialog.getInstanceId() != null) {
|
|
1517
|
-
setActiveWebView(dialog.getInstanceId(), dialog);
|
|
1518
|
-
}
|
|
1519
1576
|
call.resolve();
|
|
1520
1577
|
}
|
|
1521
1578
|
}
|
|
@@ -1898,6 +1955,7 @@ public class CapgoInAppBrowserPlugin extends Plugin implements WebViewDialog.Per
|
|
|
1898
1955
|
}
|
|
1899
1956
|
|
|
1900
1957
|
protected void handleOnResume() {
|
|
1958
|
+
fullscreenPaused = false;
|
|
1901
1959
|
customTabsLifecycleSupport.onResume(customTabsBinder);
|
|
1902
1960
|
|
|
1903
1961
|
// If we have a saved call and user returned without callback, reject
|
|
@@ -1908,6 +1966,8 @@ public class CapgoInAppBrowserPlugin extends Plugin implements WebViewDialog.Per
|
|
|
1908
1966
|
}
|
|
1909
1967
|
|
|
1910
1968
|
protected void handleOnPause() {
|
|
1969
|
+
fullscreenPaused = true;
|
|
1970
|
+
for (WebViewDialog dialog : webViewDialogs.values()) dialog.clearFullscreen();
|
|
1911
1971
|
customTabsLifecycleSupport.onPause(customTabsBinder);
|
|
1912
1972
|
}
|
|
1913
1973
|
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
package ee.forgr.capacitor_inappbrowser;
|
|
2
|
+
|
|
3
|
+
import android.os.Build;
|
|
4
|
+
import android.view.View;
|
|
5
|
+
import android.view.Window;
|
|
6
|
+
import android.view.WindowManager;
|
|
7
|
+
import androidx.core.view.ViewCompat;
|
|
8
|
+
import androidx.core.view.WindowInsetsCompat;
|
|
9
|
+
import androidx.core.view.WindowInsetsControllerCompat;
|
|
10
|
+
|
|
11
|
+
/** Saves each nesting level so media fullscreen can return to browser fullscreen. */
|
|
12
|
+
final class FullscreenWindowState {
|
|
13
|
+
|
|
14
|
+
private final Window window;
|
|
15
|
+
private final WindowManager.LayoutParams attributes = new WindowManager.LayoutParams();
|
|
16
|
+
private final int visibility;
|
|
17
|
+
private final int behavior;
|
|
18
|
+
private final boolean statusVisible;
|
|
19
|
+
private final boolean navigationVisible;
|
|
20
|
+
|
|
21
|
+
FullscreenWindowState(Window window) {
|
|
22
|
+
this.window = window;
|
|
23
|
+
attributes.copyFrom(window.getAttributes());
|
|
24
|
+
View decor = window.getDecorView();
|
|
25
|
+
visibility = decor.getSystemUiVisibility();
|
|
26
|
+
WindowInsetsControllerCompat controller = new WindowInsetsControllerCompat(window, decor);
|
|
27
|
+
behavior = controller.getSystemBarsBehavior();
|
|
28
|
+
WindowInsetsCompat insets = ViewCompat.getRootWindowInsets(decor);
|
|
29
|
+
statusVisible =
|
|
30
|
+
insets != null
|
|
31
|
+
? insets.isVisible(WindowInsetsCompat.Type.statusBars())
|
|
32
|
+
: (attributes.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) == 0;
|
|
33
|
+
navigationVisible =
|
|
34
|
+
insets != null
|
|
35
|
+
? insets.isVisible(WindowInsetsCompat.Type.navigationBars())
|
|
36
|
+
: (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
void enter() {
|
|
40
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
|
41
|
+
// DEFAULT excludes the cutout once bars hide, leaving a black band in immersive mode.
|
|
42
|
+
WindowManager.LayoutParams fullscreenAttributes = window.getAttributes();
|
|
43
|
+
fullscreenAttributes.layoutInDisplayCutoutMode =
|
|
44
|
+
Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
|
|
45
|
+
? WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
|
|
46
|
+
: WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
|
|
47
|
+
window.setAttributes(fullscreenAttributes);
|
|
48
|
+
}
|
|
49
|
+
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
|
50
|
+
View decor = window.getDecorView();
|
|
51
|
+
decor.setSystemUiVisibility(
|
|
52
|
+
decor.getSystemUiVisibility() |
|
|
53
|
+
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
|
|
54
|
+
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
|
|
55
|
+
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
|
56
|
+
);
|
|
57
|
+
WindowInsetsControllerCompat controller = new WindowInsetsControllerCompat(window, decor);
|
|
58
|
+
controller.setSystemBarsBehavior(WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
|
|
59
|
+
controller.hide(WindowInsetsCompat.Type.systemBars());
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
void restore() {
|
|
63
|
+
WindowInsetsControllerCompat controller = new WindowInsetsControllerCompat(window, window.getDecorView());
|
|
64
|
+
if (statusVisible) controller.show(WindowInsetsCompat.Type.statusBars());
|
|
65
|
+
else controller.hide(WindowInsetsCompat.Type.statusBars());
|
|
66
|
+
if (navigationVisible) controller.show(WindowInsetsCompat.Type.navigationBars());
|
|
67
|
+
else controller.hide(WindowInsetsCompat.Type.navigationBars());
|
|
68
|
+
controller.setSystemBarsBehavior(behavior);
|
|
69
|
+
window.setAttributes(attributes);
|
|
70
|
+
window.getDecorView().setSystemUiVisibility(visibility);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -198,6 +198,16 @@ public class Options {
|
|
|
198
198
|
private boolean hidden = false;
|
|
199
199
|
private boolean toBack = false;
|
|
200
200
|
private boolean transparentBackground = true;
|
|
201
|
+
private boolean fullscreen = false;
|
|
202
|
+
|
|
203
|
+
public boolean isFullscreen() {
|
|
204
|
+
return fullscreen;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
public void setFullscreen(boolean fullscreen) {
|
|
208
|
+
this.fullscreen = fullscreen;
|
|
209
|
+
}
|
|
210
|
+
|
|
201
211
|
private boolean showScreenshotButton = false;
|
|
202
212
|
private boolean screenshotOnHide = false;
|
|
203
213
|
private boolean allowWebViewJsVisibilityControl = false;
|