fix(mobile): count the iOS safe areas once

The WKWebView's scroll view inset its content by the safe areas, and the
page, laid out with viewport-fit=cover, padded by env(safe-area-inset-*)
as well. The viewport came out 778pt tall on an 874pt screen: everything
sat a status bar's height too low, with a blank band under it. The scroll
view's automatic inset adjustment is now off, so the page runs edge to
edge and its CSS alone keeps clear of the status bar and home indicator.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
l0ng-ai
2026-09-28 21:55:50 +08:00
co-authored by Claude
parent ef832f34b0
commit f98cd0f70b
3 changed files with 31 additions and 0 deletions
+1
View File
@@ -5469,6 +5469,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"iroh",
"objc2",
"rustls",
"serde",
"serde_json",
+4
View File
@@ -34,3 +34,7 @@ tokio = { version = "1", features = ["sync", "time", "macros"] }
[target.'cfg(any(target_os = "android", target_os = "ios"))'.dependencies]
tauri-plugin-barcode-scanner = "2"
# Setting one WKWebView property the Tauri API does not reach (`edge_to_edge`).
[target.'cfg(target_os = "ios")'.dependencies]
objc2 = "0.6"
+26
View File
@@ -405,6 +405,10 @@ pub fn run() {
builder
.setup(|app| {
#[cfg(target_os = "ios")]
if let Some(window) = app.get_webview_window("main") {
edge_to_edge(&window);
}
let dir = app.path().app_data_dir()?;
app.manage(Arc::new(AppState {
dir,
@@ -423,3 +427,25 @@ pub fn run() {
.run(tauri::generate_context!())
.expect("error while running tty7");
}
/// Lets the page run under the status bar and the home indicator, and leaves
/// the safe areas to it (`viewport-fit=cover` and `env(safe-area-inset-*)` in
/// the CSS). By default the WKWebView's scroll view insets its content by the
/// safe areas as well, so each was counted twice: the page sat a status bar's
/// height too low, with a blank band under it.
#[cfg(target_os = "ios")]
fn edge_to_edge(window: &tauri::WebviewWindow) {
use objc2::msg_send;
use objc2::runtime::AnyObject;
/// `UIScrollViewContentInsetAdjustmentBehavior.never`.
const NEVER: isize = 2;
let _ = window.with_webview(|webview| unsafe {
let Some(wk) = (webview.inner() as *const AnyObject).as_ref() else {
return;
};
let scroll: *const AnyObject = msg_send![wk, scrollView];
if let Some(scroll) = scroll.as_ref() {
let _: () = msg_send![scroll, setContentInsetAdjustmentBehavior: NEVER];
}
});
}