Skip to content

Fix OSC 9;4 progress bar not cleared on SIGINT#37038

Merged
reinsch82 merged 2 commits intoreleasefrom
reinhold/fix-progress-bar-on-sigint
Mar 17, 2026
Merged

Fix OSC 9;4 progress bar not cleared on SIGINT#37038
reinsch82 merged 2 commits intoreleasefrom
reinhold/fix-progress-bar-on-sigint

Conversation

@reinsch82
Copy link
Copy Markdown
Member

@reinsch82 reinsch82 commented Mar 11, 2026

Summary

Fixes #37022 — the OSC 9;4 taskbar progress indicator (ConEmu, Ghostty, iTerm2, kitty) was not being cleared when a build was interrupted with Ctrl+C.

  • Register a JVM shutdown hook in ConsoleConfigureAction that writes ESC]9;4;0 (remove taskbar progress) directly to stdout when the terminal supports OSC 9;4. This fires reliably on SIGINT and any other abrupt JVM exit.
  • Add ProgressBar.buildTaskbarProgressResetSequence(ConsoleMetaData) — a public static method returning the reset sequence, or empty string if unsupported.
  • Refactor the existing buildTaskbarProgressSequence to use a shared private buildOsc94Sequence(String) helper, eliminating duplication of the ESC]9;4; format string.

Why a shutdown hook instead of EndOutputEvent:
EndOutputEvent is only fired from OutputEventRenderer.removeChain(), which is called from restore() — this path is not taken when the client JVM exits via SIGINT. The JVM shutdown hook fires unconditionally on exit regardless of how the JVM is terminated.

Test plan

  • Run any Gradle build in a supported terminal (Ghostty, iTerm2 ≥ 3.6.6, kitty, ConEmu) and press Ctrl+C while the OSC 9;4 progress bar is visible — progress indicator should be cleared immediately
  • Verify a normal build completion also clears the progress indicator (shutdown hook fires on normal exit too)

@reinsch82 reinsch82 force-pushed the reinhold/fix-progress-bar-on-sigint branch 2 times, most recently from 0c712fd to 7967741 Compare March 11, 2026 15:12
@reinsch82 reinsch82 requested a review from Copilot March 11, 2026 15:48
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses Gradle’s OSC 9;4 taskbar progress indicator not being cleared when the client JVM terminates via SIGINT (Ctrl+C), by adding an explicit reset sequence on JVM shutdown and centralizing OSC 9;4 sequence construction.

Changes:

  • Register a JVM shutdown hook in ConsoleConfigureAction to emit an OSC 9;4 reset sequence on exit when supported.
  • Add ProgressBar.buildTaskbarProgressResetSequence(ConsoleMetaData) to generate the OSC 9;4 “remove” command (or empty string if unsupported).
  • Refactor OSC 9;4 sequence formatting into a shared helper to reduce duplication.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
platforms/core-runtime/logging/src/main/java/org/gradle/internal/logging/sink/ConsoleConfigureAction.java Adds a shutdown hook that writes the OSC 9;4 reset sequence to stdout on JVM exit.
platforms/core-runtime/logging/src/main/java/org/gradle/internal/logging/console/ProgressBar.java Adds a reset-sequence builder and refactors OSC 9;4 sequence formatting into a helper.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 11, 2026

@reinsch82 I've opened a new pull request, #37040, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 11, 2026

@reinsch82 I've opened a new pull request, #37041, to work on those changes. Once the pull request is ready, I'll request review from you.

