Repository navigation
fix(main-editor): skip replacing a background screenshot when the lis… - #870
Merged
Merged
Conversation
…t is empty Scale-end always replaces the screenshot reserved at scale-start. A canvas pan or zoom with a layer still selected never reserved one, and capture() appends nothing when background generation is off, so removeLast threw.
…ation is off capture() treated every call as an eager history screenshot. Exporting a WidgetLayer without exportConfigs then added null to List<Uint8List>.
saif-ellafi
force-pushed
the
fix/replace-screenshot-empty-list
branch
from
September 23, 2026 15:09
3ce02ad to
b34ac52
Compare
… scale-end A canvas pan or zoom, or a drag selection, that ended with layers selected ran the layer-transform branch: it discarded the screenshot of the previous history step and never passed the end to the interactive viewer, so `onEditorZoomScaleEnd` did not fire. Only a gesture that reserved a history entry at scale-start replaces its screenshot now.
`ImageConverterService.convert` dropped its `format` argument whenever it fell back to the main thread (isolate generation off, or no worker support) and always encoded in `ImageGenerationConfigs.outputFormat`. A widget layer rasterized for export, or a video editor capture, then came out as JPEG instead of the PNG it asked for and lost its transparency.
`capture()` is the state-history screenshot: it skips when background generation is off, tags the capture as a history screenshot (which returns null on web without worker support) and the crop editor passes it a widget too, so keying the skip on `screenshots == null` was fragile. Export now calls `captureWidget()`, which always rasterizes, and `capture()` keeps its original guard. `_convertLayers` takes a `List<Uint8List>` so a null record no longer type-checks.
A widget layer exported without a record (its rasterization failed) has no `recordPosition`, so the import read `widgetRecords[-1]` and threw as soon as any other widget layer had a record.
Every history step that held the same widget layer rasterized it again and appended another PNG, but the layer reference, and so the import, only ever points at the first one.
Owner
|
Thanks a lot for this PR, @saif-ellafi. Both crashes were real, and your widget test made the first one easy to reproduce against Here is what changed on top of your commits:
Thanks again! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Hi, this PR was AI-Assisted. I found the issues, debugged, and tested.
Two call sites still assumed
enableBackgroundGenerationwas on._takeScreenshot(replaceLastScreenshot: true)always calledscreenshots.removeLast(). Scale-end does that even when scale-start never reserved a screenshot (canvas pan/zoom with a layer still selected). With background generation off,capture()also never appends, so the list is empty andremoveLastthrowsRangeError. Skip the replace when the list is empty. Widget test covers a middle-button pan with a selected layer and background generation off.Export of a
WidgetLayerwith no restore params (exportConfigs) rasterizes viacapture(), which returnednullwhenever background generation was off, then didwidgetRecords.add(result)on aList<Uint8List>. Eager history screenshots still skip when the flag is off; an explicit widget capture for export still runs, andnullis not added.Type of Change