Fix OSC 9;4 progress bar not cleared on SIGINT#37038
Conversation
0c712fd to
7967741
Compare
There was a problem hiding this comment.
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
ConsoleConfigureActionto 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.
|
@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. |
|
@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. |
78a7285 to
6acae37
Compare
5264dda to
528a7d1
Compare
f6225fe to
bb69a49
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
ff49a67 to
3883037
Compare
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>
3883037 to
566b893
Compare
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>
566b893 to
ef03f1d
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
The following builds have passed: |
|
@bot-gradle test RFN |
This comment has been minimized.
This comment has been minimized.
|
The following builds have passed: |
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.
ConsoleConfigureActionthat writesESC]9;4;0(remove taskbar progress) directly tostdoutwhen the terminal supports OSC 9;4. This fires reliably on SIGINT and any other abrupt JVM exit.ProgressBar.buildTaskbarProgressResetSequence(ConsoleMetaData)— a public static method returning the reset sequence, or empty string if unsupported.buildTaskbarProgressSequenceto use a shared privatebuildOsc94Sequence(String)helper, eliminating duplication of theESC]9;4;format string.Why a shutdown hook instead of
EndOutputEvent:EndOutputEventis only fired fromOutputEventRenderer.removeChain(), which is called fromrestore()— 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