Skip to content

Commit a3e913c

Browse files
committed
feat: iOS support — edge-to-edge WKWebView, mobile defaults, safe areas (v1.4.0)
- Native WKWebView fix: contentInsetAdjustmentBehavior=never, edgesForExtendedLayout=all via Rust objc2 FFI - Mobile defaults to Chat mode on fresh install (≤768px) - CSS safe area padding for notch/home indicator - Borderless full-bleed shell frame on mobile - devUrl corrected to port 3000 (Next.js dev server) - Added objc2 v0.6.4 direct dependency - Desktop-only crates gated for iOS conditional compilation
1 parent 460ce36 commit a3e913c

10 files changed

Lines changed: 71 additions & 30 deletions

File tree

CHANGELOG.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
11
# Changelog
22

3+
## [1.4.0] — 2026-03-07
4+
5+
### Added
6+
7+
- **iOS support** — Tauri iOS builds for iPhone simulator (arm64)
8+
- **Edge-to-edge display** — Native WKWebView configuration via Rust objc2 FFI (`contentInsetAdjustmentBehavior = .never`, `edgesForExtendedLayout = .all`)
9+
- **Mobile-first defaults** — Fresh installs on small screens default to Chat mode instead of Classic/Editor
10+
- **CSS safe area handling** — Content respects notch and home indicator via `env(safe-area-inset-*)`
11+
- **Mobile layout** — Borderless, full-bleed shell frame on screens ≤768px
12+
- **Mobile features** — QR connect, agent approval cards, session presence, caffeinate toggle
13+
- **Settings panel** — Redesigned with Connect + General tabs, device list, QR code
14+
15+
### Fixed
16+
17+
- **iOS bottom gap** — WKWebView no longer constrained to safe area bounds
18+
- **Dev mode URL**`devUrl` corrected to Next.js dev server port (3000)
19+
20+
### Changed
21+
22+
- Added `objc2` v0.6.4 as direct Cargo dependency for iOS native interop
23+
- iOS capabilities separated from desktop (`capabilities/mobile.json`)
24+
- Desktop-only crates (`portable-pty`, `window-vibrancy`, `keyring`, etc.) gated with `#[cfg(not(target_os = "ios"))]`
25+
326
## [1.1.0] — 2026-03-05
427

528
### Added

app/globals.css

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,22 +1067,14 @@ body {
10671067
-webkit-backdrop-filter: blur(20px) saturate(135%);
10681068
}
10691069

1070-
/* iOS: fill entire viewport including behind safe areas.
1071-
html background covers the home indicator region;
1072-
app-shell pads content away from notch/indicator. */
1073-
@supports (padding-bottom: env(safe-area-inset-bottom)) {
1074-
html,
1075-
body {
1076-
min-height: 100vh;
1077-
min-height: -webkit-fill-available;
1078-
}
1070+
/* Mobile edge-to-edge: safe-area padding keeps content clear of
1071+
notch/home indicator while the native WebView fills the screen. */
1072+
@media (max-width: 768px) {
10791073
.app-shell {
1080-
min-height: 100vh;
1081-
min-height: -webkit-fill-available;
1082-
padding-top: env(safe-area-inset-top);
1083-
padding-bottom: env(safe-area-inset-bottom);
1084-
padding-left: env(safe-area-inset-left);
1085-
padding-right: env(safe-area-inset-right);
1074+
padding-top: env(safe-area-inset-top, 0px);
1075+
padding-bottom: env(safe-area-inset-bottom, 0px);
1076+
padding-left: env(safe-area-inset-left, 0px);
1077+
padding-right: env(safe-area-inset-right, 0px);
10861078
}
10871079
}
10881080

context/app-mode-context.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,16 @@ export function AppModeProvider({ children }: { children: ReactNode }) {
3636
activeViewRef.current = activeView
3737
}, [activeView])
3838

39-
// Hydrate from localStorage after mount to avoid SSR mismatch
39+
// Hydrate from localStorage after mount to avoid SSR mismatch.
40+
// On mobile (no saved preference), default to chat mode.
4041
useEffect(() => {
4142
try {
4243
const raw = localStorage.getItem(STORAGE_KEY) as AppMode | null
43-
if (raw && raw in MODE_REGISTRY) setModeState(raw)
44+
if (raw && raw in MODE_REGISTRY) {
45+
setModeState(raw)
46+
} else if (window.innerWidth <= 768) {
47+
setModeState('chat')
48+
}
4449
} catch {}
4550
}, [])
4651

