Skip to content

ADFA-3122 | Fix editor viewport and buffer persistence on configuration change#1066

Merged
jatezzz merged 3 commits intostagefrom
fix/ADFA-3122-editor-state-on-configuration-change
Mar 12, 2026
Merged

ADFA-3122 | Fix editor viewport and buffer persistence on configuration change#1066
jatezzz merged 3 commits intostagefrom
fix/ADFA-3122-editor-state-on-configuration-change

Conversation

@jatezzz
Copy link
Collaborator

@jatezzz jatezzz commented Mar 11, 2026

Description

This PR addresses issues related to UI glitches and state loss when the device configuration changes (e.g., docking to DeX or rotating the screen). It ensures the editor centers the cursor in the viewport after a resize and correctly updates file timestamps to prevent sync conflicts.

Details

  • Viewport Persistence: Added onConfigurationChanged logic to trigger ensurePositionVisible after the next layout pass, keeping the user's focus on the active line.
  • File Integrity: Updated the internal fileTimestamps map upon successful file saves to ensure the IDE tracks the latest buffer state accurately.
  • Process Stability: Leverages Android's configuration handling to prevent terminal disconnection during window resizing.

Before changes

document_5012592404868368210.mp4

After changes

document_5012592404868368211.mp4

Ticket

ADFA-3122

@jatezzz jatezzz force-pushed the fix/ADFA-3122-editor-state-on-configuration-change branch from bad6977 to c47a2c6 Compare March 11, 2026 22:20
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 11, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ff285c47-4aea-4c4f-9336-c59de0adf601

📥 Commits

Reviewing files that changed from the base of the PR and between ac0e79b and 3736eda.

📒 Files selected for processing (1)
  • app/src/main/java/com/itsaky/androidide/activities/editor/EditorHandlerActivity.kt

📝 Walkthrough
  • Fixes editor viewport and buffer persistence on configuration changes (ADFA-3122)

    • Ensures cursor/active line remains visible after configuration changes by overriding EditorHandlerActivity.onConfigurationChanged and scheduling ensurePositionVisible via doOnNextLayout so the editor recenters the cursor after the next layout pass.
    • Updates internal fileTimestamps after successful saves to the file's lastModified value to keep IDE buffer state in sync and avoid sync conflicts.
    • Improves Android configuration handling to reduce terminal disconnection/resizing issues.
    • Includes before/after visual references (assets) and references ticket ADFA-3122.
  • Implementation notes

    • Added override fun onConfigurationChanged(newConfig: Configuration) in EditorHandlerActivity which calls super and uses androidx.core.view.doOnNextLayout to call ensurePositionVisible for the active editor after layout.
    • Replaced the mutable map with a thread-safe ConcurrentHashMap<String, Long>() for fileTimestamps and update entries when files are saved: fileTimestamps[savedFile.absolutePath] = savedFile.lastModified().
    • saveResultInternal now updates the tracked timestamp on successful save; external-file-change detection still compares disk timestamps against tracked timestamps and reloads files that have no unsaved changes.
  • Risks & best-practice violations

    • Timestamp lifecycle: ConcurrentHashMap entries are retained without explicit cleanup when files are closed — risk of unbounded growth or stale entries.
    • Timestamp reliability: Relying solely on filesystem lastModified timestamps can produce false positives/negatives due to coarse timestamp resolution, buffering, or platform differences.
    • Save ordering / fs sync: Recording lastModified immediately after save may race with filesystem write/flush timing on some devices, causing transient mismatches.
    • Deferred callbacks & lifecycle: doOnNextLayout callbacks must guard against the editor/view/activity being destroyed before execution to avoid NPEs or no-op behavior.
    • Concurrency: although fileTimestamps is thread-safe, other related state may still have threading assumptions; ensure all cross-thread accesses are safe.
  • Recommendations

    • Evict or remove timestamp entries when files are closed, or implement TTL/periodic cleanup to prevent unbounded growth.
    • Add a small timestamp tolerance (e.g., ignore differences < 1s) or stronger validation (checksums, version counters) to reduce false sync prompts.
    • Ensure timestamp updates occur after the filesystem is reliably flushed (or verify on an IO dispatcher / re-read timestamp) to avoid races between save completion and timestamp recording.
    • Wrap deferred layout callbacks with lifecycle/attachment checks (verify view is attached and activity not finishing) before calling ensurePositionVisible.

