Skip to content

Android: Back button unresponsive during parallel agent runs #94

@begna112

Description

@begna112

Description

On Android, the back button in the session header becomes unresponsive when a session has multiple parallel agents running, preventing navigation to other sessions.

Root Cause

A z-index / touch layering conflict in the SessionView layout causes the ChatList's absolute-fill container to capture touches intended for the header back button.

Layout Structure

SessionView (Fragment <>)
├── Header wrapper (position: absolute, top: 0, zIndex: 1000)
│     └── ChatHeaderView with back button
│
└── Content wrapper (flex: 1, paddingTop: headerHeight)
      └── AgentContentView
            ├── Content container (flexGrow: 1)
            │     └── ChatList wrapper (position: absolute, top: 0, bottom: 0)  ← PROBLEM
            │           └── Inverted FlatList
            └── Input container
                  └── AgentInput
                        └── permissionRequestsContainer (no zIndex)
                              └── PermissionFooter × N

Three interacting issues

1. ChatList wrapper ignores parent padding and fills behind the header

AgentContentView.tsx line 22 renders the ChatList inside:

<View style={[{ position: 'absolute', top: 0, left: 0, right: 0, bottom: 0 }]}>
    {content}
</View>

The parent has paddingTop to make room for the header, but the absolute-positioned child ignores padding — it starts at top: 0 of the parent, directly behind the header. This creates an invisible full-screen touch target overlapping the header area.

2. No pointerEvents anywhere in the chain

Neither the ChatList absolute wrapper, the AgentContentView, nor the content container set pointerEvents="box-none". This means the absolute-fill container is a valid touch target that can capture taps in the header area.

3. Android z-index doesn't reliably control touch ordering

The header uses zIndex: 1000 but on Android, zIndex doesn't reliably determine touch event ordering the way it does on web/iOS. Android uses elevation for native z-ordering of touch targets, and the header container doesn't set elevation.

Why it's worse with parallel agents

  • More content from multiple agents = more frequent FlatList re-renders and layout recalculations
  • maintainVisibleContentPosition triggers additional layout passes on every update
  • Multiple permission footers stacking in AgentInput (no zIndex) add more interactive touch targets competing for events
  • UI thread saturation from rapid updates causes touch events to be delayed or dropped
  • React Native's touch responder system re-evaluates on each layout change — during rapid updates the ChatList container can "win" the responder negotiation over the header

Landscape mode is worse

The landscape back button (SessionView.tsx ~line 1266) has elevation: 2 but no zIndex, making it trivially overlapped by any content.

Suggested Fix

  1. Add pointerEvents="box-none" to the absolute-fill ChatList wrapper in AgentContentView.tsx line 22 so it doesn't capture touches in the header area
  2. Add elevation: 10 (or similar) to the header wrapper in SessionView.tsx line 244 for Android touch ordering
  3. Add zIndex: 1000 to the landscape back button (SessionView.tsx ~line 1268)
  4. Consider adding pointerEvents="box-none" to the content wrapper as well

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions