]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
progress-bar: issue Windows Terminal progress indicating ANSI sequences
authorLennart Poettering <lennart@poettering.net>
Tue, 29 Oct 2024 10:27:51 +0000 (11:27 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 29 Oct 2024 14:54:08 +0000 (15:54 +0100)
This generates the Windows Terminal OSC sequences indicating progress.
This let's the terminal know that we are doing a slow operation, and how
we are progressing.

Windows Terminal uses this in two ways: it shows a circle in the tab
that completes, and it highlights the progress in the task bar.

I found no Linux terminal that currently supports it, but also none that
didn't like it. Thankfully most terminals correctly ignore unrecognized
OSC sequences.

I think we should just merge this, and see if this trips up too many
people, but I have reason to believe this shouldn't be too bad.

And yes, I do work from Windows Terminal sometimes, ssh into my Linux
build systems, and it is really cute seeing the progress animation
there.

src/shared/pretty-print.c

index 0360fa9d72a2db08284b2d2c1b9f26719ef08f43..322d5f496ddfa2ad4e5ba377279f6a78b98feea6 100644 (file)
@@ -1,8 +1,9 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
 
-#include <sys/utsname.h>
 #include <errno.h>
+#include <math.h>
 #include <stdio.h>
+#include <sys/utsname.h>
 
 #include "alloc-util.h"
 #include "color-util.h"
@@ -468,6 +469,14 @@ void draw_progress_bar_impl(const char *prefix, double percentage) {
         }
 
         if (!terminal_is_dumb()) {
+                /* Generate the Windows Terminal progress indication OSC sequence here. Most Linux terminals currently
+                 * ignore this. But let's hope this changes one day. For details about this OSC sequence, see:
+                 *
+                 * https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC
+                 * https://github.com/microsoft/terminal/pull/8055
+                 */
+                fprintf(stderr, "\x1B]9;4;1;%u\a", (unsigned) ceil(percentage));
+
                 size_t cols = columns();
                 size_t prefix_width = utf8_console_width(prefix) + 1 /* space */;
                 size_t length = cols > prefix_width + 6 ? cols - prefix_width - 6 : 0;
@@ -525,7 +534,9 @@ void clear_progress_bar_impl(const char *prefix) {
                               LESS_BY(columns(), 1U)),
                       stderr);
         else
-                fputs(ANSI_ERASE_TO_END_OF_LINE, stderr);
+                /* Undo Windows Terminal progress indication again. */
+                fputs("\x1B]9;4;0;;\a"
+                      ANSI_ERASE_TO_END_OF_LINE, stderr);
 
         fputc('\r', stderr);
 }