Skip to content

Android: touch, soft keyboard and phone-width issues found testing every component of 0.7.0 #3310

Open

Description

@Bombatomica64

Description

Thank you for GPUI Kit. I built an on-device test gallery for GPUI Kit v0.7.0 on Android (gpui-mobile host entry point, a SurfaceView Activity, phone in portrait) with a demo screen for every user-facing component, and went through each one by touch. Most components work well; this issue collects what does not, in case it helps. I'm happy to split it into focused issues, add details or recordings, or test fixes on the device. Full per-component notes are in the gallery's COMPONENT_MATRIX.md (77 working / 18 partial / 4 broken / 4 not applicable), and the APK is on the v0.1.2 release.

Fixes already proposed (one PR per repository):

Try it on a device

The test app is open source and meant to be used as a playground: Bombatomica64/Gpui-android.

  • Prebuilt APK (arm64-v8a + x86_64, sideloadable, signed with a debug key): gpui-kit-mobile-lab-v0.1.2.apk
  • Build from source: ./build.sh android --release --install (Rust + cargo-ndk + Android SDK/NDK; see the README).
  • Each component has its own screen with its states, current value and an event log; there are also Touch Lab, Scroll Stress, Diagnostics, Stress Test and Themes screens. To try a Kit change on Android, add the changed Kit crates (e.g. gpui-base = { path = "…/gpui-kit/crates/base" }) to the [patch.crates-io] section of its Cargo.toml and rebuild. The app is on Kit 0.7.0 / gpui-pre 0.3.7, so the patched crates need to stay on that GPUI snapshot.

Environment

  • GPUI: gpui-pre 0.3.7 (the snapshot Kit 0.7.0 pins), wgpu 29.0.4
  • GPUI Kit: 0.7.0 (0c830f4d)
  • gpui-mobile: f379bc8 (plus the patches above)
  • Platform: Android 13 (API 33) on Redroid, 1080×2340 at 420 dpi (411×819 pt, scale 2.625), AOSP keyboard. Interactions were driven with adb shell input (taps, swipes, raw motionevent sequences, IME typing). SwiftShader rendering, so no performance claims.

Steps to Reproduce

Install the release APK and open a component's screen from the catalog, or directly:

adb shell am start -n dev.gpui.mobile.lab/.LabActivity --es screen "'Number & OTP'"

Each screen shows the current value and an event log (also on logcat, tag GPUI_MOBILE_LAB).

Actual

Broken on a touch-only device

  • OtpInput and TimeField (and the time part of a date+time DatePicker): tapping shows no soft keyboard. They have no text-input handler (EntityInputHandler) and never request the virtual keyboard, so they can only be edited with a hardware keyboard.
  • Context menus (ContextMenuExt) open only on the right mouse button; a long-press does nothing, so there is no way to open one on a phone. LongPressEvent (claimed with prevent_default on Started) looks like the natural mapping.
  • Everything built on on_drag ignores finger drags, because GPUI's drag-and-drop is mouse-only and a touch drag arrives as TouchDragEvent: Resizable dividers, Dock splitters and tab drag/split, DataTable column resize/reorder. The Slider PR shows one way to handle it for a single component.

Layout at phone width (411 pt)

  • Popover near the right edge and PopupMenu submenus are not moved back into the viewport and are clipped.
  • Breadcrumb never wraps; the last items are clipped.
  • Full Pagination overflows (Next is clipped); the compact variant fits.
  • Static Table clips its last column (no shrinking or horizontal scroll).
  • DescriptionList horizontal two-column layout and Settings content break words mid-word; the Settings sidebar takes about 70% of the width.
  • Accordion: a long title does not wrap and pushes the chevron out of view.
  • Carousel: prev/next buttons render outside the card and are clipped at the screen edges.

Touch behaviour

  • Carousel: one fling skips several slides, because every momentum scroll delta counts as a step.
  • Kit's scroll containers do not set restrict_scroll_to_axis(), so a horizontal pan on a vertical-only list scrolls it vertically (GPUI converts the pan). Setting it on the app's own containers fixes it there.
  • TextView long-press selection shows handles and Copy / Select All, but the initial selection is often not the pressed word (collapsed, or starting mid-word).
  • DataTable emits a stray RightClickedRow(None) on a plain tap.
  • After a tap, the touched menu/list row keeps its hover highlight until the next touch elsewhere.
  • Nothing scrolls a focused input above the soft keyboard; the app has to do it.

Not Android-specific

Split into focused issues:

gpui-mobile integration (listed for completeness; they may belong in gpui-mobile)

  • Bold and italic text render as regular weight: Android's Roboto is a variable font and the text system does not apply weight/italic variations. Headings are larger but not bold.
  • Dismissing the IME with back injects an escape keystroke, which apps also handle as navigation/close.
  • NumberInput and numeric masks open the full text keyboard; gpui-mobile always requests the default keyboard type.
  • show_soft_keyboard is a no-op, so components that call it get no keyboard.
  • On the host-driven entry point, night mode is not reported to window.appearance(), and the bundled-emoji fallback cannot read APK assets (it needs an AndroidApp); without a host workaround, emoji do not render on Android 13+.
  • Closing a sheet while a fling is still running hands the remaining momentum to the page behind it.
  • window.request_animation_frame() panics when called outside rendering (e.g. in a click handler).

Expected

Components are usable by touch alone: text-like fields raise the soft keyboard, context menus and drag interactions have touch equivalents, and popovers and wide components stay inside a phone-width viewport.


The gallery and this report were produced with AI assistance (Claude Code), and every item was reproduced on the emulated device.

🤖 Generated with Claude Code

Activity

  1. Bombatomica64 commented on Sep 29, 2026

    @Bombatomica64
    ContributorAuthor

    A small update after checking the app on a physical phone (360×736 pt, dark mode): I added two items under Not Android-specific:

    • a TextView inside a Filled Bubble renders white on white, because TextView paints the theme foreground over the bubble's primary_foreground
    • the default ShimmerText highlight is invisible on foreground text in dark mode

    Both include the cause and a workaround. The playground APK is now v0.1.1. Thanks again for the library!

  2. huacnlee commented on Sep 30, 2026

    @huacnlee
    Member

    #3313 is merged as 9c369db. Main now contains the Slider touch-drag path and Android FPS font fix; these are after the v0.7.0 tag.

    The rest of this report is still open. In particular, current source still overwrites each Radio's disabled state with the RadioGroup state, and the dark-mode ShimmerText default still mixes foreground text toward the same foreground color. Those are desktop-relevant too.

    Please split the remaining reproducible items into focused issues, starting with disabled RadioGroup items, Textarea rows, Bubble/TextView contrast and ShimmerText contrast. That will let each fix be verified independently of the Android integration work.

  3. Bombatomica64 commented on Sep 30, 2026

    @Bombatomica64
    ContributorAuthor

    Thank you for merging #3313 and for the guidance! I've split out the four you mentioned, each with a repro against main (201b55a4):

    I'll continue with the remaining items the same way, each with its own repro, and keep this issue as the index.

  4. huacnlee commented on Sep 30, 2026

    @huacnlee
    Member
  5. Bombatomica64 commented on Sep 30, 2026

    @Bombatomica64
    ContributorAuthor

    Fixes are now up for all four split issues, each with a regression test that fails on main:

    Each issue has a comment with the details, including two corrections to my original reports. The playground APK is now v0.1.2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions