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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions