Commit graph

25 commits

Author SHA1 Message Date
Darkatse
d04aed71c7 fix(drawers): drop the scrollbar-hiding animation on open
hide-scroll held overflow-y: hidden for the length of the open
animation, so a drawer whose content overflows gained its scrollbar only
afterwards and its content narrowed by the scrollbar width and rewrapped
(864 to 847 px in User Settings).

It covered the scrollbar flashing while the height grew from zero. Since
drawers now lay out at their final size and reveal with clip-path, the
scrollbar is in place from the first frame and is revealed with the rest.
2026-10-06 22:14:13 -04:00
Darkatse
62571562e0 fix(drawers): reveal top-level drawers with clip-path
Drawers animated height from 0 to calc-size(auto, size). WebKit has no
calc-size(), so under allow-discrete the height switched at the halfway
point: a 12 px strip for 125 ms, then a jump to full height, and the
reverse on close. This affects macOS, iOS and Linux; upstream
SillyTavern has the same rule.

Top-level drawers now lay out at their final size and transition
clip-path from inset(0 0 100% 0) to inset(0), so opening and closing run
the full duration in every engine, whatever the content height or a
theme's max-height, without relayout per frame. Floating panels keep
upstream's height transition. The assistant drawer's size no longer
depends on openDrawer, so it holds while closing.
2026-10-06 22:02:05 -04:00
Darkatse
7837cc80d8 fix(android): resize the WebView once per keyboard transition
The host registered an insets animation callback and resized the WebView
on every onProgress frame, so each keyboard show or hide relaid out the
page 7-19 times and fell behind the finger (#330).

Android already dispatches the keyboard's target insets once when the
animation starts. Follow onApplyWindowInsets only and let the keyboard
slide over a settled page. Without a callback the platform also keeps
the layout unchanged while a predictive-back gesture drags the keyboard,
commits once on release, and leaves it untouched on cancel. Chromium
still scrolls a focused field into view after the single resize.

On an API 36 emulator every transition now takes one resize, and style
plus layout work drops from 20-75 ms to 3-7 ms on a 20-message chat.

The same rule now holds on all three platforms: iOS holds the WebView
height during the dismiss drag, and ArkWeb's RESIZE_CONTENT already
resizes once per docked transition.

Refs #330
2026-10-06 17:49:10 -04:00
Darkatse
9717e2fc9b feat(ios): dismiss the keyboard with a native drag
Hide WebKit's form accessory bar and let UIKit's interactive dismissal
own the gesture. A full-window KeyboardScrollView inside WindowHost is
the pan surface: it has no content, recognizes alongside WebKit's
overflow scroll views, never cancels page touches, and keeps a zero
content offset because an empty bounce makes WebKit recompute visible
geometry every frame. The WebView stays constrained to the host's safe
area and keyboard guides.

The accessory bar also caused the two-stage dismissal: keyboardLayoutGuide
tracks the union of bar and keyboard, and the bar leaves about 400 ms
after the keyboard. Without it the guide returns to the safe area in one
animation.

While the pan is active the WebView height is held. iOS WebKit treats
every view-height change as a stylesheet-environment change and rebuilds
all styles (WebPage::viewportConfigurationChanged ->
updateSizeForCSSDefaultViewportUnits -> didChangeStyleSheetEnvironment),
about 30 ms per step on an iPhone 13. Like Safari, the page relayouts
once when the keyboard settles while the keyboard itself follows the
finger.
2026-10-06 02:37:26 -04:00
Darkatse
4798cc600b feat(mobile): derive system bar icons from the window backdrop
Choose status and navigation bar icon brightness from the host
backdrop behind each bar: the strip's average color composited over
the backdrop color, or the color alone. The renderer reports each
strip's edge and premultiplied average, and each native owner
re-evaluates when the color or strips change.

- Android drops its per-frame PixelCopy sampler and defaults new
  installs to non-immersive; saved preferences are unchanged.
- iOS sets the style through TaoUIViewController's
  preferredStatusBarStyle.
- OpenHarmony sets status and three-button navigation colors in one
  partial system bar update.
2026-10-05 20:49:10 -04:00
Darkatse
2d446c9237 feat(ohos): adopt the native window layout contract
Bring OpenHarmony onto the contract Android and iOS already follow.
ArkUI lays the Web out in the safe area, ArkWeb's RESIZE_CONTENT
shrinks the layout viewport by the docked keyboard's overlap, and an
app-owned window-layout plugin publishes window snapshots and draws
wallpaper strips behind the system bars.

- Share the window-layout plugin transport between Android and OHOS.
- Drop the remaining OHOS branches in Rust and the frontend.
- Rotate with the sensor, within the system rotation lock.

The ability and plugins-workspace pins point at the Darkatse forks
until LeenHawk/openharmony-ability#1 and LeenHawk/plugins-workspace#1
merge.
2026-10-05 19:53:38 -04:00
Darkatse
f4e48eccc5 refactor(layout): move mobile viewport ownership into native hosts
Consume system bars, cutouts and docked keyboards in Android and iOS,
then let web content use the resulting viewport. Publish window wallpaper
strips through one shared background path.

Remove the old CSS and IME compensation layers, update layout ABI v2,
and keep the matching documentation and behavior tests together.
2026-10-05 05:50:20 -04:00
Darkatse
07f8247cca refactor(platform): centralize native host identity
Derive platform and shell kind in Rust and inject them before WebView scripts.
Replace frontend UA guesses and pass host facts and IPC budgets to adapters.

Keep chat width in the frontend, preserve iOS policy initialization, and
restore the mobile third-party resource limit. Align docs and test fixtures.
2026-10-03 22:50:26 -04:00
Darkatse
369826b71d fix(android): adapt status bar icons to rendered background 2026-09-27 00:57:31 -04:00
Darkatse
34e9d8b6dd refactor(rust): move Tauri host crate into workspace crates 2026-07-02 15:30:20 -04:00
Darkatse
b346671988 fix(mobile): keep stable overlay surfaces from reclassifying on IME contract writes 2026-06-08 21:10:34 +08:00
Darkatse
8483e8a6fc fix(mobile): restore IME and overlay surface lifecycle contracts 2026-05-30 16:54:24 +08:00
Darkatse
7acd1b7635 fix(mobile): keep chat shell min-height within viewport contract 2026-05-13 21:15:59 +08:00
Darkatse
ccd56c22fe fix (mobilelayout): Fix scroll reachability for fixed-shell panels (Prompt Manager). 2026-04-17 19:59:17 -04:00
Darkatse
1cb2671e9a refactor (mobile layout): Stabilize mobile layout contract: overlay surface admission, iframe viewport bridge, docs/tests 2026-04-01 20:45:04 -04:00
Darkatse
6909201807 refactor (IME): Refactor Android IME surface routing + regression tests 2026-03-31 20:22:25 -04:00
Darkatse
63ff041334 refactor (mobile layout): host-last geometry firewall + overlay surface classifier, add regression tests 2026-03-31 00:12:27 -04:00
Darkatse
147e1dfcc7 fix(mobile): stabilize top settings panels under custom themes 2026-03-29 01:43:31 -04:00
Darkatse
967492d885 Fix (Android): Fixed an issue where the keyboard failed to lift on certain themes on Android. 2026-03-20 22:40:13 -04:00
Darkatse
0a2e21f2d2 pfix (Android): fix unexpected keyboard raise behavior when returning to the app from the background. 2026-03-17 22:49:14 -04:00
Darkatse
c337d53a4a perf (Android): optimize performance when the Android keyboard is raised. 2026-03-17 22:15:06 -04:00
Darkatse
6e19134edb fix (iOS): fixed an issue in WKWebView on iOS where automatic safe-area insets caused a dead zone at the bottom. 2026-03-16 22:17:59 -04:00
Darkatse
5a45193b1c feat (Android): No longer automatically focus on the #send_textarea when entering a chat. 2026-03-12 03:23:51 -04:00
Darkatse
b0e1b668ad fix (mobile layout): Immersive mode restores full-screen 2026-03-09 14:03:36 -04:00
Darkatse
e50c53cebd Refactoring (Mobile Layout): Refactoring Global Dynamic Styles for Mobile Devices 2026-03-08 23:42:12 -04:00