Skip to content

Show Run window during run mode in 2026.1#8985

Open
helin24 wants to merge 4 commits into
flutter:mainfrom
helin24:align-run-window
Open

Show Run window during run mode in 2026.1#8985
helin24 wants to merge 4 commits into
flutter:mainfrom
helin24:align-run-window

Conversation

@helin24
Copy link
Copy Markdown
Member

@helin24 helin24 commented May 29, 2026

Fixes #8890

This change routes the Flutter app console to the native Run tool window when running in "Run" mode (not debugging), while still starting a headless debug session in the background to support Hot Reload.

We achieve this by:

  1. Muting the debug tab in the Debug window via XDebugSessionBuilder.showTab(false) in Run mode.
  2. Returning a standard run descriptor via RunContentBuilder in LaunchState.launch() for Run mode.
  3. Manually injecting the Reload and Restart actions directly into this Run console toolbar.
  4. Overriding XDebugProcess.createConsole() to return a dummy console in Run mode, completely avoiding a Swing parent hierarchy conflict (which previously caused a blank console).
  5. Skipping deprecated suppressDebugViews calls in sessionInitialized() when the new reflective hooks are active to avoid platform warnings.

I'm pasting a description of the run and debug lifecycle below, in case this is helpful context for any future changes.


Step-by-Step Lifecycle Description

1. Shared Startup Phase

No matter which button the user clicks, the plugin first prepares the environment:

  1. Process Preparation: FlutterApp.start() is invoked. It creates the MostlySilentColoredProcessHandler which wraps the native flutter command line.
  2. API Hookup: DaemonApi.listen(process, listener) is called. This registers the JSON parser to handle the stdin/stdout streams of the process. Crucially, process.startNotify() is not called yet.
  3. Console Creation: setUpConsoleAndActions(app) creates the DaemonConsoleView and attaches it to the process. It also prepares the toolbar actions (like DevTools).

2. Debug Workflow Lifecycle

If the user clicked "Debug":

  1. Configure Builder: The plugin uses reflection to call XDebugSessionBuilder.showTab(true) on the session builder.
  2. Initialize Session: XDebuggerManager.startSession is called.
  3. UI Bindings: Because showTab is true, the platform creates XDebugSessionTab and automatically registers it with the Debug Tool Window (ToolWindowId.DEBUG). This opens the Debug window and shows the debugger panels (Variables, Frames, Threads) alongside the Console.
  4. Process Boot: Immediately after UI initialization, XDebuggerManagerImpl calls processHandler.startNotify(). This boots the OS process.
  5. Connection: The background thread (scheduleConnect()) detects the VM Service URI printed by the process and connects the debugger.

3. Run Workflow Lifecycle

If the user clicked "Run" (which still needs a headless debug connection for Hot Reload):

  1. Configure Headless Builder: The plugin calls XDebugSessionBuilder.showTab(false) on the builder.
  2. Headless Initialization: XDebuggerManager.startSession is called.
    • Because showTab is false, the platform enters a headless path.
    • It completely skips creating the XDebugSessionTab UI and does not open the Debug tool window.
    • It also skips calling processHandler.startNotify() inside XDebuggerManager.
  3. Run UI Creation: In LaunchState.launch(), the plugin discards the headless debug descriptor. Instead, it passes the console ExecutionResult to RunContentBuilder(result, env).showRunContent().
    • Since this is a standard run builder executed under the "Run" executor, it registers the console tab with the Run Tool Window (ToolWindowId.RUN).
  4. Process Boot: LaunchState.launch() returns this native Run descriptor to the platform ExecutionManager.
  5. Single startNotify: The platform ExecutionManager renders the tab in the Run tool window and calls processHandler.startNotify(). This boots the OS process exactly once.
  6. Headless Connection: The background thread (scheduleConnect()) connects the debugger silently in the background. The user gets their console and Hot Reload buttons in the Run window, while the Debug window remains completely closed.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request refactors the launch process to support background hot reload and hot restart in Run mode by establishing a VM service connection while rendering a standard Run console instead of the debug UI. The reviewer provided valuable feedback, including a correction to ensure debugger panels are properly suppressed in non-DEBUG and non-RUN modes (like PROFILE or COVERAGE), a performance optimization to cache the named tab support check, and a logic improvement to only add reload/restart actions if the launch mode supports them.

Comment thread src/io/flutter/run/FlutterDebugProcess.java Outdated
Comment thread src/io/flutter/run/FlutterDebugSessionUtils.java Outdated
Comment thread src/io/flutter/run/LaunchState.java Outdated
helin24 added 3 commits May 29, 2026 13:34
This change cleanly routes the Flutter app console to the native Run tool window when running in "Run" mode (not debugging), while still starting a headless debug session in the background to support Hot Reload.

We achieve this by:
1. Muting the debug tab in the Debug window via XDebugSessionBuilder.showTab(false) in Run mode.
2. Returning a standard run descriptor via RunContentBuilder in LaunchState.launch() for Run mode.
3. Manually injecting the Reload and Restart actions directly into this Run console toolbar.
4. Overriding XDebugProcess.createConsole() to return a dummy console in Run mode, completely avoiding a Swing parent hierarchy conflict (which previously caused a blank console).
5. Skipping deprecated suppressDebugViews calls in sessionInitialized() when the new reflective hooks are active to avoid platform warnings.

TAG=agy
CONV=fccd665d-3066-4b89-92ff-553454d58b2f
…stant access

Since the validation of the experimental builder hooks is computed once during class load, we expose the cached USE_NAMED_TAB boolean directly as a public static final constant and remove the redundant useNamedTab() getter method.

TAG=agy
CONV=fccd665d-3066-4b89-92ff-553454d58b2f
@helin24 helin24 force-pushed the align-run-window branch from facbdc5 to 3fd4894 Compare May 29, 2026 20:40
@helin24 helin24 requested a review from pq May 29, 2026 20:46
@helin24 helin24 changed the title [feat] align Run mode with JetBrains Split Debugger architecture Show Run window during run mode in 2026.1 May 29, 2026
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.

Wrong Intellij idea tool window is picked when app is running in new Idea 2026.1

1 participant