Skip to content

fix(android): inset native windows below system bars - #258

Merged
ErikBjare merged 5 commits into
ActivityWatch:masterfrom
TimeToBuildBob:fix/native-window-insets-256
Sep 13, 2026
Merged

fix(android): inset native windows below system bars#258
ErikBjare merged 5 commits into
ActivityWatch:masterfrom
TimeToBuildBob:fix/native-window-insets-256

Conversation

@TimeToBuildBob

@TimeToBuildBob TimeToBuildBob commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

On Android 16 with a display cutout, the drawer logo overlapped the status bar and the Sync switch sat at y=42–113 inside the 136px system-bar area. Tapping its center left the setting unchanged; white status icons also disappeared against the settings background.

Give each native activity root ownership of system-bar, cutout, and keyboard insets, preserving its original padding. Remove the obsolete edge-to-edge opt-out and duplicate drawer inset handling, and select dark system icons for the app's light theme. The Sync switch now sits at y=178–249 and real screen taps persist off → on → off. Main/WebUI, the drawer, Sync, Auth, and Onboarding share the same policy.

Refs #256.

Validation:

  • Four instrumentation cases cover safe bounds, full drawer-logo visibility, repeated inset dispatch, recreation, and a real Sync-toggle tap with preference verification/restoration. They fail on the baseline and pass on API 36 and API 34 with a hole cutout, in gesture and three-button navigation (16 passing case executions). API 36 gesture testing also uses system dark mode.
  • The suite grants its own usage/notification permissions. Another four-case API 36 run passes after explicitly revoking those permissions and resetting the usage app op, covering a fresh-device start.
  • Debug APK, instrumentation APK, and 99 JVM unit tests pass. CT102 uses matching JNI artifact 10193933384 from base commit e0cad8e; before/after screenshots, UI bounds, APK hashes, and run logs are retained in Bob's aw-android-insets-d32d evidence bundle.
  • lintDebug reproduces the same two UseAppTint errors in unchanged widget layouts and the same 117 warnings on both base and branch.
  • fix(android): handle rejected foreground service starts #257 touches the same activity files for service-start provenance; its hunks are separate from this UI initialization change.

Tests ran on x86_64 emulators. The issue remains open for maintainer review and merge.

@greptile-apps

greptile-apps Bot commented Sep 13, 2026

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

The PR appears safe to merge; no actionable correctness, security, or repository-rule violations remain.

Findings

  1. P2 Teardown masks setup failure

Summary

  • Adds a shared edge-to-edge inset policy to Main, Sync, Auth, and Onboarding activities.
  • Removes duplicate layout-level inset handling and the obsolete Android 15 opt-out.
  • Adds instrumentation coverage for safe bounds, drawer visibility, recreation, repeated inset dispatch, and real Sync-toggle taps.
  • Updates test teardown to preserve the original setup failure when app-op state capture fails.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Native activity onCreate] --> B[setContentView]
    B --> C[applySafeWindowInsets]
    C --> D[Enable edge-to-edge with light system-bar styles]
    C --> E[Capture original root padding]
    E --> F[Receive window insets]
    F --> G[Combine system bars, display cutout, and IME]
    G --> H[Apply original padding plus safe insets]
    H --> I[Consume insets to prevent duplicate child handling]
Loading

Reviews (4) · Last reviewed commit: "test(android): harden inset test synchro..."

@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

CI-green and mergeable (Greptile 5/5) — waiting only on a maintainer click.

This PR is ready to merge, but the bot has pull-only access to this repo and can't self-merge — surfacing it here so it isn't lost. The monitoring loop will stop re-flagging it now that this note is posted.

@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

@greptileai review

Comment thread mobile/src/androidTest/java/net/activitywatch/android/NativeWindowInsetsTest.kt Outdated
Git-Session-Id: 924ef423-1acf-5e9c-8679-cc29a143d651
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

@greptileai review


@After
fun restoreUsageAccess() {
shell("appops set $packageName GET_USAGE_STATS $originalUsageAccessMode")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Teardown masks setup failure

If appops get fails, originalUsageAccessMode is never initialized, but JUnit still runs this teardown. Reading the lateinit property then raises an additional UninitializedPropertyAccessException, which obscures the original setup failure and makes the instrumentation failure harder to diagnose. Only attempt restoration after confirming that the original mode was captured.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in d9411a4: the captured app-op mode is now nullable and teardown restores it only after setup initialized it, preserving the original setup failure. I also fixed the API 29 CI race exposed by the previous head: after a real UIAutomator tap, the test now waits for the switch's checked state before reading its asynchronously persisted preference. :mobile:compileDebugAndroidTestKotlin passes locally.

Git-Session-Id: 7023c762-9062-522e-89d5-c877b46e7bbd
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

@greptileai review

@ErikBjare
ErikBjare merged commit 7142aab into ActivityWatch:master Sep 13, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants