Skip to content

[BUG] Resizing the render window mid-session breaks draw's styling and crashes animate's save #265

Description

@camUrban

Bug Description

Dragging, maximizing, or tile-snapping the render window after draw or animate has created it breaks the saved output in two ways. First, screenshots capture at the live window size, while the font sizes and line widths were computed once from the requested window_size through _output_rendering.get_window_scale and baked into the actors, so a resized window saves an image at the new resolution with styling scaled for the old one, reintroducing the mismatch the window scale exists to prevent. The scalar bar makes the mismatch visible even without a capture, since its box is positioned in normalized viewport coordinates and grows with the window while its fonts stay fixed. The granted-window-size validation only guards the initial request. Second, a resize during animate's rendering loop produces frames of different dimensions within one animation, and webp.save_images fails on mixed-size frames deep in its cffi layer with AttributeError: cdata 'struct WebPAnimEncoder *' points to an opaque type, after the full render time has already been spent. Both failure modes were reproduced under Xvfb, and the second is reachable in production even though the rendering loop never processes interactor events: an external window-manager-style resize was confirmed to take effect at the next render with no event pumping at all.

Location(s): pterasoftware/output.py, pterasoftware/_output_rendering.py

Expected Behavior

The saved output always has the dimensions and styling of the validated window_size request, regardless of what the user does to the window. The fix is to lock the window size in both draw and animate, in two layers. During the interactive phases, an observer on the interactor's ConfigureEvent snaps the window back with SetSize: every OS resize mechanism (drag, the maximize button, tiling and snapping, keyboard resizes) funnels into that event through the platform's native notification (ConfigureNotify on X11 and XWayland, WM_SIZE on Windows, windowDidResize on macOS), and the interactor pumps events continuously while a window is shown interactively, so the snap-back fires immediately. During the rendering loop, which never pumps events, SetSize to the requested size is re-asserted before each frame's render, and likewise before draw's single capture. The assert is cheap and idempotent when the size is already correct, and it closes the path the ConfigureEvent observer cannot cover.

Additional Context

Snap-back is the portable lock because VTK exposes neither window-manager size hints (the native non-resizable mechanism) nor a resizable flag, and SetBorders(0) would remove the title bar along with the resize handles. The lock does not change interaction during the rendering loop, since the loop already processes no mouse or scroll input.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions