Fixed word wrapping emitting a blank row for trailing whitespace - #177

Merged
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fix/issue-159-wrap-blank-row
Aug 27, 2026
Merged

Fixed word wrapping emitting a blank row for trailing whitespace#177
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fix/issue-159-wrap-blank-row

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

What this fixes

b8bb23b8 (#159) fixed issue #130 by letting the overflow branch of _gx_multi_line_text_view_display_info_get() run when an ASCII space is the character that overflows the available width. That branch consumes the space and any consecutive spaces without adding them to the row width — correct — and then breaks.

When the whitespace ran to the end of the source line, the line terminator was left behind. The next call started on it, hit the GX_KEY_LINE_FEED case immediately, and returned a row of one byte and zero width: a blank line that is not in the text.

The overflow branch now takes the line terminator with the whitespace when nothing else separates them, handling both a bare line feed and a \r\n pair, with the second byte guarded on the remaining length. gx_text_display_width is untouched, so the #130 fix stands.

Why two golden tests have been red since June

guix_ml_text_view_32bpp (268 of 300 frames) and guix_bidi_text_draw_32bpp (144 of 429) have failed in every CI run since #159 landed.

Two phantom rows appear in the guix_ml_text_view_32bpp fixture, at string offsets 2992 and 23988 of readme_guix_generic.txt: ...Improved internal logic. with twelve trailing spaces, and ...cursor_pos_calculate.c with one. Both were confirmed with a conditional breakpoint on display_number == 1 && display_width == 0 preceded by a space — it fires exactly twice on the pre-fix code and never after.

Nothing inside GUIX reads gx_text_display_width; every caller uses only gx_text_display_number, to advance its index. So the row count alone governs where every row starts, and two extra rows change the scrollbar's value-to-pixel mapping. Every scroll step then lands at a slightly different pixel offset and the whole text block is drawn a few pixels up or down. Of the 300 frames, 297 were a pure vertical shift of otherwise identical text; only 3 were laid out differently, and those 3 are the two places above.

No golden data is regenerated.gx_multi_line_text_view_text_total_rows for the long text view goes back from 2226 to 2224, and both tests pass against their existing golden files.

Test work

guix_ml_text_view_word_wrap_no_output did not protect #159's fix — it passed on the pre-#159 code too. Its available_width was one pixel too generous (a_width + space_width), so the over-wide row the old code produced measured exactly available_width and still satisfied width <= available_width.

It is now a_width + space_width - 1, and three cases are added:

  1. a line feed terminator,
  2. a \r\n terminator,
  3. the total row count _gx_multi_line_text_view_string_total_rows_compute() derives from them — the quantity the golden frames actually depend on, and the only one of the three a unit test can pin without golden data.

Verified to discriminate in both directions by rebuilding against each source state:

Source stateTest outcome
pre-b8bb23b8Fails 4 width <= available_width assertions (issue #130)
b8bb23b8 as shippedFails LF row (2 bytes, not 3), \r\n row (2, not 4), row count (3, not 2)
this PRPasses

Verification

Linux, all eighteen build configurations, 1847 tests, no failures.

ConfigurationResult
default_build_coverage733/733 — guix_ml_text_view_32bpp green against unmodified golden
dynamic_bidi_text_build3/3 — guix_bidi_text_draw_32bpp green against unmodified golden
no_utf8_build_coverage135/135
the other 15all pass

One coverage boundary worth naming: the unit test builds against the all_widgets demo, which is not in NO_UTF8_DEMOS, so it runs in default_build_coverage and disable_error_check_build but not in the GX_UTF8_SUPPORT-off configurations. The changed code is common to both paths — only the surrounding character advance differs — and no_utf8_build_coverage covers it through its 135 golden tests.

No documentation change is required: _gx_multi_line_text_view_display_info_get is internal, and the GUIX documentation does not describe multi-line text view wrapping behaviour for trailing whitespace.

b8bb23b (eclipse-threadx#159) fixed issue eclipse-threadx#130 by letting the overflow branch of
_gx_multi_line_text_view_display_info_get() run when an ASCII space is the
character that overflows the available width. That branch consumes the space
and any consecutive spaces without adding them to the row width, which is
correct, and then breaks. When the whitespace ran to the end of the source
line, the line terminator was left behind: the next call started on it, hit
the GX_KEY_LINE_FEED case immediately and returned a row of one byte and zero
width, which draws as a blank line that is not in the text.
The overflow branch now takes the line terminator with the whitespace when
nothing else separates them, handling a bare line feed and a carriage return /
line feed pair, and guarding the second byte on the remaining length -- unlike
the pre-existing GX_KEY_CARRIAGE_RETURN case earlier in the same loop, which
reads ch.gx_string_ptr[1] unchecked. gx_text_display_width is untouched, so the
issue eclipse-threadx#130 fix stands.
Two such rows appear in the guix_ml_text_view_32bpp fixture, at string offsets
2992 and 23988 of readme_guix_generic.txt: "...Improved internal logic." with
twelve trailing spaces, and "...cursor_pos_calculate.c" with one. Both were
confirmed with a conditional breakpoint on display_number == 1 and
display_width == 0 preceded by a space, which fires exactly twice on the
pre-fix code and never after.
The two extra rows are why 268 of that test's 300 frames and 144 of
guix_bidi_text_draw_32bpp's 429 frames have differed from their golden data
since June. Nothing inside GUIX reads gx_text_display_width -- every caller
uses only gx_text_display_number, to advance its index -- so the row count
alone governs where every row starts, and two extra rows change the
scrollbar's value-to-pixel mapping. Every scroll step then lands at a slightly
different pixel offset and the whole text block is drawn a few pixels up or
down. Of the 300 frames, 297 were a pure vertical shift of otherwise identical
text; only 3 were laid out differently, and those 3 are the two places above.
No golden data is regenerated. gx_multi_line_text_view_text_total_rows for the
long text view goes back from 2226 to 2224, and both tests pass against their
existing golden files.
guix_ml_text_view_word_wrap_no_output did not protect eclipse-threadx#159's fix: it passed on
the pre-eclipse-threadx#159 code as well. Its available_width was one pixel too generous --
a_width + space_width, so the over-wide row the old code produced measured
exactly available_width and still satisfied "width <= available_width". It is
now a_width + space_width - 1, which makes appending the space genuinely
overflow, and three cases are added: a line feed terminator, a carriage return
/ line feed terminator, and the total row count that
_gx_multi_line_text_view_string_total_rows_compute() derives from them. That
last one is the quantity the golden frames actually depend on, and the only
one of the three a unit test can pin without golden data.
The test was verified to discriminate in both directions by rebuilding against
each. Against the pre-eclipse-threadx#159 source it fails four width assertions, which is
issue eclipse-threadx#130. Against eclipse-threadx#159 as shipped it fails the line feed row (2 bytes, not
3), the carriage return / line feed row (2, not 4) and the row count (3, not
2). It passes only with both fixes in place.
Verified on Linux across all eighteen build configurations, 1847 tests, no
failures. default_build_coverage 733/733, dynamic_bidi_text_build 3/3
including guix_bidi_text_draw_32bpp, no_utf8_build_coverage 135/135.
One coverage boundary worth naming: the unit test builds against the
all_widgets demo, which is not in NO_UTF8_DEMOS, so it runs in
default_build_coverage and disable_error_check_build but not in the
GX_UTF8_SUPPORT-off configurations. The changed code is common to both paths
-- only the surrounding character advance differs -- and no_utf8_build_coverage
covers it through its 135 golden tests.
No documentation change is required. _gx_multi_line_text_view_display_info_get
is internal, and the GUIX documentation does not describe multi-line text view
wrapping behaviour for trailing whitespace.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@fdesbiens
fdesbiens merged commit 1bae371 into eclipse-threadx:devAug 27, 2026
3 checks passed
@fdesbiens
fdesbiens deleted the fix/issue-159-wrap-blank-row branch August 27, 2026 15:48
Sign up for freeto 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.

1 participant

@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Fixed word wrapping emitting a blank row for trailing whitespace - #177

Merged
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fix/issue-159-wrap-blank-row
Aug 27, 2026
Merged

Fixed word wrapping emitting a blank row for trailing whitespace#177
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fix/issue-159-wrap-blank-row

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

What this fixes

b8bb23b8 (#159) fixed issue #130 by letting the overflow branch of _gx_multi_line_text_view_display_info_get() run when an ASCII space is the character that overflows the available width. That branch consumes the space and any consecutive spaces without adding them to the row width — correct — and then breaks.

When the whitespace ran to the end of the source line, the line terminator was left behind. The next call started on it, hit the GX_KEY_LINE_FEED case immediately, and returned a row of one byte and zero width: a blank line that is not in the text.

The overflow branch now takes the line terminator with the whitespace when nothing else separates them, handling both a bare line feed and a \r\n pair, with the second byte guarded on the remaining length. gx_text_display_width is untouched, so the #130 fix stands.

Why two golden tests have been red since June

guix_ml_text_view_32bpp (268 of 300 frames) and guix_bidi_text_draw_32bpp (144 of 429) have failed in every CI run since #159 landed.

Two phantom rows appear in the guix_ml_text_view_32bpp fixture, at string offsets 2992 and 23988 of readme_guix_generic.txt: ...Improved internal logic. with twelve trailing spaces, and ...cursor_pos_calculate.c with one. Both were confirmed with a conditional breakpoint on display_number == 1 && display_width == 0 preceded by a space — it fires exactly twice on the pre-fix code and never after.

Nothing inside GUIX reads gx_text_display_width; every caller uses only gx_text_display_number, to advance its index. So the row count alone governs where every row starts, and two extra rows change the scrollbar's value-to-pixel mapping. Every scroll step then lands at a slightly different pixel offset and the whole text block is drawn a few pixels up or down. Of the 300 frames, 297 were a pure vertical shift of otherwise identical text; only 3 were laid out differently, and those 3 are the two places above.

No golden data is regenerated.gx_multi_line_text_view_text_total_rows for the long text view goes back from 2226 to 2224, and both tests pass against their existing golden files.

Test work

guix_ml_text_view_word_wrap_no_output did not protect #159's fix — it passed on the pre-#159 code too. Its available_width was one pixel too generous (a_width + space_width), so the over-wide row the old code produced measured exactly available_width and still satisfied width <= available_width.

It is now a_width + space_width - 1, and three cases are added:

  1. a line feed terminator,
  2. a \r\n terminator,
  3. the total row count _gx_multi_line_text_view_string_total_rows_compute() derives from them — the quantity the golden frames actually depend on, and the only one of the three a unit test can pin without golden data.

Verified to discriminate in both directions by rebuilding against each source state:

Source stateTest outcome
pre-b8bb23b8Fails 4 width <= available_width assertions (issue #130)
b8bb23b8 as shippedFails LF row (2 bytes, not 3), \r\n row (2, not 4), row count (3, not 2)
this PRPasses

Verification

Linux, all eighteen build configurations, 1847 tests, no failures.

ConfigurationResult
default_build_coverage733/733 — guix_ml_text_view_32bpp green against unmodified golden
dynamic_bidi_text_build3/3 — guix_bidi_text_draw_32bpp green against unmodified golden
no_utf8_build_coverage135/135
the other 15all pass

One coverage boundary worth naming: the unit test builds against the all_widgets demo, which is not in NO_UTF8_DEMOS, so it runs in default_build_coverage and disable_error_check_build but not in the GX_UTF8_SUPPORT-off configurations. The changed code is common to both paths — only the surrounding character advance differs — and no_utf8_build_coverage covers it through its 135 golden tests.

No documentation change is required: _gx_multi_line_text_view_display_info_get is internal, and the GUIX documentation does not describe multi-line text view wrapping behaviour for trailing whitespace.

b8bb23b (eclipse-threadx#159) fixed issue eclipse-threadx#130 by letting the overflow branch of
_gx_multi_line_text_view_display_info_get() run when an ASCII space is the
character that overflows the available width. That branch consumes the space
and any consecutive spaces without adding them to the row width, which is
correct, and then breaks. When the whitespace ran to the end of the source
line, the line terminator was left behind: the next call started on it, hit
the GX_KEY_LINE_FEED case immediately and returned a row of one byte and zero
width, which draws as a blank line that is not in the text.
The overflow branch now takes the line terminator with the whitespace when
nothing else separates them, handling a bare line feed and a carriage return /
line feed pair, and guarding the second byte on the remaining length -- unlike
the pre-existing GX_KEY_CARRIAGE_RETURN case earlier in the same loop, which
reads ch.gx_string_ptr[1] unchecked. gx_text_display_width is untouched, so the
issue eclipse-threadx#130 fix stands.
Two such rows appear in the guix_ml_text_view_32bpp fixture, at string offsets
2992 and 23988 of readme_guix_generic.txt: "...Improved internal logic." with
twelve trailing spaces, and "...cursor_pos_calculate.c" with one. Both were
confirmed with a conditional breakpoint on display_number == 1 and
display_width == 0 preceded by a space, which fires exactly twice on the
pre-fix code and never after.
The two extra rows are why 268 of that test's 300 frames and 144 of
guix_bidi_text_draw_32bpp's 429 frames have differed from their golden data
since June. Nothing inside GUIX reads gx_text_display_width -- every caller
uses only gx_text_display_number, to advance its index -- so the row count
alone governs where every row starts, and two extra rows change the
scrollbar's value-to-pixel mapping. Every scroll step then lands at a slightly
different pixel offset and the whole text block is drawn a few pixels up or
down. Of the 300 frames, 297 were a pure vertical shift of otherwise identical
text; only 3 were laid out differently, and those 3 are the two places above.
No golden data is regenerated. gx_multi_line_text_view_text_total_rows for the
long text view goes back from 2226 to 2224, and both tests pass against their
existing golden files.
guix_ml_text_view_word_wrap_no_output did not protect eclipse-threadx#159's fix: it passed on
the pre-eclipse-threadx#159 code as well. Its available_width was one pixel too generous --
a_width + space_width, so the over-wide row the old code produced measured
exactly available_width and still satisfied "width <= available_width". It is
now a_width + space_width - 1, which makes appending the space genuinely
overflow, and three cases are added: a line feed terminator, a carriage return
/ line feed terminator, and the total row count that
_gx_multi_line_text_view_string_total_rows_compute() derives from them. That
last one is the quantity the golden frames actually depend on, and the only
one of the three a unit test can pin without golden data.
The test was verified to discriminate in both directions by rebuilding against
each. Against the pre-eclipse-threadx#159 source it fails four width assertions, which is
issue eclipse-threadx#130. Against eclipse-threadx#159 as shipped it fails the line feed row (2 bytes, not
3), the carriage return / line feed row (2, not 4) and the row count (3, not
2). It passes only with both fixes in place.
Verified on Linux across all eighteen build configurations, 1847 tests, no
failures. default_build_coverage 733/733, dynamic_bidi_text_build 3/3
including guix_bidi_text_draw_32bpp, no_utf8_build_coverage 135/135.
One coverage boundary worth naming: the unit test builds against the
all_widgets demo, which is not in NO_UTF8_DEMOS, so it runs in
default_build_coverage and disable_error_check_build but not in the
GX_UTF8_SUPPORT-off configurations. The changed code is common to both paths
-- only the surrounding character advance differs -- and no_utf8_build_coverage
covers it through its 135 golden tests.
No documentation change is required. _gx_multi_line_text_view_display_info_get
is internal, and the GUIX documentation does not describe multi-line text view
wrapping behaviour for trailing whitespace.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@fdesbiens
fdesbiens merged commit 1bae371 into eclipse-threadx:devAug 27, 2026
3 checks passed
@fdesbiens
fdesbiens deleted the fix/issue-159-wrap-blank-row branch August 27, 2026 15:48
Sign up for freeto 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.

1 participant

@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fixed word wrapping emitting a blank row for trailing whitespace - #177

Merged
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fix/issue-159-wrap-blank-row
Aug 27, 2026
Merged

Fixed word wrapping emitting a blank row for trailing whitespace#177
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fix/issue-159-wrap-blank-row

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

What this fixes

b8bb23b8 (#159) fixed issue #130 by letting the overflow branch of _gx_multi_line_text_view_display_info_get() run when an ASCII space is the character that overflows the available width. That branch consumes the space and any consecutive spaces without adding them to the row width — correct — and then breaks.

When the whitespace ran to the end of the source line, the line terminator was left behind. The next call started on it, hit the GX_KEY_LINE_FEED case immediately, and returned a row of one byte and zero width: a blank line that is not in the text.

The overflow branch now takes the line terminator with the whitespace when nothing else separates them, handling both a bare line feed and a \r\n pair, with the second byte guarded on the remaining length. gx_text_display_width is untouched, so the #130 fix stands.

Why two golden tests have been red since June

guix_ml_text_view_32bpp (268 of 300 frames) and guix_bidi_text_draw_32bpp (144 of 429) have failed in every CI run since #159 landed.

Two phantom rows appear in the guix_ml_text_view_32bpp fixture, at string offsets 2992 and 23988 of readme_guix_generic.txt: ...Improved internal logic. with twelve trailing spaces, and ...cursor_pos_calculate.c with one. Both were confirmed with a conditional breakpoint on display_number == 1 && display_width == 0 preceded by a space — it fires exactly twice on the pre-fix code and never after.

Nothing inside GUIX reads gx_text_display_width; every caller uses only gx_text_display_number, to advance its index. So the row count alone governs where every row starts, and two extra rows change the scrollbar's value-to-pixel mapping. Every scroll step then lands at a slightly different pixel offset and the whole text block is drawn a few pixels up or down. Of the 300 frames, 297 were a pure vertical shift of otherwise identical text; only 3 were laid out differently, and those 3 are the two places above.

No golden data is regenerated.gx_multi_line_text_view_text_total_rows for the long text view goes back from 2226 to 2224, and both tests pass against their existing golden files.

Test work

guix_ml_text_view_word_wrap_no_output did not protect #159's fix — it passed on the pre-#159 code too. Its available_width was one pixel too generous (a_width + space_width), so the over-wide row the old code produced measured exactly available_width and still satisfied width <= available_width.

It is now a_width + space_width - 1, and three cases are added:

  1. a line feed terminator,
  2. a \r\n terminator,
  3. the total row count _gx_multi_line_text_view_string_total_rows_compute() derives from them — the quantity the golden frames actually depend on, and the only one of the three a unit test can pin without golden data.

Verified to discriminate in both directions by rebuilding against each source state:

Source stateTest outcome
pre-b8bb23b8Fails 4 width <= available_width assertions (issue #130)
b8bb23b8 as shippedFails LF row (2 bytes, not 3), \r\n row (2, not 4), row count (3, not 2)
this PRPasses

Verification

Linux, all eighteen build configurations, 1847 tests, no failures.

ConfigurationResult
default_build_coverage733/733 — guix_ml_text_view_32bpp green against unmodified golden
dynamic_bidi_text_build3/3 — guix_bidi_text_draw_32bpp green against unmodified golden
no_utf8_build_coverage135/135
the other 15all pass

One coverage boundary worth naming: the unit test builds against the all_widgets demo, which is not in NO_UTF8_DEMOS, so it runs in default_build_coverage and disable_error_check_build but not in the GX_UTF8_SUPPORT-off configurations. The changed code is common to both paths — only the surrounding character advance differs — and no_utf8_build_coverage covers it through its 135 golden tests.

No documentation change is required: _gx_multi_line_text_view_display_info_get is internal, and the GUIX documentation does not describe multi-line text view wrapping behaviour for trailing whitespace.

b8bb23b (eclipse-threadx#159) fixed issue eclipse-threadx#130 by letting the overflow branch of
_gx_multi_line_text_view_display_info_get() run when an ASCII space is the
character that overflows the available width. That branch consumes the space
and any consecutive spaces without adding them to the row width, which is
correct, and then breaks. When the whitespace ran to the end of the source
line, the line terminator was left behind: the next call started on it, hit
the GX_KEY_LINE_FEED case immediately and returned a row of one byte and zero
width, which draws as a blank line that is not in the text.
The overflow branch now takes the line terminator with the whitespace when
nothing else separates them, handling a bare line feed and a carriage return /
line feed pair, and guarding the second byte on the remaining length -- unlike
the pre-existing GX_KEY_CARRIAGE_RETURN case earlier in the same loop, which
reads ch.gx_string_ptr[1] unchecked. gx_text_display_width is untouched, so the
issue eclipse-threadx#130 fix stands.
Two such rows appear in the guix_ml_text_view_32bpp fixture, at string offsets
2992 and 23988 of readme_guix_generic.txt: "...Improved internal logic." with
twelve trailing spaces, and "...cursor_pos_calculate.c" with one. Both were
confirmed with a conditional breakpoint on display_number == 1 and
display_width == 0 preceded by a space, which fires exactly twice on the
pre-fix code and never after.
The two extra rows are why 268 of that test's 300 frames and 144 of
guix_bidi_text_draw_32bpp's 429 frames have differed from their golden data
since June. Nothing inside GUIX reads gx_text_display_width -- every caller
uses only gx_text_display_number, to advance its index -- so the row count
alone governs where every row starts, and two extra rows change the
scrollbar's value-to-pixel mapping. Every scroll step then lands at a slightly
different pixel offset and the whole text block is drawn a few pixels up or
down. Of the 300 frames, 297 were a pure vertical shift of otherwise identical
text; only 3 were laid out differently, and those 3 are the two places above.
No golden data is regenerated. gx_multi_line_text_view_text_total_rows for the
long text view goes back from 2226 to 2224, and both tests pass against their
existing golden files.
guix_ml_text_view_word_wrap_no_output did not protect eclipse-threadx#159's fix: it passed on
the pre-eclipse-threadx#159 code as well. Its available_width was one pixel too generous --
a_width + space_width, so the over-wide row the old code produced measured
exactly available_width and still satisfied "width <= available_width". It is
now a_width + space_width - 1, which makes appending the space genuinely
overflow, and three cases are added: a line feed terminator, a carriage return
/ line feed terminator, and the total row count that
_gx_multi_line_text_view_string_total_rows_compute() derives from them. That
last one is the quantity the golden frames actually depend on, and the only
one of the three a unit test can pin without golden data.
The test was verified to discriminate in both directions by rebuilding against
each. Against the pre-eclipse-threadx#159 source it fails four width assertions, which is
issue eclipse-threadx#130. Against eclipse-threadx#159 as shipped it fails the line feed row (2 bytes, not
3), the carriage return / line feed row (2, not 4) and the row count (3, not
2). It passes only with both fixes in place.
Verified on Linux across all eighteen build configurations, 1847 tests, no
failures. default_build_coverage 733/733, dynamic_bidi_text_build 3/3
including guix_bidi_text_draw_32bpp, no_utf8_build_coverage 135/135.
One coverage boundary worth naming: the unit test builds against the
all_widgets demo, which is not in NO_UTF8_DEMOS, so it runs in
default_build_coverage and disable_error_check_build but not in the
GX_UTF8_SUPPORT-off configurations. The changed code is common to both paths
-- only the surrounding character advance differs -- and no_utf8_build_coverage
covers it through its 135 golden tests.
No documentation change is required. _gx_multi_line_text_view_display_info_get
is internal, and the GUIX documentation does not describe multi-line text view
wrapping behaviour for trailing whitespace.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@fdesbiens
fdesbiens merged commit 1bae371 into eclipse-threadx:devAug 27, 2026
3 checks passed
@fdesbiens
fdesbiens deleted the fix/issue-159-wrap-blank-row branch August 27, 2026 15:48
Sign up for freeto 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.

1 participant

@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fixed word wrapping emitting a blank row for trailing whitespace - #177

Merged
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fix/issue-159-wrap-blank-row
Aug 27, 2026
Merged

Fixed word wrapping emitting a blank row for trailing whitespace#177
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fix/issue-159-wrap-blank-row

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

What this fixes

b8bb23b8 (#159) fixed issue #130 by letting the overflow branch of _gx_multi_line_text_view_display_info_get() run when an ASCII space is the character that overflows the available width. That branch consumes the space and any consecutive spaces without adding them to the row width — correct — and then breaks.

When the whitespace ran to the end of the source line, the line terminator was left behind. The next call started on it, hit the GX_KEY_LINE_FEED case immediately, and returned a row of one byte and zero width: a blank line that is not in the text.

The overflow branch now takes the line terminator with the whitespace when nothing else separates them, handling both a bare line feed and a \r\n pair, with the second byte guarded on the remaining length. gx_text_display_width is untouched, so the #130 fix stands.

Why two golden tests have been red since June

guix_ml_text_view_32bpp (268 of 300 frames) and guix_bidi_text_draw_32bpp (144 of 429) have failed in every CI run since #159 landed.

Two phantom rows appear in the guix_ml_text_view_32bpp fixture, at string offsets 2992 and 23988 of readme_guix_generic.txt: ...Improved internal logic. with twelve trailing spaces, and ...cursor_pos_calculate.c with one. Both were confirmed with a conditional breakpoint on display_number == 1 && display_width == 0 preceded by a space — it fires exactly twice on the pre-fix code and never after.

Nothing inside GUIX reads gx_text_display_width; every caller uses only gx_text_display_number, to advance its index. So the row count alone governs where every row starts, and two extra rows change the scrollbar's value-to-pixel mapping. Every scroll step then lands at a slightly different pixel offset and the whole text block is drawn a few pixels up or down. Of the 300 frames, 297 were a pure vertical shift of otherwise identical text; only 3 were laid out differently, and those 3 are the two places above.

No golden data is regenerated.gx_multi_line_text_view_text_total_rows for the long text view goes back from 2226 to 2224, and both tests pass against their existing golden files.

Test work

guix_ml_text_view_word_wrap_no_output did not protect #159's fix — it passed on the pre-#159 code too. Its available_width was one pixel too generous (a_width + space_width), so the over-wide row the old code produced measured exactly available_width and still satisfied width <= available_width.

It is now a_width + space_width - 1, and three cases are added:

  1. a line feed terminator,
  2. a \r\n terminator,
  3. the total row count _gx_multi_line_text_view_string_total_rows_compute() derives from them — the quantity the golden frames actually depend on, and the only one of the three a unit test can pin without golden data.

Verified to discriminate in both directions by rebuilding against each source state:

Source stateTest outcome
pre-b8bb23b8Fails 4 width <= available_width assertions (issue #130)
b8bb23b8 as shippedFails LF row (2 bytes, not 3), \r\n row (2, not 4), row count (3, not 2)
this PRPasses

Verification

Linux, all eighteen build configurations, 1847 tests, no failures.

ConfigurationResult
default_build_coverage733/733 — guix_ml_text_view_32bpp green against unmodified golden
dynamic_bidi_text_build3/3 — guix_bidi_text_draw_32bpp green against unmodified golden
no_utf8_build_coverage135/135
the other 15all pass

One coverage boundary worth naming: the unit test builds against the all_widgets demo, which is not in NO_UTF8_DEMOS, so it runs in default_build_coverage and disable_error_check_build but not in the GX_UTF8_SUPPORT-off configurations. The changed code is common to both paths — only the surrounding character advance differs — and no_utf8_build_coverage covers it through its 135 golden tests.

No documentation change is required: _gx_multi_line_text_view_display_info_get is internal, and the GUIX documentation does not describe multi-line text view wrapping behaviour for trailing whitespace.

b8bb23b (eclipse-threadx#159) fixed issue eclipse-threadx#130 by letting the overflow branch of
_gx_multi_line_text_view_display_info_get() run when an ASCII space is the
character that overflows the available width. That branch consumes the space
and any consecutive spaces without adding them to the row width, which is
correct, and then breaks. When the whitespace ran to the end of the source
line, the line terminator was left behind: the next call started on it, hit
the GX_KEY_LINE_FEED case immediately and returned a row of one byte and zero
width, which draws as a blank line that is not in the text.
The overflow branch now takes the line terminator with the whitespace when
nothing else separates them, handling a bare line feed and a carriage return /
line feed pair, and guarding the second byte on the remaining length -- unlike
the pre-existing GX_KEY_CARRIAGE_RETURN case earlier in the same loop, which
reads ch.gx_string_ptr[1] unchecked. gx_text_display_width is untouched, so the
issue eclipse-threadx#130 fix stands.
Two such rows appear in the guix_ml_text_view_32bpp fixture, at string offsets
2992 and 23988 of readme_guix_generic.txt: "...Improved internal logic." with
twelve trailing spaces, and "...cursor_pos_calculate.c" with one. Both were
confirmed with a conditional breakpoint on display_number == 1 and
display_width == 0 preceded by a space, which fires exactly twice on the
pre-fix code and never after.
The two extra rows are why 268 of that test's 300 frames and 144 of
guix_bidi_text_draw_32bpp's 429 frames have differed from their golden data
since June. Nothing inside GUIX reads gx_text_display_width -- every caller
uses only gx_text_display_number, to advance its index -- so the row count
alone governs where every row starts, and two extra rows change the
scrollbar's value-to-pixel mapping. Every scroll step then lands at a slightly
different pixel offset and the whole text block is drawn a few pixels up or
down. Of the 300 frames, 297 were a pure vertical shift of otherwise identical
text; only 3 were laid out differently, and those 3 are the two places above.
No golden data is regenerated. gx_multi_line_text_view_text_total_rows for the
long text view goes back from 2226 to 2224, and both tests pass against their
existing golden files.
guix_ml_text_view_word_wrap_no_output did not protect eclipse-threadx#159's fix: it passed on
the pre-eclipse-threadx#159 code as well. Its available_width was one pixel too generous --
a_width + space_width, so the over-wide row the old code produced measured
exactly available_width and still satisfied "width <= available_width". It is
now a_width + space_width - 1, which makes appending the space genuinely
overflow, and three cases are added: a line feed terminator, a carriage return
/ line feed terminator, and the total row count that
_gx_multi_line_text_view_string_total_rows_compute() derives from them. That
last one is the quantity the golden frames actually depend on, and the only
one of the three a unit test can pin without golden data.
The test was verified to discriminate in both directions by rebuilding against
each. Against the pre-eclipse-threadx#159 source it fails four width assertions, which is
issue eclipse-threadx#130. Against eclipse-threadx#159 as shipped it fails the line feed row (2 bytes, not
3), the carriage return / line feed row (2, not 4) and the row count (3, not
2). It passes only with both fixes in place.
Verified on Linux across all eighteen build configurations, 1847 tests, no
failures. default_build_coverage 733/733, dynamic_bidi_text_build 3/3
including guix_bidi_text_draw_32bpp, no_utf8_build_coverage 135/135.
One coverage boundary worth naming: the unit test builds against the
all_widgets demo, which is not in NO_UTF8_DEMOS, so it runs in
default_build_coverage and disable_error_check_build but not in the
GX_UTF8_SUPPORT-off configurations. The changed code is common to both paths
-- only the surrounding character advance differs -- and no_utf8_build_coverage
covers it through its 135 golden tests.
No documentation change is required. _gx_multi_line_text_view_display_info_get
is internal, and the GUIX documentation does not describe multi-line text view
wrapping behaviour for trailing whitespace.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@fdesbiens
fdesbiens merged commit 1bae371 into eclipse-threadx:devAug 27, 2026
3 checks passed
@fdesbiens
fdesbiens deleted the fix/issue-159-wrap-blank-row branch August 27, 2026 15:48
Sign up for freeto 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.

1 participant

@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Fixed word wrapping emitting a blank row for trailing whitespace - #177

Merged
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fix/issue-159-wrap-blank-row
Aug 27, 2026
Merged

Fixed word wrapping emitting a blank row for trailing whitespace#177
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fix/issue-159-wrap-blank-row

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

What this fixes

b8bb23b8 (#159) fixed issue #130 by letting the overflow branch of _gx_multi_line_text_view_display_info_get() run when an ASCII space is the character that overflows the available width. That branch consumes the space and any consecutive spaces without adding them to the row width — correct — and then breaks.

When the whitespace ran to the end of the source line, the line terminator was left behind. The next call started on it, hit the GX_KEY_LINE_FEED case immediately, and returned a row of one byte and zero width: a blank line that is not in the text.

The overflow branch now takes the line terminator with the whitespace when nothing else separates them, handling both a bare line feed and a \r\n pair, with the second byte guarded on the remaining length. gx_text_display_width is untouched, so the #130 fix stands.

Why two golden tests have been red since June

guix_ml_text_view_32bpp (268 of 300 frames) and guix_bidi_text_draw_32bpp (144 of 429) have failed in every CI run since #159 landed.

Two phantom rows appear in the guix_ml_text_view_32bpp fixture, at string offsets 2992 and 23988 of readme_guix_generic.txt: ...Improved internal logic. with twelve trailing spaces, and ...cursor_pos_calculate.c with one. Both were confirmed with a conditional breakpoint on display_number == 1 && display_width == 0 preceded by a space — it fires exactly twice on the pre-fix code and never after.

Nothing inside GUIX reads gx_text_display_width; every caller uses only gx_text_display_number, to advance its index. So the row count alone governs where every row starts, and two extra rows change the scrollbar's value-to-pixel mapping. Every scroll step then lands at a slightly different pixel offset and the whole text block is drawn a few pixels up or down. Of the 300 frames, 297 were a pure vertical shift of otherwise identical text; only 3 were laid out differently, and those 3 are the two places above.

No golden data is regenerated.gx_multi_line_text_view_text_total_rows for the long text view goes back from 2226 to 2224, and both tests pass against their existing golden files.

Test work

guix_ml_text_view_word_wrap_no_output did not protect #159's fix — it passed on the pre-#159 code too. Its available_width was one pixel too generous (a_width + space_width), so the over-wide row the old code produced measured exactly available_width and still satisfied width <= available_width.

It is now a_width + space_width - 1, and three cases are added:

  1. a line feed terminator,
  2. a \r\n terminator,
  3. the total row count _gx_multi_line_text_view_string_total_rows_compute() derives from them — the quantity the golden frames actually depend on, and the only one of the three a unit test can pin without golden data.

Verified to discriminate in both directions by rebuilding against each source state:

Source stateTest outcome
pre-b8bb23b8Fails 4 width <= available_width assertions (issue #130)
b8bb23b8 as shippedFails LF row (2 bytes, not 3), \r\n row (2, not 4), row count (3, not 2)
this PRPasses

Verification

Linux, all eighteen build configurations, 1847 tests, no failures.

ConfigurationResult
default_build_coverage733/733 — guix_ml_text_view_32bpp green against unmodified golden
dynamic_bidi_text_build3/3 — guix_bidi_text_draw_32bpp green against unmodified golden
no_utf8_build_coverage135/135
the other 15all pass

One coverage boundary worth naming: the unit test builds against the all_widgets demo, which is not in NO_UTF8_DEMOS, so it runs in default_build_coverage and disable_error_check_build but not in the GX_UTF8_SUPPORT-off configurations. The changed code is common to both paths — only the surrounding character advance differs — and no_utf8_build_coverage covers it through its 135 golden tests.

No documentation change is required: _gx_multi_line_text_view_display_info_get is internal, and the GUIX documentation does not describe multi-line text view wrapping behaviour for trailing whitespace.

b8bb23b (eclipse-threadx#159) fixed issue eclipse-threadx#130 by letting the overflow branch of
_gx_multi_line_text_view_display_info_get() run when an ASCII space is the
character that overflows the available width. That branch consumes the space
and any consecutive spaces without adding them to the row width, which is
correct, and then breaks. When the whitespace ran to the end of the source
line, the line terminator was left behind: the next call started on it, hit
the GX_KEY_LINE_FEED case immediately and returned a row of one byte and zero
width, which draws as a blank line that is not in the text.
The overflow branch now takes the line terminator with the whitespace when
nothing else separates them, handling a bare line feed and a carriage return /
line feed pair, and guarding the second byte on the remaining length -- unlike
the pre-existing GX_KEY_CARRIAGE_RETURN case earlier in the same loop, which
reads ch.gx_string_ptr[1] unchecked. gx_text_display_width is untouched, so the
issue eclipse-threadx#130 fix stands.
Two such rows appear in the guix_ml_text_view_32bpp fixture, at string offsets
2992 and 23988 of readme_guix_generic.txt: "...Improved internal logic." with
twelve trailing spaces, and "...cursor_pos_calculate.c" with one. Both were
confirmed with a conditional breakpoint on display_number == 1 and
display_width == 0 preceded by a space, which fires exactly twice on the
pre-fix code and never after.
The two extra rows are why 268 of that test's 300 frames and 144 of
guix_bidi_text_draw_32bpp's 429 frames have differed from their golden data
since June. Nothing inside GUIX reads gx_text_display_width -- every caller
uses only gx_text_display_number, to advance its index -- so the row count
alone governs where every row starts, and two extra rows change the
scrollbar's value-to-pixel mapping. Every scroll step then lands at a slightly
different pixel offset and the whole text block is drawn a few pixels up or
down. Of the 300 frames, 297 were a pure vertical shift of otherwise identical
text; only 3 were laid out differently, and those 3 are the two places above.
No golden data is regenerated. gx_multi_line_text_view_text_total_rows for the
long text view goes back from 2226 to 2224, and both tests pass against their
existing golden files.
guix_ml_text_view_word_wrap_no_output did not protect eclipse-threadx#159's fix: it passed on
the pre-eclipse-threadx#159 code as well. Its available_width was one pixel too generous --
a_width + space_width, so the over-wide row the old code produced measured
exactly available_width and still satisfied "width <= available_width". It is
now a_width + space_width - 1, which makes appending the space genuinely
overflow, and three cases are added: a line feed terminator, a carriage return
/ line feed terminator, and the total row count that
_gx_multi_line_text_view_string_total_rows_compute() derives from them. That
last one is the quantity the golden frames actually depend on, and the only
one of the three a unit test can pin without golden data.
The test was verified to discriminate in both directions by rebuilding against
each. Against the pre-eclipse-threadx#159 source it fails four width assertions, which is
issue eclipse-threadx#130. Against eclipse-threadx#159 as shipped it fails the line feed row (2 bytes, not
3), the carriage return / line feed row (2, not 4) and the row count (3, not
2). It passes only with both fixes in place.
Verified on Linux across all eighteen build configurations, 1847 tests, no
failures. default_build_coverage 733/733, dynamic_bidi_text_build 3/3
including guix_bidi_text_draw_32bpp, no_utf8_build_coverage 135/135.
One coverage boundary worth naming: the unit test builds against the
all_widgets demo, which is not in NO_UTF8_DEMOS, so it runs in
default_build_coverage and disable_error_check_build but not in the
GX_UTF8_SUPPORT-off configurations. The changed code is common to both paths
-- only the surrounding character advance differs -- and no_utf8_build_coverage
covers it through its 135 golden tests.
No documentation change is required. _gx_multi_line_text_view_display_info_get
is internal, and the GUIX documentation does not describe multi-line text view
wrapping behaviour for trailing whitespace.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@fdesbiens
fdesbiens merged commit 1bae371 into eclipse-threadx:devAug 27, 2026
3 checks passed
@fdesbiens
fdesbiens deleted the fix/issue-159-wrap-blank-row branch August 27, 2026 15:48
Sign up for freeto 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.

1 participant

@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fixed word wrapping emitting a blank row for trailing whitespace - #177

Merged
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fix/issue-159-wrap-blank-row
Aug 27, 2026
Merged

Fixed word wrapping emitting a blank row for trailing whitespace#177
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fix/issue-159-wrap-blank-row

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

What this fixes

b8bb23b8 (#159) fixed issue #130 by letting the overflow branch of _gx_multi_line_text_view_display_info_get() run when an ASCII space is the character that overflows the available width. That branch consumes the space and any consecutive spaces without adding them to the row width — correct — and then breaks.

When the whitespace ran to the end of the source line, the line terminator was left behind. The next call started on it, hit the GX_KEY_LINE_FEED case immediately, and returned a row of one byte and zero width: a blank line that is not in the text.

The overflow branch now takes the line terminator with the whitespace when nothing else separates them, handling both a bare line feed and a \r\n pair, with the second byte guarded on the remaining length. gx_text_display_width is untouched, so the #130 fix stands.

Why two golden tests have been red since June

guix_ml_text_view_32bpp (268 of 300 frames) and guix_bidi_text_draw_32bpp (144 of 429) have failed in every CI run since #159 landed.

Two phantom rows appear in the guix_ml_text_view_32bpp fixture, at string offsets 2992 and 23988 of readme_guix_generic.txt: ...Improved internal logic. with twelve trailing spaces, and ...cursor_pos_calculate.c with one. Both were confirmed with a conditional breakpoint on display_number == 1 && display_width == 0 preceded by a space — it fires exactly twice on the pre-fix code and never after.

Nothing inside GUIX reads gx_text_display_width; every caller uses only gx_text_display_number, to advance its index. So the row count alone governs where every row starts, and two extra rows change the scrollbar's value-to-pixel mapping. Every scroll step then lands at a slightly different pixel offset and the whole text block is drawn a few pixels up or down. Of the 300 frames, 297 were a pure vertical shift of otherwise identical text; only 3 were laid out differently, and those 3 are the two places above.

No golden data is regenerated.gx_multi_line_text_view_text_total_rows for the long text view goes back from 2226 to 2224, and both tests pass against their existing golden files.

Test work

guix_ml_text_view_word_wrap_no_output did not protect #159's fix — it passed on the pre-#159 code too. Its available_width was one pixel too generous (a_width + space_width), so the over-wide row the old code produced measured exactly available_width and still satisfied width <= available_width.

It is now a_width + space_width - 1, and three cases are added:

  1. a line feed terminator,
  2. a \r\n terminator,
  3. the total row count _gx_multi_line_text_view_string_total_rows_compute() derives from them — the quantity the golden frames actually depend on, and the only one of the three a unit test can pin without golden data.

Verified to discriminate in both directions by rebuilding against each source state:

Source stateTest outcome
pre-b8bb23b8Fails 4 width <= available_width assertions (issue #130)
b8bb23b8 as shippedFails LF row (2 bytes, not 3), \r\n row (2, not 4), row count (3, not 2)
this PRPasses

Verification

Linux, all eighteen build configurations, 1847 tests, no failures.

ConfigurationResult
default_build_coverage733/733 — guix_ml_text_view_32bpp green against unmodified golden
dynamic_bidi_text_build3/3 — guix_bidi_text_draw_32bpp green against unmodified golden
no_utf8_build_coverage135/135
the other 15all pass

One coverage boundary worth naming: the unit test builds against the all_widgets demo, which is not in NO_UTF8_DEMOS, so it runs in default_build_coverage and disable_error_check_build but not in the GX_UTF8_SUPPORT-off configurations. The changed code is common to both paths — only the surrounding character advance differs — and no_utf8_build_coverage covers it through its 135 golden tests.

No documentation change is required: _gx_multi_line_text_view_display_info_get is internal, and the GUIX documentation does not describe multi-line text view wrapping behaviour for trailing whitespace.

b8bb23b (eclipse-threadx#159) fixed issue eclipse-threadx#130 by letting the overflow branch of
_gx_multi_line_text_view_display_info_get() run when an ASCII space is the
character that overflows the available width. That branch consumes the space
and any consecutive spaces without adding them to the row width, which is
correct, and then breaks. When the whitespace ran to the end of the source
line, the line terminator was left behind: the next call started on it, hit
the GX_KEY_LINE_FEED case immediately and returned a row of one byte and zero
width, which draws as a blank line that is not in the text.
The overflow branch now takes the line terminator with the whitespace when
nothing else separates them, handling a bare line feed and a carriage return /
line feed pair, and guarding the second byte on the remaining length -- unlike
the pre-existing GX_KEY_CARRIAGE_RETURN case earlier in the same loop, which
reads ch.gx_string_ptr[1] unchecked. gx_text_display_width is untouched, so the
issue eclipse-threadx#130 fix stands.
Two such rows appear in the guix_ml_text_view_32bpp fixture, at string offsets
2992 and 23988 of readme_guix_generic.txt: "...Improved internal logic." with
twelve trailing spaces, and "...cursor_pos_calculate.c" with one. Both were
confirmed with a conditional breakpoint on display_number == 1 and
display_width == 0 preceded by a space, which fires exactly twice on the
pre-fix code and never after.
The two extra rows are why 268 of that test's 300 frames and 144 of
guix_bidi_text_draw_32bpp's 429 frames have differed from their golden data
since June. Nothing inside GUIX reads gx_text_display_width -- every caller
uses only gx_text_display_number, to advance its index -- so the row count
alone governs where every row starts, and two extra rows change the
scrollbar's value-to-pixel mapping. Every scroll step then lands at a slightly
different pixel offset and the whole text block is drawn a few pixels up or
down. Of the 300 frames, 297 were a pure vertical shift of otherwise identical
text; only 3 were laid out differently, and those 3 are the two places above.
No golden data is regenerated. gx_multi_line_text_view_text_total_rows for the
long text view goes back from 2226 to 2224, and both tests pass against their
existing golden files.
guix_ml_text_view_word_wrap_no_output did not protect eclipse-threadx#159's fix: it passed on
the pre-eclipse-threadx#159 code as well. Its available_width was one pixel too generous --
a_width + space_width, so the over-wide row the old code produced measured
exactly available_width and still satisfied "width <= available_width". It is
now a_width + space_width - 1, which makes appending the space genuinely
overflow, and three cases are added: a line feed terminator, a carriage return
/ line feed terminator, and the total row count that
_gx_multi_line_text_view_string_total_rows_compute() derives from them. That
last one is the quantity the golden frames actually depend on, and the only
one of the three a unit test can pin without golden data.
The test was verified to discriminate in both directions by rebuilding against
each. Against the pre-eclipse-threadx#159 source it fails four width assertions, which is
issue eclipse-threadx#130. Against eclipse-threadx#159 as shipped it fails the line feed row (2 bytes, not
3), the carriage return / line feed row (2, not 4) and the row count (3, not
2). It passes only with both fixes in place.
Verified on Linux across all eighteen build configurations, 1847 tests, no
failures. default_build_coverage 733/733, dynamic_bidi_text_build 3/3
including guix_bidi_text_draw_32bpp, no_utf8_build_coverage 135/135.
One coverage boundary worth naming: the unit test builds against the
all_widgets demo, which is not in NO_UTF8_DEMOS, so it runs in
default_build_coverage and disable_error_check_build but not in the
GX_UTF8_SUPPORT-off configurations. The changed code is common to both paths
-- only the surrounding character advance differs -- and no_utf8_build_coverage
covers it through its 135 golden tests.
No documentation change is required. _gx_multi_line_text_view_display_info_get
is internal, and the GUIX documentation does not describe multi-line text view
wrapping behaviour for trailing whitespace.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@fdesbiens
fdesbiens merged commit 1bae371 into eclipse-threadx:devAug 27, 2026
3 checks passed
@fdesbiens
fdesbiens deleted the fix/issue-159-wrap-blank-row branch August 27, 2026 15:48
Sign up for freeto 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.

1 participant

@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fixed word wrapping emitting a blank row for trailing whitespace - #177

Merged
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fix/issue-159-wrap-blank-row
Aug 27, 2026
Merged

Fixed word wrapping emitting a blank row for trailing whitespace#177
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fix/issue-159-wrap-blank-row

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

What this fixes

b8bb23b8 (#159) fixed issue #130 by letting the overflow branch of _gx_multi_line_text_view_display_info_get() run when an ASCII space is the character that overflows the available width. That branch consumes the space and any consecutive spaces without adding them to the row width — correct — and then breaks.

When the whitespace ran to the end of the source line, the line terminator was left behind. The next call started on it, hit the GX_KEY_LINE_FEED case immediately, and returned a row of one byte and zero width: a blank line that is not in the text.

The overflow branch now takes the line terminator with the whitespace when nothing else separates them, handling both a bare line feed and a \r\n pair, with the second byte guarded on the remaining length. gx_text_display_width is untouched, so the #130 fix stands.

Why two golden tests have been red since June

guix_ml_text_view_32bpp (268 of 300 frames) and guix_bidi_text_draw_32bpp (144 of 429) have failed in every CI run since #159 landed.

Two phantom rows appear in the guix_ml_text_view_32bpp fixture, at string offsets 2992 and 23988 of readme_guix_generic.txt: ...Improved internal logic. with twelve trailing spaces, and ...cursor_pos_calculate.c with one. Both were confirmed with a conditional breakpoint on display_number == 1 && display_width == 0 preceded by a space — it fires exactly twice on the pre-fix code and never after.

Nothing inside GUIX reads gx_text_display_width; every caller uses only gx_text_display_number, to advance its index. So the row count alone governs where every row starts, and two extra rows change the scrollbar's value-to-pixel mapping. Every scroll step then lands at a slightly different pixel offset and the whole text block is drawn a few pixels up or down. Of the 300 frames, 297 were a pure vertical shift of otherwise identical text; only 3 were laid out differently, and those 3 are the two places above.

No golden data is regenerated.gx_multi_line_text_view_text_total_rows for the long text view goes back from 2226 to 2224, and both tests pass against their existing golden files.

Test work

guix_ml_text_view_word_wrap_no_output did not protect #159's fix — it passed on the pre-#159 code too. Its available_width was one pixel too generous (a_width + space_width), so the over-wide row the old code produced measured exactly available_width and still satisfied width <= available_width.

It is now a_width + space_width - 1, and three cases are added:

  1. a line feed terminator,
  2. a \r\n terminator,
  3. the total row count _gx_multi_line_text_view_string_total_rows_compute() derives from them — the quantity the golden frames actually depend on, and the only one of the three a unit test can pin without golden data.

Verified to discriminate in both directions by rebuilding against each source state:

Source stateTest outcome
pre-b8bb23b8Fails 4 width <= available_width assertions (issue #130)
b8bb23b8 as shippedFails LF row (2 bytes, not 3), \r\n row (2, not 4), row count (3, not 2)
this PRPasses

Verification

Linux, all eighteen build configurations, 1847 tests, no failures.

ConfigurationResult
default_build_coverage733/733 — guix_ml_text_view_32bpp green against unmodified golden
dynamic_bidi_text_build3/3 — guix_bidi_text_draw_32bpp green against unmodified golden
no_utf8_build_coverage135/135
the other 15all pass

One coverage boundary worth naming: the unit test builds against the all_widgets demo, which is not in NO_UTF8_DEMOS, so it runs in default_build_coverage and disable_error_check_build but not in the GX_UTF8_SUPPORT-off configurations. The changed code is common to both paths — only the surrounding character advance differs — and no_utf8_build_coverage covers it through its 135 golden tests.

No documentation change is required: _gx_multi_line_text_view_display_info_get is internal, and the GUIX documentation does not describe multi-line text view wrapping behaviour for trailing whitespace.

b8bb23b (eclipse-threadx#159) fixed issue eclipse-threadx#130 by letting the overflow branch of
_gx_multi_line_text_view_display_info_get() run when an ASCII space is the
character that overflows the available width. That branch consumes the space
and any consecutive spaces without adding them to the row width, which is
correct, and then breaks. When the whitespace ran to the end of the source
line, the line terminator was left behind: the next call started on it, hit
the GX_KEY_LINE_FEED case immediately and returned a row of one byte and zero
width, which draws as a blank line that is not in the text.
The overflow branch now takes the line terminator with the whitespace when
nothing else separates them, handling a bare line feed and a carriage return /
line feed pair, and guarding the second byte on the remaining length -- unlike
the pre-existing GX_KEY_CARRIAGE_RETURN case earlier in the same loop, which
reads ch.gx_string_ptr[1] unchecked. gx_text_display_width is untouched, so the
issue eclipse-threadx#130 fix stands.
Two such rows appear in the guix_ml_text_view_32bpp fixture, at string offsets
2992 and 23988 of readme_guix_generic.txt: "...Improved internal logic." with
twelve trailing spaces, and "...cursor_pos_calculate.c" with one. Both were
confirmed with a conditional breakpoint on display_number == 1 and
display_width == 0 preceded by a space, which fires exactly twice on the
pre-fix code and never after.
The two extra rows are why 268 of that test's 300 frames and 144 of
guix_bidi_text_draw_32bpp's 429 frames have differed from their golden data
since June. Nothing inside GUIX reads gx_text_display_width -- every caller
uses only gx_text_display_number, to advance its index -- so the row count
alone governs where every row starts, and two extra rows change the
scrollbar's value-to-pixel mapping. Every scroll step then lands at a slightly
different pixel offset and the whole text block is drawn a few pixels up or
down. Of the 300 frames, 297 were a pure vertical shift of otherwise identical
text; only 3 were laid out differently, and those 3 are the two places above.
No golden data is regenerated. gx_multi_line_text_view_text_total_rows for the
long text view goes back from 2226 to 2224, and both tests pass against their
existing golden files.
guix_ml_text_view_word_wrap_no_output did not protect eclipse-threadx#159's fix: it passed on
the pre-eclipse-threadx#159 code as well. Its available_width was one pixel too generous --
a_width + space_width, so the over-wide row the old code produced measured
exactly available_width and still satisfied "width <= available_width". It is
now a_width + space_width - 1, which makes appending the space genuinely
overflow, and three cases are added: a line feed terminator, a carriage return
/ line feed terminator, and the total row count that
_gx_multi_line_text_view_string_total_rows_compute() derives from them. That
last one is the quantity the golden frames actually depend on, and the only
one of the three a unit test can pin without golden data.
The test was verified to discriminate in both directions by rebuilding against
each. Against the pre-eclipse-threadx#159 source it fails four width assertions, which is
issue eclipse-threadx#130. Against eclipse-threadx#159 as shipped it fails the line feed row (2 bytes, not
3), the carriage return / line feed row (2, not 4) and the row count (3, not
2). It passes only with both fixes in place.
Verified on Linux across all eighteen build configurations, 1847 tests, no
failures. default_build_coverage 733/733, dynamic_bidi_text_build 3/3
including guix_bidi_text_draw_32bpp, no_utf8_build_coverage 135/135.
One coverage boundary worth naming: the unit test builds against the
all_widgets demo, which is not in NO_UTF8_DEMOS, so it runs in
default_build_coverage and disable_error_check_build but not in the
GX_UTF8_SUPPORT-off configurations. The changed code is common to both paths
-- only the surrounding character advance differs -- and no_utf8_build_coverage
covers it through its 135 golden tests.
No documentation change is required. _gx_multi_line_text_view_display_info_get
is internal, and the GUIX documentation does not describe multi-line text view
wrapping behaviour for trailing whitespace.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@fdesbiens
fdesbiens merged commit 1bae371 into eclipse-threadx:devAug 27, 2026
3 checks passed
@fdesbiens
fdesbiens deleted the fix/issue-159-wrap-blank-row branch August 27, 2026 15:48
Sign up for freeto 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.

1 participant

@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Fixed word wrapping emitting a blank row for trailing whitespace - #177

Merged
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fix/issue-159-wrap-blank-row
Aug 27, 2026
Merged

Fixed word wrapping emitting a blank row for trailing whitespace#177
fdesbiens merged 1 commit into
eclipse-threadx:devfrom
fdesbiens:fix/issue-159-wrap-blank-row

Conversation

@fdesbiens

Copy link
Copy Markdown
Contributor

What this fixes

b8bb23b8 (#159) fixed issue #130 by letting the overflow branch of _gx_multi_line_text_view_display_info_get() run when an ASCII space is the character that overflows the available width. That branch consumes the space and any consecutive spaces without adding them to the row width — correct — and then breaks.

When the whitespace ran to the end of the source line, the line terminator was left behind. The next call started on it, hit the GX_KEY_LINE_FEED case immediately, and returned a row of one byte and zero width: a blank line that is not in the text.

The overflow branch now takes the line terminator with the whitespace when nothing else separates them, handling both a bare line feed and a \r\n pair, with the second byte guarded on the remaining length. gx_text_display_width is untouched, so the #130 fix stands.

Why two golden tests have been red since June

guix_ml_text_view_32bpp (268 of 300 frames) and guix_bidi_text_draw_32bpp (144 of 429) have failed in every CI run since #159 landed.

Two phantom rows appear in the guix_ml_text_view_32bpp fixture, at string offsets 2992 and 23988 of readme_guix_generic.txt: ...Improved internal logic. with twelve trailing spaces, and ...cursor_pos_calculate.c with one. Both were confirmed with a conditional breakpoint on display_number == 1 && display_width == 0 preceded by a space — it fires exactly twice on the pre-fix code and never after.

Nothing inside GUIX reads gx_text_display_width; every caller uses only gx_text_display_number, to advance its index. So the row count alone governs where every row starts, and two extra rows change the scrollbar's value-to-pixel mapping. Every scroll step then lands at a slightly different pixel offset and the whole text block is drawn a few pixels up or down. Of the 300 frames, 297 were a pure vertical shift of otherwise identical text; only 3 were laid out differently, and those 3 are the two places above.

No golden data is regenerated.gx_multi_line_text_view_text_total_rows for the long text view goes back from 2226 to 2224, and both tests pass against their existing golden files.

Test work

guix_ml_text_view_word_wrap_no_output did not protect #159's fix — it passed on the pre-#159 code too. Its available_width was one pixel too generous (a_width + space_width), so the over-wide row the old code produced measured exactly available_width and still satisfied width <= available_width.

It is now a_width + space_width - 1, and three cases are added:

  1. a line feed terminator,
  2. a \r\n terminator,
  3. the total row count _gx_multi_line_text_view_string_total_rows_compute() derives from them — the quantity the golden frames actually depend on, and the only one of the three a unit test can pin without golden data.

Verified to discriminate in both directions by rebuilding against each source state:

Source stateTest outcome
pre-b8bb23b8Fails 4 width <= available_width assertions (issue #130)
b8bb23b8 as shippedFails LF row (2 bytes, not 3), \r\n row (2, not 4), row count (3, not 2)
this PRPasses

Verification

Linux, all eighteen build configurations, 1847 tests, no failures.

ConfigurationResult
default_build_coverage733/733 — guix_ml_text_view_32bpp green against unmodified golden
dynamic_bidi_text_build3/3 — guix_bidi_text_draw_32bpp green against unmodified golden
no_utf8_build_coverage135/135
the other 15all pass

One coverage boundary worth naming: the unit test builds against the all_widgets demo, which is not in NO_UTF8_DEMOS, so it runs in default_build_coverage and disable_error_check_build but not in the GX_UTF8_SUPPORT-off configurations. The changed code is common to both paths — only the surrounding character advance differs — and no_utf8_build_coverage covers it through its 135 golden tests.

No documentation change is required: _gx_multi_line_text_view_display_info_get is internal, and the GUIX documentation does not describe multi-line text view wrapping behaviour for trailing whitespace.

b8bb23b (eclipse-threadx#159) fixed issue eclipse-threadx#130 by letting the overflow branch of
_gx_multi_line_text_view_display_info_get() run when an ASCII space is the
character that overflows the available width. That branch consumes the space
and any consecutive spaces without adding them to the row width, which is
correct, and then breaks. When the whitespace ran to the end of the source
line, the line terminator was left behind: the next call started on it, hit
the GX_KEY_LINE_FEED case immediately and returned a row of one byte and zero
width, which draws as a blank line that is not in the text.
The overflow branch now takes the line terminator with the whitespace when
nothing else separates them, handling a bare line feed and a carriage return /
line feed pair, and guarding the second byte on the remaining length -- unlike
the pre-existing GX_KEY_CARRIAGE_RETURN case earlier in the same loop, which
reads ch.gx_string_ptr[1] unchecked. gx_text_display_width is untouched, so the
issue eclipse-threadx#130 fix stands.
Two such rows appear in the guix_ml_text_view_32bpp fixture, at string offsets
2992 and 23988 of readme_guix_generic.txt: "...Improved internal logic." with
twelve trailing spaces, and "...cursor_pos_calculate.c" with one. Both were
confirmed with a conditional breakpoint on display_number == 1 and
display_width == 0 preceded by a space, which fires exactly twice on the
pre-fix code and never after.
The two extra rows are why 268 of that test's 300 frames and 144 of
guix_bidi_text_draw_32bpp's 429 frames have differed from their golden data
since June. Nothing inside GUIX reads gx_text_display_width -- every caller
uses only gx_text_display_number, to advance its index -- so the row count
alone governs where every row starts, and two extra rows change the
scrollbar's value-to-pixel mapping. Every scroll step then lands at a slightly
different pixel offset and the whole text block is drawn a few pixels up or
down. Of the 300 frames, 297 were a pure vertical shift of otherwise identical
text; only 3 were laid out differently, and those 3 are the two places above.
No golden data is regenerated. gx_multi_line_text_view_text_total_rows for the
long text view goes back from 2226 to 2224, and both tests pass against their
existing golden files.
guix_ml_text_view_word_wrap_no_output did not protect eclipse-threadx#159's fix: it passed on
the pre-eclipse-threadx#159 code as well. Its available_width was one pixel too generous --
a_width + space_width, so the over-wide row the old code produced measured
exactly available_width and still satisfied "width <= available_width". It is
now a_width + space_width - 1, which makes appending the space genuinely
overflow, and three cases are added: a line feed terminator, a carriage return
/ line feed terminator, and the total row count that
_gx_multi_line_text_view_string_total_rows_compute() derives from them. That
last one is the quantity the golden frames actually depend on, and the only
one of the three a unit test can pin without golden data.
The test was verified to discriminate in both directions by rebuilding against
each. Against the pre-eclipse-threadx#159 source it fails four width assertions, which is
issue eclipse-threadx#130. Against eclipse-threadx#159 as shipped it fails the line feed row (2 bytes, not
3), the carriage return / line feed row (2, not 4) and the row count (3, not
2). It passes only with both fixes in place.
Verified on Linux across all eighteen build configurations, 1847 tests, no
failures. default_build_coverage 733/733, dynamic_bidi_text_build 3/3
including guix_bidi_text_draw_32bpp, no_utf8_build_coverage 135/135.
One coverage boundary worth naming: the unit test builds against the
all_widgets demo, which is not in NO_UTF8_DEMOS, so it runs in
default_build_coverage and disable_error_check_build but not in the
GX_UTF8_SUPPORT-off configurations. The changed code is common to both paths
-- only the surrounding character advance differs -- and no_utf8_build_coverage
covers it through its 135 golden tests.
No documentation change is required. _gx_multi_line_text_view_display_info_get
is internal, and the GUIX documentation does not describe multi-line text view
wrapping behaviour for trailing whitespace.
Assisted-by: Claude Code (Opus 5)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@fdesbiens
fdesbiens merged commit 1bae371 into eclipse-threadx:devAug 27, 2026
3 checks passed
@fdesbiens
fdesbiens deleted the fix/issue-159-wrap-blank-row branch August 27, 2026 15:48
Sign up for freeto 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.

1 participant

@fdesbiens