Walkthrough

Adds handling for configuration changes to ensure the editor caret is visible after layout, replaces a mutable map with a thread-safe ConcurrentHashMap for per-file timestamps, and updates those timestamps immediately after fragment saves.

Changes

Cohort / File(s) Summary
Editor activity
app/src/main/java/com/itsaky/androidide/activities/editor/EditorHandlerActivity.kt
Swapped mutableMapOfConcurrentHashMap for fileTimestamps; added imports (Configuration, doOnNextLayout, ConcurrentHashMap); added override fun onConfigurationChanged(newConfig: Configuration) which posts a next-layout callback to call ensurePositionVisible on the active editor fragment; on save (saveResultInternal) update fileTimestamps[frag.file.absolutePath] = frag.file.lastModified().

Sequence Diagram(s)

sequenceDiagram
participant Activity as EditorHandlerActivity
participant Fragment as EditorFragment
participant View as EditorView

Activity->>Fragment: find current editor fragment
Activity->>View: post doOnNextLayout callback
Note right of View: after layout completes
View-->>Activity: invoke callback
Activity->>Fragment: call ensurePositionVisible()
Fragment->>View: adjust caret/scroll position
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~7 minutes

Possibly related PRs

Suggested reviewers

  • Daniel-ADFA
  • jomen-adfa

Poem

"I am a rabbit, quick and spry,
When screens rotate I give a sigh.
I wait till layout hops on through,
Then nudge the caret into view.
Saved timestamps tick — a tidy cue." 🐇✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and specifically describes the main changes: fixing editor viewport centering and file timestamp persistence during configuration changes.
Description check ✅ Passed The description is directly related to the changeset, providing context about UI glitches on configuration changes, explaining the viewport and file integrity fixes with clear before/after references.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/ADFA-3122-editor-state-on-configuration-change
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

CodeRabbit can scan for known vulnerabilities in your dependencies using OSV Scanner.

OSV Scanner will automatically detect and report security vulnerabilities in your project's dependencies. No additional configuration is required.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@app/src/main/java/com/itsaky/androidide/activities/editor/EditorHandlerActivity.kt`:
- Around line 731-733: The writes to fileTimestamps in the save flow are not
synchronized and can race with onPause() and checkForExternalFileChanges() which
run on Dispatchers.IO; make fileTimestamps thread-safe by replacing its backing
map with a concurrent data structure (e.g., Java's ConcurrentHashMap) or
protecting all accesses with a single Mutex, update references to fileTimestamps
used in saveAllAsync(), onPause(), and checkForExternalFileChanges()
accordingly, and ensure the frag.file?.let { savedFile -> fileTimestamps[...] =
savedFile.lastModified() } write uses the new thread-safe access pattern.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2bcabb1b-5878-4445-b34b-5d8c3c2491cd

📥 Commits

Reviewing files that changed from the base of the PR and between 26b4268 and bad6977.

📒 Files selected for processing (1)
  • app/src/main/java/com/itsaky/androidide/activities/editor/EditorHandlerActivity.kt

jatezzz added 2 commits March 12, 2026 09:30
…ation change

Ensure cursor visibility after layout changes and update file timestamps after saving.
@jatezzz jatezzz force-pushed the fix/ADFA-3122-editor-state-on-configuration-change branch from c47a2c6 to ac0e79b Compare March 12, 2026 14:30
@jatezzz jatezzz requested a review from Daniel-ADFA March 12, 2026 14:31
@jatezzz jatezzz merged commit 2154fa4 into stage Mar 12, 2026
2 checks passed
@jatezzz jatezzz deleted the fix/ADFA-3122-editor-state-on-configuration-change branch March 12, 2026 20:51
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