* [PATCH 0/2] term: Defer configfile clear on inactive output terminals
@ 2026-10-20 12:49 Sean Rhodes
2026-10-20 12:49 ` [PATCH 1/2] term: Defer configfile clear per output terminal Sean Rhodes
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Sean Rhodes @ 2026-10-20 12:49 UTC (permalink / raw)
To: grub-devel
A configfile can run before its target has selected visible output. On EFI,
clearing immediately activates text mode and erases the firmware splash even
when the target proceeds with a hidden-menu autoboot.
Defer the clear on inactive output terminals until they prepare for visible
output. Active terminals retain the existing immediate-clear behaviour. The
second patch adds functional coverage for silent and nested configfiles,
subsequent output, multiple terminals, explicit clears, empty output, and
verbose sleep cursor ordering.
Sean Rhodes (2):
term: Defer configfile clear per output terminal
tests: Exercise deferred configfile clear
Sean Rhodes (2):
term: Defer configfile clear per output terminal
tests: Exercise deferred configfile clear
grub-core/Makefile.core.def | 5 +
grub-core/commands/configfile.c | 3 +-
grub-core/commands/sleep.c | 4 +
grub-core/normal/term.c | 35 +++
grub-core/term/efi/console.c | 19 ++
grub-core/tests/deferred_clear_test.c | 317 ++++++++++++++++++++++++++
grub-core/tests/lib/functional_test.c | 1 +
include/grub/term.h | 11 +
8 files changed, 394 insertions(+), 1 deletion(-)
create mode 100644 grub-core/tests/deferred_clear_test.c
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] term: Defer configfile clear per output terminal
2026-10-20 12:49 [PATCH 0/2] term: Defer configfile clear on inactive output terminals Sean Rhodes
@ 2026-10-20 12:49 ` Sean Rhodes
2026-10-20 12:49 ` [PATCH 2/2] tests: Exercise deferred configfile clear Sean Rhodes
2026-10-20 18:40 ` [PATCH 0/2] term: Defer configfile clear on inactive output terminals Leo Sandoval via Grub-devel
2 siblings, 0 replies; 4+ messages in thread
From: Sean Rhodes @ 2026-10-20 12:49 UTC (permalink / raw)
To: grub-devel
A configfile can run before its target selects visible output. Clearing the EFI console immediately erases the firmware splash even when the target continues with a hidden-menu autoboot.
Keep a pending clear on each inactive output terminal and consume it when that terminal prepares for visible output. Active terminals retain the existing immediate clear behaviour. This also prepares output before verbose sleep saves its cursor position.
Signed-off-by: Sean Rhodes <sean@starlabs.systems>
---
grub-core/commands/configfile.c | 3 ++-
grub-core/commands/sleep.c | 4 ++++
grub-core/normal/term.c | 35 +++++++++++++++++++++++++++++++++
grub-core/term/efi/console.c | 19 ++++++++++++++++++
include/grub/term.h | 11 +++++++++++
5 files changed, 71 insertions(+), 1 deletion(-)
diff --git a/grub-core/commands/configfile.c b/grub-core/commands/configfile.c
index f2d2abb..67bf5b1 100644
--- a/grub-core/commands/configfile.c
+++ b/grub-core/commands/configfile.c
@@ -37,8 +37,9 @@ grub_cmd_source (grub_command_t cmd, int argc, char **args)
extractor = (cmd->name[0] == 'e');
new_env = (cmd->name[extractor ? sizeof ("extract_entries_") - 1 : 0] == 'c');
+ /* An uninitialized terminal may still be displaying a firmware splash. */
if (new_env)
- grub_cls ();
+ grub_cls_deferred ();
if (new_env && !extractor)
grub_env_context_open ();
diff --git a/grub-core/commands/sleep.c b/grub-core/commands/sleep.c
index a1370b7..be4f2ce 100644
--- a/grub-core/commands/sleep.c
+++ b/grub-core/commands/sleep.c
@@ -80,6 +80,10 @@ grub_cmd_sleep (grub_extcmd_context_t ctxt, int argc, char **args)
grub_refresh ();
+ /* A pending clear must happen before the countdown saves its position. */
+ if (state[0].set)
+ grub_term_prepare_output ();
+
pos = grub_term_save_pos ();
for (; n; n--)
diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c
index c073eb4..dc47390 100644
--- a/grub-core/normal/term.c
+++ b/grub-core/normal/term.c
@@ -990,6 +990,9 @@ grub_print_ucs4 (const grub_uint32_t * str,
int margin_left, int margin_right,
struct grub_term_output *term)
{
+ if (str == last_position)
+ return;
+
print_ucs4_real (str, last_position, margin_left, margin_right,
term, 0, 0, 1, 0, -1, 0, 0, 0);
}
@@ -1011,6 +1014,9 @@ grub_xnputs (const char *str, grub_size_t msg_len)
int backlog = 0;
grub_term_output_t term;
+ if (msg_len == 0)
+ return;
+
grub_error_push ();
unicode_str = grub_calloc (msg_len, sizeof (grub_uint32_t));
@@ -1096,3 +1102,32 @@ grub_cls (void)
(term->cls) (term);
}
}
+
+void
+grub_cls_deferred (void)
+{
+ struct grub_term_output *term;
+
+ FOR_ACTIVE_TERM_OUTPUTS(term)
+ {
+ if (term->prepare && !(term->flags & GRUB_TERM_OUTPUT_ACTIVE))
+ term->flags |= GRUB_TERM_CLEAR_PENDING;
+ else if ((term->flags & GRUB_TERM_DUMB) || (grub_env_get ("debug")))
+ {
+ grub_putcode ('\n', term);
+ grub_term_refresh (term);
+ }
+ else
+ grub_term_cls (term);
+ }
+}
+
+void
+grub_term_prepare_output (void)
+{
+ struct grub_term_output *term;
+
+ FOR_ACTIVE_TERM_OUTPUTS(term)
+ if (term->prepare)
+ term->prepare (term);
+}
diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c
index 37c4e51..52308df 100644
--- a/grub-core/term/efi/console.c
+++ b/grub-core/term/efi/console.c
@@ -140,6 +140,9 @@ grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)),
static grub_err_t
grub_prepare_for_text_output (struct grub_term_output *term)
{
+ grub_efi_simple_text_output_interface_t *o;
+ grub_efi_int32_t orig_attr;
+
if (grub_efi_is_finished)
return GRUB_ERR_BAD_DEVICE;
@@ -159,6 +162,18 @@ grub_prepare_for_text_output (struct grub_term_output *term)
if (text_colorstate != GRUB_TERM_COLOR_UNDEFINED)
grub_console_setcolorstate (term, text_colorstate);
text_mode = GRUB_TEXT_MODE_AVAILABLE;
+ term->flags |= GRUB_TERM_OUTPUT_ACTIVE;
+
+ if (term->flags & GRUB_TERM_CLEAR_PENDING)
+ {
+ term->flags &= ~GRUB_TERM_CLEAR_PENDING;
+ o = grub_efi_system_table->con_out;
+ orig_attr = o->mode->attribute;
+ o->set_attributes (o, GRUB_EFI_BACKGROUND_BLACK);
+ o->clear_screen (o);
+ o->set_attributes (o, orig_attr);
+ }
+
return GRUB_ERR_NONE;
}
@@ -435,6 +450,7 @@ grub_console_cls (struct grub_term_output *term __attribute__ ((unused)))
grub_efi_simple_text_output_interface_t *o;
grub_efi_int32_t orig_attr;
+ term->flags &= ~GRUB_TERM_CLEAR_PENDING;
if (grub_prepare_for_text_output (term) != GRUB_ERR_NONE)
return;
@@ -448,6 +464,8 @@ grub_console_cls (struct grub_term_output *term __attribute__ ((unused)))
static grub_err_t
grub_efi_console_output_fini (struct grub_term_output *term)
{
+ term->flags &= ~(GRUB_TERM_OUTPUT_ACTIVE | GRUB_TERM_CLEAR_PENDING);
+
if (text_mode != GRUB_TEXT_MODE_AVAILABLE)
return 0;
@@ -469,6 +487,7 @@ static struct grub_term_output grub_console_term_output =
{
.name = "console",
.fini = grub_efi_console_output_fini,
+ .prepare = grub_prepare_for_text_output,
.putchar = grub_console_putchar,
.getwh = grub_console_getwh,
.getxy = grub_console_getxy,
diff --git a/include/grub/term.h b/include/grub/term.h
index 7f1a14c..fd08f6f 100644
--- a/include/grub/term.h
+++ b/include/grub/term.h
@@ -102,6 +102,10 @@ grub_term_color_state;
#define GRUB_TERM_NO_EDIT (1 << 1)
/* Set when the terminal cannot do fancy things. */
#define GRUB_TERM_DUMB (1 << 2)
+/* Visible output has initialized this terminal. */
+#define GRUB_TERM_OUTPUT_ACTIVE (1 << 8)
+/* Clear when the terminal is prepared for visible output. */
+#define GRUB_TERM_CLEAR_PENDING (1 << 9)
/* Which encoding does terminal expect stream to be. */
#define GRUB_TERM_CODE_TYPE_SHIFT 3
#define GRUB_TERM_CODE_TYPE_MASK (7 << GRUB_TERM_CODE_TYPE_SHIFT)
@@ -184,6 +188,11 @@ struct grub_term_output
/* Clean up the terminal. */
grub_err_t (*fini) (struct grub_term_output *term);
+ /* Prepare the terminal for visible output. Implementations set
+ GRUB_TERM_OUTPUT_ACTIVE and consume GRUB_TERM_CLEAR_PENDING before
+ rendering. */
+ grub_err_t (*prepare) (struct grub_term_output *term);
+
/* Put a character. C is encoded in Unicode. */
void (*putchar) (struct grub_term_output *term,
const struct grub_unicode_glyph *c);
@@ -332,6 +341,8 @@ int EXPORT_FUNC(grub_getkey_noblock) (void);
int EXPORT_FUNC(grub_getkeystatus) (void);
int EXPORT_FUNC(grub_key_is_interrupt) (int key);
void grub_cls (void);
+void grub_cls_deferred (void);
+void grub_term_prepare_output (void);
void EXPORT_FUNC(grub_refresh) (void);
void grub_puts_terminal (const char *str, struct grub_term_output *term);
struct grub_term_coordinate *grub_term_save_pos (void);
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] tests: Exercise deferred configfile clear
2026-10-20 12:49 [PATCH 0/2] term: Defer configfile clear on inactive output terminals Sean Rhodes
2026-10-20 12:49 ` [PATCH 1/2] term: Defer configfile clear per output terminal Sean Rhodes
@ 2026-10-20 12:49 ` Sean Rhodes
2026-10-20 18:40 ` [PATCH 0/2] term: Defer configfile clear on inactive output terminals Leo Sandoval via Grub-devel
2 siblings, 0 replies; 4+ messages in thread
From: Sean Rhodes @ 2026-10-20 12:49 UTC (permalink / raw)
To: grub-devel
Cover silent and nested configfiles, output after redirection, active and inactive EFI terminals, empty output, explicit clears, and the verbose sleep cursor ordering.
Signed-off-by: Sean Rhodes <sean@starlabs.systems>
---
grub-core/Makefile.core.def | 5 +
grub-core/tests/deferred_clear_test.c | 317 ++++++++++++++++++++++++++
grub-core/tests/lib/functional_test.c | 1 +
3 files changed, 323 insertions(+)
create mode 100644 grub-core/tests/deferred_clear_test.c
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 1a91e53..6cead25 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -2258,6 +2258,11 @@ module = {
common = tests/sleep_test.c;
};
+module = {
+ name = deferred_clear_test;
+ common = tests/deferred_clear_test.c;
+};
+
module = {
name = xnu_uuid_test;
common = tests/xnu_uuid_test.c;
diff --git a/grub-core/tests/deferred_clear_test.c b/grub-core/tests/deferred_clear_test.c
new file mode 100644
index 0000000..1e6baa5
--- /dev/null
+++ b/grub-core/tests/deferred_clear_test.c
@@ -0,0 +1,317 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2026 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/command.h>
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/normal.h>
+#include <grub/procfs.h>
+#include <grub/test.h>
+#include <grub/term.h>
+
+GRUB_MOD_LICENSE ("GPLv3+");
+
+static const char silent_config[] = "true\n";
+static const char nested_config[] =
+ "configfile (proc)/deferred-clear-silent.cfg\n";
+static unsigned int silent_config_reads;
+static unsigned int nested_config_reads;
+
+static char *
+get_silent_config (grub_size_t *size)
+{
+ silent_config_reads++;
+ *size = sizeof (silent_config) - 1;
+ return grub_strdup (silent_config);
+}
+
+static char *
+get_nested_config (grub_size_t *size)
+{
+ nested_config_reads++;
+ *size = sizeof (nested_config) - 1;
+ return grub_strdup (nested_config);
+}
+
+static struct grub_procfs_entry silent_config_entry =
+ {
+ .name = "deferred-clear-silent.cfg",
+ .get_contents = get_silent_config
+ };
+
+static struct grub_procfs_entry nested_config_entry =
+ {
+ .name = "deferred-clear-nested.cfg",
+ .get_contents = get_nested_config
+ };
+
+struct fake_state
+{
+ struct grub_term_coordinate pos;
+ unsigned int chars;
+ unsigned int clears;
+ unsigned int chars_before_clear;
+ struct grub_term_coordinate first_gotoxy;
+ int have_gotoxy;
+ int gotoxy_changed;
+};
+
+static void
+fake_clear (struct grub_term_output *term)
+{
+ struct fake_state *state = term->data;
+
+ if (state->clears == 0)
+ state->chars_before_clear = state->chars;
+ state->clears++;
+ state->chars = 0;
+ state->pos = (struct grub_term_coordinate) { 0, 0 };
+}
+
+static grub_err_t
+fake_prepare (struct grub_term_output *term)
+{
+ if (term->flags & GRUB_TERM_OUTPUT_ACTIVE)
+ return GRUB_ERR_NONE;
+
+ term->flags |= GRUB_TERM_OUTPUT_ACTIVE;
+ if (term->flags & GRUB_TERM_CLEAR_PENDING)
+ {
+ term->flags &= ~GRUB_TERM_CLEAR_PENDING;
+ fake_clear (term);
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+static void
+fake_putchar (struct grub_term_output *term,
+ const struct grub_unicode_glyph *c)
+{
+ struct fake_state *state = term->data;
+
+ fake_prepare (term);
+ state->chars++;
+ if (c->base == '\n')
+ {
+ state->pos.x = 0;
+ state->pos.y++;
+ }
+ else
+ state->pos.x++;
+}
+
+static struct grub_term_coordinate
+fake_getwh (struct grub_term_output *term)
+{
+ fake_prepare (term);
+ return (struct grub_term_coordinate) { 80, 25 };
+}
+
+static struct grub_term_coordinate
+fake_getxy (struct grub_term_output *term)
+{
+ struct fake_state *state = term->data;
+
+ return state->pos;
+}
+
+static void
+fake_gotoxy (struct grub_term_output *term, struct grub_term_coordinate pos)
+{
+ struct fake_state *state = term->data;
+
+ fake_prepare (term);
+ if (!state->have_gotoxy)
+ {
+ state->first_gotoxy = pos;
+ state->have_gotoxy = 1;
+ }
+ else if (state->first_gotoxy.x != pos.x || state->first_gotoxy.y != pos.y)
+ state->gotoxy_changed = 1;
+ state->pos = pos;
+}
+
+static void
+fake_cls (struct grub_term_output *term)
+{
+ term->flags &= ~GRUB_TERM_CLEAR_PENDING;
+ fake_prepare (term);
+ fake_clear (term);
+}
+
+static void
+reset_term (struct grub_term_output *term, struct fake_state *state,
+ int active)
+{
+ grub_memset (state, 0, sizeof (*state));
+ state->pos = (struct grub_term_coordinate) { 7, 4 };
+ term->flags &= ~(GRUB_TERM_OUTPUT_ACTIVE | GRUB_TERM_CLEAR_PENDING);
+ if (active)
+ term->flags |= GRUB_TERM_OUTPUT_ACTIVE;
+}
+
+static void
+run_command (const char *name, int argc, char **argv)
+{
+ grub_command_t cmd = grub_command_find (name);
+
+ grub_test_assert (cmd != NULL, "%s command is unavailable", name);
+ if (cmd)
+ grub_command_execute (name, argc, argv);
+}
+
+static void
+deferred_clear_test (void)
+{
+ struct grub_term_output *saved_outputs = grub_term_outputs;
+ struct fake_state first_state, second_state;
+ struct grub_term_output second = {
+ .name = "deferred-clear-second",
+ .prepare = fake_prepare,
+ .putchar = fake_putchar,
+ .getwh = fake_getwh,
+ .getxy = fake_getxy,
+ .gotoxy = fake_gotoxy,
+ .cls = fake_cls,
+ .data = &second_state
+ };
+ struct grub_term_output first = {
+ .next = &second,
+ .name = "deferred-clear-first",
+ .prepare = fake_prepare,
+ .putchar = fake_putchar,
+ .getwh = fake_getwh,
+ .getxy = fake_getxy,
+ .gotoxy = fake_gotoxy,
+ .cls = fake_cls,
+ .data = &first_state
+ };
+ char sleep_verbose_option[] = "--verbose";
+ char sleep_value[] = "1";
+ char echo_no_newline[] = "-n";
+ char echo_value[] = "";
+ char *sleep_verbose[] = { sleep_verbose_option, sleep_value };
+ char *sleep_quiet[] = { sleep_value };
+ char *echo_empty[] = { echo_no_newline, echo_value };
+ char config_path[] = "(proc)/deferred-clear-silent.cfg";
+ char nested_config_path[] = "(proc)/deferred-clear-nested.cfg";
+ char *config[] = { config_path };
+ char *nested[] = { nested_config_path };
+
+ grub_procfs_register ("deferred-clear-silent.cfg", &silent_config_entry);
+ grub_procfs_register ("deferred-clear-nested.cfg", &nested_config_entry);
+ grub_dl_load ("configfile");
+ grub_term_outputs = &first;
+
+ reset_term (&first, &first_state, 0);
+ reset_term (&second, &second_state, 0);
+ grub_cls_deferred ();
+ run_command ("help", 0, NULL);
+ grub_test_assert (first_state.clears == 1,
+ "help did not prepare the first terminal");
+ grub_test_assert (first_state.chars_before_clear == 0,
+ "help output was cleared after rendering started");
+ grub_test_assert (second_state.clears == 1 && second_state.chars > 0 &&
+ second_state.chars_before_clear == 0,
+ "help output was cleared late on the second terminal");
+
+ reset_term (&first, &first_state, 0);
+ reset_term (&second, &second_state, 1);
+ silent_config_reads = 0;
+ run_command ("configfile", ARRAY_SIZE (config), config);
+ grub_test_assert (silent_config_reads == 1,
+ "configfile did not read its target configuration");
+ grub_test_assert (first_state.clears == 0 && first_state.chars == 0 &&
+ (first.flags & GRUB_TERM_CLEAR_PENDING),
+ "silent configfile cleared the untouched terminal");
+ grub_test_assert (second_state.clears == 1 && second_state.chars == 0,
+ "silent configfile did not clear the active terminal");
+ grub_xnputs ("visible", sizeof ("visible") - 1);
+ grub_test_assert (first_state.clears == 1 &&
+ first_state.chars_before_clear == 0 &&
+ first_state.chars == sizeof ("visible") - 1,
+ "configfile clear did not precede later output");
+ grub_test_assert (second_state.clears == 1 &&
+ second_state.chars == sizeof ("visible") - 1,
+ "configfile cleared the active terminal again before output");
+
+ reset_term (&first, &first_state, 0);
+ reset_term (&second, &second_state, 0);
+ silent_config_reads = 0;
+ nested_config_reads = 0;
+ run_command ("configfile", ARRAY_SIZE (nested), nested);
+ grub_test_assert (nested_config_reads == 1 && silent_config_reads == 1,
+ "nested configfile redirect did not read both configurations");
+ grub_test_assert (first_state.clears == 0 && first_state.chars == 0 &&
+ (first.flags & GRUB_TERM_CLEAR_PENDING),
+ "nested silent configfile cleared the untouched terminal");
+
+ reset_term (&first, &first_state, 0);
+ reset_term (&second, &second_state, 0);
+ grub_cls_deferred ();
+ grub_xnputs ("direct", sizeof ("direct") - 1);
+ grub_printf (" formatted\n");
+ grub_test_assert (first_state.clears == 1 &&
+ first_state.chars_before_clear == 0 &&
+ first_state.chars > sizeof ("direct") - 1,
+ "formatted output erased direct output");
+
+ reset_term (&first, &first_state, 0);
+ reset_term (&second, &second_state, 0);
+ grub_cls_deferred ();
+ run_command ("sleep", ARRAY_SIZE (sleep_verbose), sleep_verbose);
+ grub_test_assert (first_state.clears == 1 &&
+ first_state.chars_before_clear == 0,
+ "verbose sleep prepared the display too late");
+ grub_test_assert (!first_state.gotoxy_changed,
+ "verbose sleep restored different cursor positions");
+ grub_test_assert (first_state.have_gotoxy &&
+ first_state.first_gotoxy.x == 0 &&
+ first_state.first_gotoxy.y == 0 &&
+ second_state.have_gotoxy &&
+ second_state.first_gotoxy.x == 0 &&
+ second_state.first_gotoxy.y == 0,
+ "verbose sleep saved its cursor position before preparation");
+
+ reset_term (&first, &first_state, 0);
+ reset_term (&second, &second_state, 0);
+ grub_cls_deferred ();
+ run_command ("sleep", ARRAY_SIZE (sleep_quiet), sleep_quiet);
+ grub_test_assert (first_state.clears == 0 &&
+ (first.flags & GRUB_TERM_CLEAR_PENDING),
+ "non-verbose sleep prepared the display");
+ run_command ("echo", ARRAY_SIZE (echo_empty), echo_empty);
+ grub_test_assert (first_state.clears == 0 && first_state.chars == 0,
+ "empty echo prepared the display (%u clears, %u chars)",
+ first_state.clears, first_state.chars);
+
+ reset_term (&first, &first_state, 0);
+ reset_term (&second, &second_state, 0);
+ grub_cls_deferred ();
+ grub_cls ();
+ grub_test_assert (first_state.clears == 1 &&
+ !(first.flags & GRUB_TERM_CLEAR_PENDING),
+ "explicit clear did not replace the deferred clear");
+
+ grub_procfs_unregister (&nested_config_entry);
+ grub_procfs_unregister (&silent_config_entry);
+ grub_term_outputs = saved_outputs;
+}
+
+GRUB_FUNCTIONAL_TEST (deferred_clear_test, deferred_clear_test);
diff --git a/grub-core/tests/lib/functional_test.c b/grub-core/tests/lib/functional_test.c
index 4214332..8429eff 100644
--- a/grub-core/tests/lib/functional_test.c
+++ b/grub-core/tests/lib/functional_test.c
@@ -75,6 +75,7 @@ grub_functional_all_tests (grub_extcmd_context_t ctxt __attribute__ ((unused)),
grub_dl_load ("signature_test");
grub_dl_load ("appended_signature_test");
grub_dl_load ("sleep_test");
+ grub_dl_load ("deferred_clear_test");
grub_dl_load ("bswap_test");
grub_dl_load ("ctz_test");
grub_dl_load ("cmp_test");
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 0/2] term: Defer configfile clear on inactive output terminals
2026-10-20 12:49 [PATCH 0/2] term: Defer configfile clear on inactive output terminals Sean Rhodes
2026-10-20 12:49 ` [PATCH 1/2] term: Defer configfile clear per output terminal Sean Rhodes
2026-10-20 12:49 ` [PATCH 2/2] tests: Exercise deferred configfile clear Sean Rhodes
@ 2026-10-20 18:40 ` Leo Sandoval via Grub-devel
2 siblings, 0 replies; 4+ messages in thread
From: Leo Sandoval via Grub-devel @ 2026-10-20 18:40 UTC (permalink / raw)
To: The development of GNU GRUB; +Cc: Leo Sandoval
[-- Attachment #1.1: Type: text/plain, Size: 1884 bytes --]
Hi Sean,
Contributions are now handled via Merge Requests (MR):
https://gitlab.freedesktop.org/gnu-grub/grub/-/blob/master/CONTRIBUTING
Which is : open an account and ask for verification, fork the main repo,
create a branch then open a MR based on it.
Leo
On Tue, Oct 20, 2026 at 7:34 AM Sean Rhodes <sean@starlabs.systems> wrote:
> A configfile can run before its target has selected visible output. On EFI,
> clearing immediately activates text mode and erases the firmware splash
> even
> when the target proceeds with a hidden-menu autoboot.
>
> Defer the clear on inactive output terminals until they prepare for visible
> output. Active terminals retain the existing immediate-clear behaviour. The
> second patch adds functional coverage for silent and nested configfiles,
> subsequent output, multiple terminals, explicit clears, empty output, and
> verbose sleep cursor ordering.
>
> Sean Rhodes (2):
> term: Defer configfile clear per output terminal
> tests: Exercise deferred configfile clear
>
> Sean Rhodes (2):
> term: Defer configfile clear per output terminal
> tests: Exercise deferred configfile clear
>
> grub-core/Makefile.core.def | 5 +
> grub-core/commands/configfile.c | 3 +-
> grub-core/commands/sleep.c | 4 +
> grub-core/normal/term.c | 35 +++
> grub-core/term/efi/console.c | 19 ++
> grub-core/tests/deferred_clear_test.c | 317 ++++++++++++++++++++++++++
> grub-core/tests/lib/functional_test.c | 1 +
> include/grub/term.h | 11 +
> 8 files changed, 394 insertions(+), 1 deletion(-)
> create mode 100644 grub-core/tests/deferred_clear_test.c
>
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel
>
>
[-- Attachment #1.2: Type: text/html, Size: 2627 bytes --]
[-- Attachment #2: Type: text/plain, Size: 141 bytes --]
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-10-20 18:41 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-20 12:49 [PATCH 0/2] term: Defer configfile clear on inactive output terminals Sean Rhodes
2026-10-20 12:49 ` [PATCH 1/2] term: Defer configfile clear per output terminal Sean Rhodes
2026-10-20 12:49 ` [PATCH 2/2] tests: Exercise deferred configfile clear Sean Rhodes
2026-10-20 18:40 ` [PATCH 0/2] term: Defer configfile clear on inactive output terminals Leo Sandoval via Grub-devel
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.