ADFA-3645 | Open terminal in adjacent window on large screens#1173
ADFA-3645 | Open terminal in adjacent window on large screens#1173
Conversation
Extract multi-window intent flags and handle new intents in TerminalActivity.
📝 WalkthroughRelease Notes - Terminal Multi-Window Support (ADFA-3645)Features
Changes
|
| Cohort / File(s) | Summary |
|---|---|
Intent Utilities common/src/main/java/com/itsaky/androidide/utils/IntentExtensions.kt |
New extension function applyMultiWindowFlags(context: Context) that conditionally applies multi-window flags (NEW_TASK, NEW_DOCUMENT, SINGLE_TOP, LAUNCH_ADJACENT) for large-screen devices, and FLAG_ACTIVITY_NEW_TASK for non-Activity contexts on smaller screens. |
Activity Intent Launching app/src/main/java/com/itsaky/androidide/actions/main/OpenTerminalAction.kt, app/src/main/java/com/itsaky/androidide/actions/sidebar/TerminalSidebarAction.kt, common/src/main/java/com/itsaky/androidide/activities/editor/HelpActivity.kt |
Refactored to apply multi-window flags via applyMultiWindowFlags() before starting activities, centralizing flag handling and removing inline flag logic. |
Terminal Intent Handling termux/termux-app/src/main/java/com/itsaky/androidide/activities/TerminalActivity.kt |
Added onNewIntent() override to extract session-related extras (working directory, session name, failsafe flag) and create new Termux sessions dynamically when new intents arrive. |
Sequence Diagram(s)
sequenceDiagram
participant Activity as Activity Component
participant Intent as Intent Object
participant Ext as applyMultiWindowFlags()
participant DFF as DeviceFormFactorUtils
participant AM as ActivityManager
Activity->>Intent: create new Intent()
Activity->>Ext: intent.applyMultiWindowFlags(context)
Ext->>DFF: getCurrent(context)
alt Large Screen Device
Ext->>Intent: add NEW_TASK, NEW_DOCUMENT, SINGLE_TOP, LAUNCH_ADJACENT flags
else Non-Large Screen
Ext->>Intent: add FLAG_ACTIVITY_NEW_TASK (if non-Activity context)
end
Ext-->>Intent: return modified Intent
Activity->>AM: startActivity(intent)
rect rgba(100, 150, 200, 0.5)
Note over Activity,AM: Multi-window intent launching flow
end
sequenceDiagram
participant System as System/Intent Router
participant TA as TerminalActivity
participant TS as TermuxService
participant Session as TermuxSession
System->>TA: onNewIntent(intent)
TA->>TA: setIntent(intent)
TA->>TA: extract extras (workDir, sessionName, failsafe)
alt mTermuxService Available
TA->>TS: createTermuxSession(workDir, sessionName, failsafe)
TS-->>Session: newSession
alt Session Created Successfully
TA->>TA: setCurrentSession(newSession.terminalSession)
end
end
rect rgba(150, 100, 200, 0.5)
Note over System,Session: Terminal session creation from intent
end
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
- ADFA-3644 | Support pop-out tooltip display for tablets and DeX #1164 — Modifies HelpActivity's launch behavior and multi-window intent handling using DeviceFormFactorUtils, directly overlapping with centralized flag application logic.
Suggested reviewers
- itsaky-adfa
- Daniel-ADFA
- dara-abijo-adfa
Poem
🐰 Hops through intents with multi-window glee,
Flags are unified for all to see!
New sessions bloom when terminals arise,
Form factors bend to screen device size. ✨📱
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | 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 clearly and specifically describes the main change: enabling terminal launch in adjacent windows on large screens, which aligns with the core functionality added across multiple files. |
| Description check | ✅ Passed | The description is directly related to the changeset, providing clear context about the multi-window terminal feature, the extracted extension function, and the onNewIntent handling, all of which are present in the changes. |
✏️ Tip: You can configure your own custom pre-merge checks in the settings.
✨ Finishing Touches
📝 Generate docstrings
- Create stacked PR
- Commit on current branch
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Commit unit tests in branch
feat/ADFA-3645-multi-window-terminal
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.
Comment @coderabbitai help to get the list of available commands and usage tips.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
termux/termux-app/src/main/java/com/itsaky/androidide/activities/TerminalActivity.kt (1)
51-56:⚠️ Potential issue | 🟡 MinorQueue session requests when
mTermuxServiceis temporarily unavailable.If a relaunch intent arrives while
mTermuxServiceis null, the request is dropped and no session is created. Consider buffering the request and consuming it inonServiceConnectedto avoid missed opens in edge cases.🔧 Proposed fix
class TerminalActivity : TermuxActivity() { + private data class PendingSessionRequest( + val workingDir: String?, + val sessionName: String?, + val isFailsafe: Boolean, + ) + + private var pendingSessionRequest: PendingSessionRequest? = null + override fun onServiceConnected(componentName: ComponentName?, service: IBinder?) { super.onServiceConnected(componentName, service) + pendingSessionRequest?.let { req -> + pendingSessionRequest = null + createAndSelectSession(req.workingDir, req.sessionName, req.isFailsafe) + } lifecycleScope.launch(Dispatchers.IO) { Environment.mkdirIfNotExists(Environment.TMP_DIR) } } - override fun onNewIntent(intent: Intent?) { - super.onNewIntent(intent) - setIntent(intent) - if (intent == null) return + override fun onNewIntent(intent: Intent?) { + super.onNewIntent(intent) + if (intent == null) return + setIntent(intent) - val newWorkingDir = intent.getStringExtra(TermuxConstants.TERMUX_APP.TERMUX_ACTIVITY.EXTRA_SESSION_WORKING_DIR) - val newSessionName = intent.getStringExtra(TermuxConstants.TERMUX_APP.TERMUX_ACTIVITY.EXTRA_SESSION_NAME) - val isFailsafe = intent.getBooleanExtra(TermuxConstants.TERMUX_APP.TERMUX_ACTIVITY.EXTRA_FAILSAFE_SESSION, false) + val newWorkingDir = + intent.getStringExtra(TermuxConstants.TERMUX_APP.TERMUX_ACTIVITY.EXTRA_SESSION_WORKING_DIR) + val newSessionName = + intent.getStringExtra(TermuxConstants.TERMUX_APP.TERMUX_ACTIVITY.EXTRA_SESSION_NAME) + val isFailsafe = + intent.getBooleanExtra(TermuxConstants.TERMUX_APP.TERMUX_ACTIVITY.EXTRA_FAILSAFE_SESSION, false) - val service = mTermuxService - if (service != null) { - val newSession = service.createTermuxSession( - null, - null, - null, - newWorkingDir, - isFailsafe, - newSessionName - ) + if (mTermuxService == null) { + pendingSessionRequest = PendingSessionRequest(newWorkingDir, newSessionName, isFailsafe) + return + } - if (newSession != null) { - mTermuxTerminalSessionActivityClient.setCurrentSession(newSession.terminalSession) - } - } + createAndSelectSession(newWorkingDir, newSessionName, isFailsafe) + } + + private fun createAndSelectSession(workingDir: String?, sessionName: String?, isFailsafe: Boolean) { + val newSession = + mTermuxService?.createTermuxSession(null, null, null, workingDir, isFailsafe, sessionName) + if (newSession != null) { + mTermuxTerminalSessionActivityClient.setCurrentSession(newSession.terminalSession) } + } }Also applies to: 58-81
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@termux/termux-app/src/main/java/com/itsaky/androidide/activities/TerminalActivity.kt` around lines 51 - 56, The relaunch requests get dropped when mTermuxService is null; add a small queue (e.g., pendingRelaunchIntents: MutableList<Intent>) and update the code path that handles incoming relaunch intents (the method that currently creates sessions from the Intent—call it handleRelaunchIntent/processRelaunchIntent) to push the Intent into pendingRelaunchIntents if mTermuxService == null, otherwise process immediately; then in onServiceConnected, after mTermuxService is set, drain pendingRelaunchIntents and call the same session-creation logic for each queued Intent so no requests are lost.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In
`@termux/termux-app/src/main/java/com/itsaky/androidide/activities/TerminalActivity.kt`:
- Around line 51-56: The relaunch requests get dropped when mTermuxService is
null; add a small queue (e.g., pendingRelaunchIntents: MutableList<Intent>) and
update the code path that handles incoming relaunch intents (the method that
currently creates sessions from the Intent—call it
handleRelaunchIntent/processRelaunchIntent) to push the Intent into
pendingRelaunchIntents if mTermuxService == null, otherwise process immediately;
then in onServiceConnected, after mTermuxService is set, drain
pendingRelaunchIntents and call the same session-creation logic for each queued
Intent so no requests are lost.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: ae7aeae2-66ea-4c03-aeb6-8847a462b72e
📒 Files selected for processing (5)
app/src/main/java/com/itsaky/androidide/actions/main/OpenTerminalAction.ktapp/src/main/java/com/itsaky/androidide/actions/sidebar/TerminalSidebarAction.ktcommon/src/main/java/com/itsaky/androidide/activities/editor/HelpActivity.ktcommon/src/main/java/com/itsaky/androidide/utils/IntentExtensions.kttermux/termux-app/src/main/java/com/itsaky/androidide/activities/TerminalActivity.kt
Description
Added support for launching the terminal in a secondary adjacent window (split-screen) when users are on a tablet or DeX device. This allows users to read their code in the editor and interact with the terminal at the same time. The multi-window intent flags were extracted into a reusable
Intent.applyMultiWindowFlags()extension function, which is now applied to terminal actions. Additionally,TerminalActivitywas updated to handleonNewIntentso that new terminal sessions are created correctly when the activity is already open.Details
IntentExtensions.ktto centralize large screen / multi-window intent flag configurations.OpenTerminalActionandTerminalSidebarAction.onNewIntentinTerminalActivityto instantiate anewTermuxSessionwhen the activity is launched again.document_5100351222519432845.mp4
Ticket
ADFA-3645
Observation
Because the multi-window launch uses
Intent.FLAG_ACTIVITY_SINGLE_TOP,TerminalActivityrequires theonNewIntentimplementation to ensure subsequent terminal open actions correctly initialize new sessions with the provided working directory and session name, rather than just bringing the existing window into focus silently.