next-env.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/// <reference types="next" />
22
/// <reference types="next/image-types/global" />
3-
import "./.next/types/routes.d.ts";
3+
import "./.next/dev/types/routes.d.ts";
44

55
// NOTE: This file should not be edited
66
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "code-editor",
3-
"version": "1.3.0",
3+
"version": "1.4.0",
44
"private": true,
55
"scripts": {
66
"frontend:dev": "next dev --turbopack",

src-tauri/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-tauri/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ base64 = "0.22.1"
2727
tauri-plugin-dialog = "2.6.0"
2828
tauri-plugin-clipboard-manager = "2.3.2"
2929
tauri-plugin-localhost = "2"
30+
objc2 = "0.6.4"
3031

3132
# Desktop-only dependencies
3233
[target.'cfg(not(target_os = "ios"))'.dependencies]

src-tauri/gen/apple/project.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ targets:
5151
- UIInterfaceOrientationPortraitUpsideDown
5252
- UIInterfaceOrientationLandscapeLeft
5353
- UIInterfaceOrientationLandscapeRight
54-
CFBundleShortVersionString: 1.3.0
55-
CFBundleVersion: "1.3.0"
54+
CFBundleShortVersionString: 1.4.0
55+
CFBundleVersion: "1.4.0"
5656
entitlements:
5757
path: app_iOS/app_iOS.entitlements
5858
scheme:

src-tauri/src/lib.rs

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -84,18 +84,37 @@ pub fn run() {
8484
setup_desktop_menu(app)?;
8585
}
8686

87-
// iOS: extend WebView edge-to-edge behind safe areas
87+
// iOS: make WKWebView fill the entire screen edge-to-edge
8888
#[cfg(target_os = "ios")]
8989
{
9090
use tauri::Manager;
9191
if let Some(ww) = app.get_webview_window("main") {
92-
let _ = ww.with_webview(|wv| {
93-
#[allow(deprecated)]
92+
let _ = ww.with_webview(move |wv| {
9493
unsafe {
95-
let inner = wv.inner();
96-
let sv: *mut std::ffi::c_void = objc2::msg_send![inner, scrollView];
97-
// UIScrollViewContentInsetAdjustmentNever = 2
98-
let _: () = objc2::msg_send![sv as *mut objc2::runtime::AnyObject, setContentInsetAdjustmentBehavior: 2_isize];
94+
let wk_ptr = wv.inner() as *mut objc2::runtime::AnyObject;
95+
// Get the scrollView from WKWebView
96+
let scroll_view: *mut objc2::runtime::AnyObject =
97+
objc2::msg_send![wk_ptr, scrollView];
98+
// contentInsetAdjustmentBehavior = .never (2)
99+
let _: () = objc2::msg_send![
100+
scroll_view,
101+
setContentInsetAdjustmentBehavior: 2_isize
102+
];
103+
104+
// Also configure the view controller to extend layout under all bars
105+
let vc_ptr = wv.view_controller() as *mut objc2::runtime::AnyObject;
106+
if !vc_ptr.is_null() {
107+
// edgesForExtendedLayout = UIRectEdgeAll (15)
108+
let _: () = objc2::msg_send![
109+
vc_ptr,
110+
setEdgesForExtendedLayout: 15_usize
111+
];
112+
// extendedLayoutIncludesOpaqueBars = YES
113+
let _: () = objc2::msg_send![
114+
vc_ptr,
115+
setExtendedLayoutIncludesOpaqueBars: true
116+
];
117+
}
99118
}
100119
});
101120
}

src-tauri/tauri.conf.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
{
22
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
33
"productName": "KnotCode",
4-
"version": "1.3.0",
4+
"version": "1.4.0",
55
"identifier": "ai.openknot.code-editor",
66
"build": {
77
"frontendDist": "../out",
8-
"devUrl": "http://127.0.0.1:3080",
8+
"devUrl": "http://127.0.0.1:3000",
99
"beforeDevCommand": "pnpm frontend:dev",
1010
"beforeBuildCommand": "pnpm frontend:build"
1111
},

0 commit comments

Comments
 (0)