@reinsch82 reinsch82 force-pushed the reinhold/fix-progress-bar-on-sigint branch from 78a7285 to 6acae37 Compare March 11, 2026 16:19
@reinsch82 reinsch82 marked this pull request as ready for review March 11, 2026 16:39
@reinsch82 reinsch82 requested a review from a team as a code owner March 11, 2026 16:39
@reinsch82 reinsch82 requested review from asodja and bamboo and removed request for a team March 11, 2026 16:39
@reinsch82 reinsch82 changed the base branch from master to release March 11, 2026 16:41
@reinsch82 reinsch82 requested review from a team as code owners March 11, 2026 16:41
@reinsch82 reinsch82 requested review from eskatos and ghale March 11, 2026 16:41
@ljacomet ljacomet added this to the 9.4.1 milestone Mar 11, 2026
@reinsch82 reinsch82 force-pushed the reinhold/fix-progress-bar-on-sigint branch from 5264dda to 528a7d1 Compare March 12, 2026 08:11
Comment thread subprojects/core/src/main/java/org/gradle/process/internal/ExecHandleRunner.java Outdated
@reinsch82 reinsch82 force-pushed the reinhold/fix-progress-bar-on-sigint branch 3 times, most recently from f6225fe to bb69a49 Compare March 16, 2026 07:17
@reinsch82 reinsch82 requested a review from eskatos March 16, 2026 07:17
@cobexer cobexer removed the request for review from a team March 16, 2026 09:18
@reinsch82

This comment has been minimized.

@bot-gradle

This comment has been minimized.

@bot-gradle

This comment has been minimized.

@reinsch82 reinsch82 force-pushed the reinhold/fix-progress-bar-on-sigint branch 3 times, most recently from ff49a67 to 3883037 Compare March 17, 2026 09:54
When Gradle exits (normally or via SIGINT/Ctrl+C), terminals that support
the OSC 9;4 protocol (Ghostty, iTerm2, ConEmu, kitty) were left with a
stale taskbar progress indicator. The EndOutputEvent path does not fire
on abrupt JVM exit, so the reset must be sent from a JVM shutdown hook.

Register a shutdown hook in ConsoleConfigureAction that writes the
OSC 9;4;0 reset sequence directly to raw stdout. The hook is registered
solely based on terminal capability (supportsTaskbarProgress()), keeping
the decision decoupled from the user's ConsoleOutput choice.

Add integration tests that verify the reset sequence is emitted both
after a successful build and after a SIGINT (Unix only). The SIGINT
test uses a new sendSignal(int) method on GradleHandle and ExecHandle.
The signal logic lives in ExecHandleRunner, which resolves the PID via
Process.pid() on Java 9+ and falls back to reflection on Java 8.

Fixes: #37022

Signed-off-by: Reinhold Degenfellner <rdegenfellner@gradle.com>
@reinsch82 reinsch82 force-pushed the reinhold/fix-progress-bar-on-sigint branch from 3883037 to 566b893 Compare March 17, 2026 10:01
scriptsAreReused() compared scripts by list index, but isolated
projects mode does not guarantee a stable project configuration order
across builds. Match by path instead so the assertion is
order-independent.

Signed-off-by: Reinhold Degenfellner <rdegenfellner@gradle.com>
@reinsch82 reinsch82 force-pushed the reinhold/fix-progress-bar-on-sigint branch from 566b893 to ef03f1d Compare March 17, 2026 12:01
@reinsch82

This comment has been minimized.

@bot-gradle

This comment has been minimized.

@bot-gradle
Copy link
Copy Markdown
Collaborator

The following builds have passed:

@reinsch82
Copy link
Copy Markdown
Member Author

@bot-gradle test RFN

@bot-gradle

This comment has been minimized.

@bot-gradle
Copy link
Copy Markdown
Collaborator

The following builds have passed:

Copy link
Copy Markdown
Member

@eskatos eskatos left a comment

Choose a reason for hiding this comment

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

LGTM

@reinsch82 reinsch82 enabled auto-merge March 17, 2026 15:24
@reinsch82 reinsch82 dismissed jbartok’s stale review March 17, 2026 16:07

paul approved

@reinsch82 reinsch82 added this pull request to the merge queue Mar 17, 2026
Merged via the queue into release with commit 47cb783 Mar 17, 2026
24 of 26 checks passed
@reinsch82 reinsch82 deleted the reinhold/fix-progress-bar-on-sigint branch March 17, 2026 17:11
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.

OSC 9;4 progress bar not cleared on SIGINT

7 participants