Skip to content

Keep oversized xwidgets visible with GNU-compatible geometry (#301) - #328

Merged
eval-exec merged 15 commits into
eval-exec:mainfrom
tag-und-nacht:fix/xwidget-crop-oversized
Sep 4, 2026
Merged

eval-exec merged 15 commits into
eval-exec:mainfrom
tag-und-nacht:fix/xwidget-crop-oversized

Conversation

@tag-und-nacht

@tag-und-nacht tag-und-nacht commented Sep 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Closes #301. An xwidget wider than the room remaining in a row was produced, then removed by the body row's generic overflow rollback while its source character was still consumed. The result contained no FrameGlyph::Xwidget, so every backend correctly hid the view and showed only the buffer background.

GNU Emacs handles xwidgets specially in produce_xwidget_glyph: it may crop the glyph's layout advance to the remaining row width, while x_draw_xwidget_glyph_string keeps the native widget at its intrinsic size and clips its presentation to the window text area. Narrow mid-row xwidgets are left whole; display_line retains them in truncating rows and the presentation clip limits visibility.

Design

  • DisplayXwidgetOverflowAction is xwidget-only. Images, videos, and shader surfaces retain their existing behavior; GNU's distinct image policy is not generalized here.
  • XwidgetPresentationGeometry<Space> carries three separate concepts through layout, frame materialization, child-frame translation, rendering, native placement, and pointer hit-testing:
    • intrinsic XwidgetContentExtent;
    • typed XwidgetLayoutAdvance;
    • the visible clip in a branded coordinate space.
  • WindowLocalRowExtent converts frame coordinates once, validates finite ordered geometry, and implements GNU's window-local quarter-width predicate. Invalid intervals cannot reach the crop policy.
  • DisplayItemRightEdgeAdmission::PreserveWholeXwidget is the typed, exhaustive exception that permits only GNU's LeaveWhole xwidget case past the row boundary. Frame materialization preserves that whole advance instead of replacing it with the visible slice.
  • Renderer composition and pointer dispatch resolve the same presentation geometry, preventing viewport, pixels, and hit targets from drifting apart.

WebView reliability found by the strict GUI test

The end-to-end test initially exposed two independent Linux backend defects that prevented reliable pixel verification:

  • desired navigation/visibility state submitted while native creation was asynchronous was not reconciled before Ready;
  • WPE pixel imports are borrowed, but Neomacs unreferenced the cached GBytes, causing use-after-free behavior on later callbacks.

The lifecycle now converges through typed pending/desired state, and the WPE boundary uses borrowed wrappers plus validated software pixel layouts. The incorrect unref is no longer available in the generated binding surface.

Tests

  • Red-first layout regressions cover an oversized xwidget, a right-hand split, line-number-origin semantics, GNU's narrow LeaveWhole case, tall clipping, and invalid row geometry.
  • Protocol/runtime/renderer tests cover content-vs-advance-vs-clip preservation, coordinate translation, composition, and hit-testing.
  • A Linux real-GUI test loads a deterministic magenta data: page in an xwidget twice the live text-area size, asserts the semantic glyph geometry, and verifies actual pixels in the PNG. It passed 5 consecutive Wayland runs and 3 consecutive X11 runs.
  • All 12 focused layout xwidget/geometry tests pass; all 52 neomacs-webview tests pass.

Known GNU gaps are documented next to the policy: zero-room glyphs, positive box-line widths, horizontal scrolling across first_visible_x, and GNU's ascent/descent split.

@tag-und-nacht

Copy link
Copy Markdown
Contributor Author

GUI verification on the release build (cargo xtask fresh-build --release, then neomacs -Q -l oversize.el: xwidget-webkit-browse-url on example.com in a 502×442 px window, xwidget-resize, redisplay, neomacs--frame-snapshot nil 'json, and reading the window matrix):

state xwidget-size-request Xwidget glyph in the matrix pixel_width row height_px
fits 480×416 present 480 416
resized to 3× window height 502×1326 present (was absent before) 480 1326
resized to 2× window width 1004×442 present (was absent before) 480 442

The text area of that window is 480 px wide (502 minus fringes), so both resizes are width overflows and both are cropped to 480 exactly as GNU's crop = pixel_width - (last_visible_x - current_x) gives; the tall one keeps its 1326 px height and is clipped by the row's window clip. Before this change the same two snapshots had no Xwidget glyph at all.

@eval-exec eval-exec left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I reviewed this against issue #301 and the separate GNU Emacs 31.0.90 image/xwidget paths in src/xdisp.c.

Blocking findings

  1. Preserve intrinsic xwidget size separately from cropped layout width. cropped_to_visible_width overwrites DisplayMediaReplacement.width. That becomes the only width on FrameGlyph::Xwidget, and collect_frame_webviews then uses it as the native webview content rectangle. A 600px widget cropped to 304px therefore becomes a 304px browser viewport instead of a 600px viewport behind a 304px clip. GNU preserves the model/widget size and narrows only the glyph/visible region. Please model intrinsic content extent, layout advance extent, and visible clip extent separately.

  2. Use window-local width in the GNU quarter-width predicate. for_replacement compares against right_edge_px / 4, but the caller supplies an absolute frame-space right edge. GNU last_visible_x is window-local. In a right-hand split, the inflated threshold can choose LeaveWhole, and the oversized xwidget can still be dropped. The policy should receive typed window-local available width/window width rather than an absolute coordinate. Please add a right-hand split regression.

  3. Do not apply the xwidget rule generically to all media. builder.rs:1619-1636 applies one rule to images, videos, xwidgets, and surfaces. Issue #301 is specifically about xwidgets. GNU intentionally uses different policies:

    With word-wrap, this PR can crop a mid-row image that GNU keeps whole so it can wrap. Video and surface behavior is also unrelated scope expansion.

  4. The image slice arithmetic is incorrect when margins or box space exist. visible_width / self.width uses total glyph width, including horizontal margins/box expansion, to scale the source rectangle. GNU subtracts the cropped pixel count from the image slice after calculating total glyph width. A margined image therefore samples too much source and rescales it. The current test only covers zero margins.

There is also a documentation mix-up: the positive box-line-width paragraph is attached to cropped_to_visible_width rather than with_positive_box_line_width.

Recommended shape

For #301, narrow the immediate policy to DisplayMediaReplacementKind::Xwidget, preserve the intrinsic widget width, calculate cropping with window-local coordinates, and test both a right-hand split and the final native placement (content width = 600, visible width = 304). Image overflow should be a separate typed policy carrying wrap mode, line-number-prefix state, margins, and box geometry.

@tag-und-nacht

Copy link
Copy Markdown
Contributor Author

Thanks for the review. Reworked in two commits on top of the original; the combined change is what to read.

1. Intrinsic size vs cropped width. New protocol type XwidgetContentExtent (GNU xw->width/xw->height) travels from DisplayMediaReplacementKind::Xwidget through GlyphType::Xwidget to FrameGlyph::Xwidget::content. The glyph's width stays the cropped slot (the cursor cell), clip_rect stays the text area, and collect_frame_webviews builds the placement from content ∩ clip, so the native view is 600 px behind a 304 px clip (a_cropped_xwidget_slot_keeps_the_native_content_width_behind_the_clip asserts content_rect().width() == 600, visible_rect().width() == 304). The pointer hit test reads the same pair. The row hash mixes the extent in.

2. Window-local width. DisplayRowTextAreaOrigin (text-area left edge = content x minus the line-number prefix, per it->current_x counting the prefix) rides with DisplayRowRenderBounds from the append context to the row writer, and WindowLocalRowExtent converts once before the rule runs. Right-hand split regressions: the_quarter_width_rule_uses_the_windows_own_width_in_a_right_hand_split (policy) and layout_frame_rust_crops_an_xwidget_in_a_right_hand_split_by_the_windows_width (engine: 300 px widget at frame x 1368 in the right window of a 1600 px frame; cropped to 224 with the window-local origin, dropped with the frame-absolute one). A second engine test checks the origin with display-line-numbers on: a 195 px widget after the prefix is left whole (≤ 784/4), a 200 px one is cropped.

3. Xwidgets only. The policy is now DisplayXwidgetOverflowAction, matched on DisplayMediaReplacementKind::Xwidget in the pattern; images, videos and surfaces are back to the previous behavior, and the image rule (xdisp.c:32457-32473) is left for its own typed policy.

4. Image slice arithmetic. Removed along with the image path.

Doc mix-up. The paragraph is back on with_positive_box_line_width.

Ledger of what is still not GNU (in the enum's doc): LeaveWhole drops the glyph where display_line would continue/truncate it (the pre-existing behavior, now limited to widgets GNU also leaves whole); the hpos == 0 no-room case is dropped rather than produced at zero width (:32600); box line widths are not added before the crop (:32556-32570); hscroll's first_visible_x is not carried (:3507).

Not run here: the Linux wgpu draw paths (draw_inline_webkit_views, render_frame_content) now draw the content extent cut to the clip through clipped_media_rect, the image branch's helper; they are compiled only on Linux. Everything else was run on macOS. A GUI probe of a 600 px widget after 70 cells in a right-hand split shows content width 600 with a 206 px advance, the exact text-area remainder.

@tag-und-nacht
tag-und-nacht force-pushed the fix/xwidget-crop-oversized branch from e99b4de to 4b65faf Compare September 2, 2026 16:14
@eval-exec
eval-exec self-requested a review September 3, 2026 06:24
@tag-und-nacht
tag-und-nacht force-pushed the fix/xwidget-crop-oversized branch from 423ca62 to 67f5af1 Compare September 3, 2026 20:35
@tag-und-nacht

Copy link
Copy Markdown
Contributor Author

Rebased onto current main (5195028) after GitHub flagged the conflict. What changed beyond the rebase itself, so nothing lands here silently:

  • Dropped test(layout-engine): gate the Fontconfig font test to Linux. Your 2808417 made the same change, so that commit was skipped rather than merged.
  • ce42d8f refactor(layout): define the text-area left edge once. Your 1382937 added DisplayRowAppendSurface::text_area_left for hscroll truncation. It computes the same edge (content_x - line_number_width) that this branch's DisplayRowAppendFrame::text_area_origin computed on its own for the window-local it->current_x extent (src/dispextern.h:2785-2791). The textual merge kept both, so DisplayRowAppendArea::text_area_left is now the one definition: the surface delegates to it and the frame holds the area instead of three copied fields.
  • 077f58d fix(display-protocol): validate an xwidget content extent on deserialization too. The derived Deserialize bypassed XwidgetContentExtent::new, so a serialized frame could carry a zero or non-finite extent the constructor refuses. It now deserializes through #[serde(try_from)]; same wire shape, red-first test on {"width_px":0.0,…}.
  • 67f5af1 docs(layout): declare the remaining gaps. Three things produce_xwidget_glyph does that the ledger did not list: a widget straddling first_visible_x under hscroll (this port's skip phase consumes it before the rule runs), it->hpos == 0 counting only visible glyphs (src/xdisp.c:25705-25706), and the even ascent/descent split (:32546-32547). Two citations were off by a line or pointed at the continuation test instead of the restore branch; corrected to 32557-32571 and 26221-26224 / 26416-26434.

Checked for semantic drift, not just merge cleanliness: of the 108 upstream commits since the previous base, 15 touch this branch's files; 1382937 was the only real overlap (above). Its skip phase never carries a media replacement, so it cannot reach the RejectOverflowingGlyph crop arm.

Run on macOS: cargo fmt --check; cargo clippy --all-targets on display-protocol, layout-engine, display-runtime and renderer-wgpu (the latter two with webview); the four crates' test suites. On this machine main itself fails 26 tests in display-protocol/layout-engine (font-cluster shaping after the freetype removal, the gui_chrome Lisp loads, and glyph_pointer_token_has_small_niche_sized_overhead: Glyph is 104 bytes on main, the bound is 80; GlyphType is sized by AutomaticComposite, so the 8-byte XwidgetContentExtent on the Xwidget variant does not move it). This branch fails exactly that set and nothing else. Not run: the Linux wgpu paths and the WPE build.

Left as-is, for the record: the policy seam (for_xwidget, xwidget_advance_cropped_to) still takes bare f32 rather than Px; the pointer hit test's new test sits in the existing inline mod webview_tests; body_render.rs has its own text_area_left from text_x, equal by construction (content_x = text_x + line_number_pixel_width).

@eval-exec
eval-exec force-pushed the fix/xwidget-crop-oversized branch from 67f5af1 to 8b3156b Compare September 4, 2026 03:52
Comment thread crates/neomacs-webview/src/platform/linux/view.rs Fixed
@eval-exec eval-exec changed the title Crop a media glyph wider than its row like GNU instead of dropping it (#301) Keep oversized xwidgets visible with GNU-compatible geometry (#301) Sep 4, 2026
tag-und-nacht and others added 15 commits September 4, 2026 01:48
… dropping it

An xwidget (or image, video, surface) wider than the room left on its
row produced no glyph at all: `DisplayRowProgressWriter::push_item`
measured the freshly pushed media glyph against the row's right edge and,
under body text's `RejectOverflowingGlyph` policy, restored the checkpoint
-- unpushing it -- while the covered buffer text was still consumed.  The
window showed an empty background, indistinguishable from a page that
failed to load (issue 301; both reported reproductions, 1326 px tall and
1004 px wide, were width overflows of a full-window-width widget).

GNU never declines the glyph.  `produce_xwidget_glyph`
(src/xdisp.c:32700-32704) and `produce_image_glyph` (:32582-32598) crop it
when they produce it:

    crop = it->pixel_width - (it->last_visible_x - it->current_x);
    if (crop > 0 && (it->hpos == 0 || it->pixel_width > it->last_visible_x / 4))
      it->pixel_width -= crop;

so a glyph that starts the row, or is wider than a quarter of the visible
width, fits exactly and `display_line` keeps it (:26254-26310); an image
also narrows its slice (:32597).  Only a narrower glyph mid-row is left
whole for `display_line` to continue or truncate.

Model that decision as `DisplayMediaReplacementOverflowAction`
(`Fits | CropToVisibleWidth | LeaveWhole`) beside the existing character
overflow actions, give `DisplayMediaReplacement` a
`cropped_to_visible_width` that narrows an image's `ImageSourceRect`
proportionally and leaves other kinds' content to draw-time clipping, and
apply the action in the row writer's body-text path before its fit check.
A cropped glyph now completes with positive width, so the row still
grows to the widget's height and `text_clip_bounds` gives the glyph its
window clip.

`LeaveWhole` keeps today's behaviour for the narrow mid-row case, which
GNU instead continues onto the next row; that divergence is separate from
this issue and is left as it was.

Tests (red first): `layout_frame_rust_crops_an_xwidget_wider_than_its_window_like_gnu`
pins GNU's arithmetic on the TTY test frame (600 px at x=8 in a 312 px row
-> 304), the tall-widget test pins that height is kept and the row clip
bounds it, `media_wider_than_the_remaining_row_is_cropped_by_gnus_rule`
pins the predicate, and the image-slice test pins `slice.width -= crop`.

Closes eval-exec#301.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117NsCB7AbwgdEqduGF5Kww
…the right edge

Rework of the previous commit after review (PR 328): the crop was the
right idea applied to the wrong things.

Three extents, as GNU keeps them.  `produce_xwidget_glyph` crops only the
glyph's layout advance (`it->pixel_width -= crop`, src/xdisp.c:32577-32579,
emacs-31.0.90); the widget keeps `xw->width`/`xw->height`, and
`x_draw_xwidget_glyph_string` sizes the native view from that and clips it
to the window's text area (src/xwidget.c:2841-2847).  The previous commit
overwrote `DisplayMediaReplacement.width`, which is also what
`collect_frame_webviews` fed the native view as its content rectangle: a
600 px page cropped to a 304 px slot became a 304 px viewport instead of a
600 px viewport behind a 304 px clip.  A new protocol type,
`XwidgetContentExtent`, now carries the widget's own size from
`DisplayMediaReplacementKind::Xwidget` through `GlyphType::Xwidget` to
`FrameGlyph::Xwidget`; the glyph's `width` stays the cropped slot (the
cursor cell), `clip_rect` stays the text area, and the runtime's placement
and pointer hit test read `content` for the view and the clip for what is
visible.  The Linux wgpu paths draw the content extent and cut it to the
clip on all four sides, as the image path already did.

Window-local coordinates.  GNU's quarter-width predicate compares against
`it->last_visible_x`, which is measured from the window's text area
(src/dispextern.h:2785-2791); the row writer works in frame-absolute pixels
and the previous commit fed those straight in, so in a right-hand split
the threshold was about twice what GNU uses and a widget GNU crops was
left whole and then dropped.  `DisplayRowTextAreaOrigin` travels with
`DisplayRowRenderBounds` from the append context (text-area left = content
x minus the line-number prefix) to the writer, and
`WindowLocalRowExtent` converts once before the rule runs.

Xwidgets only.  Issue 301 is about xwidgets, and GNU's image rule
(src/xdisp.c:32457-32473) is a different one that also weighs word wrap,
the line-number prefix and the frame's column width; the previous commit
applied the xwidget rule to every media kind and scaled an image's slice
by a ratio that included its margins.  The policy is now
`DisplayXwidgetOverflowAction`, applied only to
`DisplayMediaReplacementKind::Xwidget`; images, videos and surfaces are
back to the pre-existing behavior, and the image rule is left for its own
typed policy.  The doc comment that had been re-attached to the crop
helper is back on `with_positive_box_line_width`.

Tests, red first:
- `the_quarter_width_rule_uses_the_windows_own_width_in_a_right_hand_split`
  and `layout_frame_rust_crops_an_xwidget_in_a_right_hand_split_by_the_windows_width`
  (a 300 px widget at frame x 1368 in the right window of a 1600 px frame:
  cropped to 224 with the window-local origin, dropped with the
  frame-absolute one);
- `a_cropped_xwidget_slot_keeps_the_native_content_width_behind_the_clip`
  (`ResolvedWebViewPlacement` content width 600, visible width 304);
- `hit_testing_uses_the_widgets_own_extent_not_the_cropped_slot`;
- `cropping_an_xwidgets_advance_keeps_its_content_extent`;
- the existing wide/tall engine tests now also assert the content extent.

Not run here: the Linux wgpu draw paths (`draw_inline_webkit_views`,
`render_frame_content`) are compiled only on Linux; the display-runtime
webview tests need the macOS webview build fix from PR 327 to compile on
this machine and were run on a branch carrying it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117NsCB7AbwgdEqduGF5Kww
…d ledger the GNU gaps

Findings of an adversarial pre-push review of the previous commit.

The Linux child-frame path (`render_frame_content`, content.rs) drew the
xwidget texture at its content size but never read `clip_rect`, so a
widget cropped at the right edge of a split child frame would have spilled
across the neighbouring window; before the content/slot split that glyph
was dropped, so the spill was new.  Both Linux paths now cut the content
extent through `clipped_media_rect`, the helper the image branch already
uses, so the clip arithmetic has one owner.  `FrameGlyph::Xwidget::height`
likewise had two writers (`add_xwidget` stored the content height,
`materialize` the glyph's layout height); both now store the content
height, which is what the row promoted anyway.

`DisplayXwidgetOverflowAction`'s doc now ledgers what the port does not
do relative to `produce_xwidget_glyph`: `LeaveWhole` drops the glyph where
`display_line` would continue or truncate it (src/xdisp.c:26411-26432),
the no-room `hpos == 0` case is dropped rather than produced at zero width
(:32605), box line widths are not added before the crop (:32562-32569),
and hscroll's `first_visible_x` is not carried (:3507).  A phantom citation
in the tall-widget test (":32703", an R2L box-edge line) is replaced by
the real crop and clip lines, and the `x_draw_xwidget_glyph_string` range
now includes `clip_bottom` (src/xwidget.c:2841-2849).

The right-edge match in the row builder binds the xwidget kind in the
pattern instead of a `matches!` guard.  A new engine test,
`layout_frame_rust_measures_the_quarter_width_rule_from_the_text_area_not_the_line_numbers`,
exercises `DisplayRowAppendFrame::text_area_origin` with a non-zero
line-number width end to end: a 200 px widget after 75 cells is cropped
to the row's remainder, and a 195 px one (not wider than a quarter of the
784 px text area, but wider than a quarter of the content area after the
prefix) is left whole, as GNU does.

Not run here: the Linux wgpu draw paths are compiled only on Linux.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117NsCB7AbwgdEqduGF5Kww
CI's cargo fmt jobs failed on one assertion I had edited by hand after the
formatting pass.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117NsCB7AbwgdEqduGF5Kww
… xwidget origin from it

Upstream 1382937 (fix(layout): preserve hscroll boundary items) added
`DisplayRowAppendSurface::text_area_left` for hscroll truncation.  It
computes `content_x - line_number_width`, the same edge that
`DisplayRowAppendFrame::text_area_origin` computed on its own for the
window-local extent an overflowing xwidget is measured against
(GNU's `it->current_x`, src/dispextern.h:2785-2791; the line-number
prefix is produced as glyphs and counted, `maybe_produce_line_number`,
src/xdisp.c:25701).

Two definitions of one edge can drift apart.  `DisplayRowAppendArea`
now owns the computation; the surface delegates to it, and the frame
holds the area itself instead of three copied fields, so `content_x`,
`text_width`, `line_number_width` and the text-area origin are all
read from the one value.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117NsCB7AbwgdEqduGF5Kww
…ization too

`XwidgetContentExtent::new` refuses a zero, negative or non-finite
dimension, but the derived `Deserialize` built the struct directly, so a
serialized frame could carry an extent the constructor would never
produce.  Deserialize through `#[serde(try_from)]` and the one
constructor; the serialized shape is unchanged.  Red-first test:
`{"width_px":0.0,"height_px":40.0}` deserialized before, is refused now.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117NsCB7AbwgdEqduGF5Kww
…d fix two citations

The ledger on `DisplayXwidgetOverflowAction` now lists what else the
port leaves out of the GNU function it is taken from (emacs-31.0.90):

- a widget straddling `first_visible_x` under hscroll, which GNU keeps
  with a negative `row->x` and this port's skip phase consumes as a
  plain glyph before the rule can see it;
- `it->hpos == 0` counting only visible glyphs (src/xdisp.c:25705-25706),
  which `at_row_start` matches only because the skip phase writes
  nothing before the first visible glyph;
- the even ascent/descent split (src/xdisp.c:32546-32547).

Citations corrected against the mirror: the box-width lines are
32557-32571, and the `display_line` continuation is the test at
26221-26224 plus the restore-and-continue branch at 26416-26434.  The
line-number crop test's comment counted a four-cell prefix; it is the
six-cell `lnum_width + 2` gutter, which is how the pen reaches 1456.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117NsCB7AbwgdEqduGF5Kww
Keep intrinsic content, cropped layout advance, and visible clipping in one coordinate-space-branded protocol value. Translate and resolve that value once for native placement, GPU composition, and pointer input so those consumers cannot reconstruct incompatible rectangles.\n\nMake GNU's xwidget-only overflow decision consume and return a validated XwidgetLayoutAdvance, and expose crop application only through a DisplayXwidgetReplacement capability. This prevents image, video, and surface replacements from entering the xwidget policy.
Keep the mutable native state submitted with each pending WebView creation. Before publishing Ready, apply any model-size or navigation changes that arrived while the platform was creating the view.

This preserves GNU Emacs's immediate xwidget navigation contract across asynchronous backends and prevents the first URI from being lost by WPE.
Treat wpe_buffer_import_to_pixels as a borrowed transfer instead of unreferencing WebKit's cached GBytes. Encode the callback borrow separately from accepted-buffer ownership, validate foreign row metadata before slicing or allocating, and copy padded rows directly into packed BGRA pixels.
Create a deterministic oversized WebKit xwidget and assert the GNU-compatible split between intrinsic content extent and cropped row advance. Require the page's magenta pixels in the real wgpu surface readback so the regression covers redisplay, async native creation, WPE capture, clipping, and composition together.
@eval-exec
eval-exec force-pushed the fix/xwidget-crop-oversized branch from 2ef002e to 809b1fb Compare September 4, 2026 05:52
@eval-exec
eval-exec merged commit ec1c909 into eval-exec:main Sep 4, 2026
21 of 25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

An xwidget larger than its window disappears instead of being cropped

3 participants