Skip to content

fix(linux) + feat(ui): fix video export crash on Linux and improve editor UI polish - #998

Closed
Rajanvik wants to merge 1 commit into
webadderallorg:mainfrom
Rajanvik:feat/ui-improvements-and-fullscreen-preview
Closed

Rajanvik wants to merge 1 commit into
webadderallorg:mainfrom
Rajanvik:feat/ui-improvements-and-fullscreen-preview

Conversation

@Rajanvik

@Rajanvik Rajanvik commented Sep 18, 2026

Copy link
Copy Markdown

Summary

This PR fixes a critical video export crash on Linux and includes UI polish improvements made while investigating the issue.


Bug Fix: Video export crash on Linux

Problem

On Linux — particularly with Intel integrated graphics and Mesa drivers inside Electron — video export was silently failing or crashing with the following error:

TypeError: Cannot read properties of undefined (reading '_resourceType')
    at BindGroup (pixi.js)

There were three root causes.

Root cause 1: WebGPU selected by default on Linux despite driver instability

PixiJS v8's WebGPU backend has known upstream driver-compatibility issues on Linux that are not yet resolved. Modern Electron exposes navigator.gpu on Linux, which caused the renderer to pick WebGPU as its default backend even though the implementation is unstable on Intel/Mesa integrated graphics.

Root cause 2: Texture double-free / use-after-free

In three hot-path methods — updateLayerTexture, uploadVideoFrameToSprite, and updateCaptionTexture — the previous texture was destroyed unconditionally:

previousTexture.destroy(true);

When the new texture shared the same underlying GPU source as the previous one, this destroyed a resource still in active use and caused a GPU crash on any backend, most visibly under WebGPU.

Root cause 3: Retained VideoFrame / ImageBitmap lifetime bugs

resolveDetachedVideoFrameSource had complex per-backend branching — an ImageBitmap cache for WebGPU, a retained VideoFrame path, and a canvas staging fallback — that produced hard-to-reproduce texture lifetime bugs across backends.

Fix

Fix 1: Force WebGL on Linux by default

const isLinux =
  typeof navigator !== "undefined" &&
  navigator.userAgent.toLowerCase().includes("linux");

const backendOrder: ExportRenderBackend[] =
  preferredRenderBackend === "webgl" ||
  (isLinux && preferredRenderBackend !== "webgpu")
    ? ["webgl", "webgpu"]
    : preferredRenderBackend === "webgpu"
      ? ["webgpu", "webgl"]
      : ...

WebGPU remains available as an explicit opt-in for Linux users who have working drivers. This only changes the default.

Fix 2: Guard texture destroy with a same-source check

const isSameSource = previousTexture.source === nextTexture.source;
previousTexture.destroy(!isSameSource);

Applied consistently in all three hot-path methods.

Fix 3: Simplify frame source resolution

Removed the complex per-backend retained-VideoFrame and ImageBitmap cache from resolveDetachedVideoFrameSource. All backends now use stageVideoFrameOnCanvas, which is the simplest and most tested path. The now-unused fields retainedSceneBitmapTimestamp and retainedBackgroundBitmapTimestamp are removed.


UI Improvements

These improvements were made while auditing the codebase. They are non-breaking, presentation-only changes.

Sidebar rail navigation redesign

The active section indicator has been redesigned from a faint background pill with a small blue dot to an animated inverted-curve background that connects the active icon flush into the settings panel content area.

  • Framer Motion layoutId="rail-active-bg" provides a smooth spring animation when switching sections.
  • SVG corner curves at the top and bottom of the active indicator give a seamless connected-tab appearance.
  • The motion.button wrapper is replaced with a plain button element with a motion.span for the icon, reducing DOM complexity.
  • Icon size normalised from h-[27px] w-[27px] to h-[24px] w-[24px].
  • whileHover opacity added for inactive icons.

Fullscreen preview mode

Adds a distraction-free fullscreen preview toggle to the editor.

  • index.css: A new body.preview-fullscreen rule hides [data-editor-header], [data-editor-sidebar], [data-editor-timeline], and [data-editor-announcement] using display: none. The hide/show requires no JavaScript beyond toggling the body class.
  • EditorShell.tsx: Each panel section is wrapped with its corresponding data-editor-* attribute so the CSS rule can target it.
  • EditorPreviewPanel.tsx: Adds isFullscreen state with a CornersIn exit button positioned in the top-right corner of the preview area. The button uses a semi-transparent backdrop-blur pill and reveals on hover. Toolbar controls are hidden while fullscreen is active. The preview container margin adapts to the fullscreen layout.

Theme token cleanup

All occurrences of the hardcoded hex #2563EB across 17 component files are replaced with semantic Tailwind CSS variable utilities so the UI correctly responds to the --primary CSS variable already used for theming.

Before After
bg-[#2563EB] bg-primary
text-[#2563EB] text-primary
border-[#2563EB]/20 border-primary/20
data-[state=checked]:bg-[#2563EB] data-[state=checked]:bg-primary
selection:bg-[#2563EB]/30 selection:bg-primary/30

Undo / Redo button polish

  • Removed the border and background from the inactive state.
  • Size normalised from h-8 w-8 to h-7 w-7. Icon size from h-4 w-4 to h-[14px] w-[14px].

Files changed

File Type
src/lib/exporter/modernFrameRenderer.ts Bug fix
src/components/video-editor/layout/EditorSidebar.tsx Sidebar redesign
src/components/video-editor/layout/EditorPreviewPanel.tsx Fullscreen preview
src/components/video-editor/layout/EditorShell.tsx data-editor-* attributes
src/index.css Fullscreen CSS rule
src/components/video-editor/layout/EditorHeader.tsx Undo/Redo polish
26 other component files Theme tokens (#2563EB to primary)

Testing

  • Video export completes without crash on Linux with Intel Mesa and Electron.
  • Video export is unaffected on macOS (WebGPU path unchanged).
  • Video export is unaffected on Windows.
  • Exported video quality and frame accuracy are unchanged.
  • User-selected WebGPU preference in export settings is still respected on Linux.
  • Sidebar section switching animates smoothly between all sections.
  • Fullscreen preview hides all UI panels correctly.
  • Fullscreen exit button reveals on hover and exits correctly.
  • Theme colours update correctly when --primary is changed.
  • No TypeScript errors.
  • No new dependencies added.

Summary by CodeRabbit

  • New Features
    • Added fullscreen preview mode with Escape-to-exit support and simplified fullscreen controls.
  • Visual Improvements
    • Updated the video editor layout, sidebar, settings panels, controls, and dialogs with refreshed spacing, sizing, and card styling.
    • Replaced fixed accent colors with theme-aware colors throughout the editor for more consistent customization.
  • Compatibility
    • Improved video frame processing across supported rendering environments, including more consistent behavior on Linux.

…olish

## Bug Fix — Linux video export crash (modernFrameRenderer.ts)

On Linux with Intel/Mesa integrated graphics, video export was crashing with:
  TypeError: Cannot read properties of undefined (reading '_resourceType')

Root cause 1 — WebGPU instability on Linux:
PixiJS v8 WebGPU backend has known upstream driver issues on Linux inside
Electron. The renderer was picking WebGPU by default whenever navigator.gpu
was present — which Electron exposes on Linux even though the implementation
is unstable on Intel/Mesa. Fixed by detecting Linux via navigator.userAgent
and forcing backend order to [webgl, webgpu] unless user has explicitly
opted into WebGPU in export settings.

Root cause 2 — Texture double-free / use-after-free:
Three hot-path methods were calling previousTexture.destroy(true)
unconditionally. When the new and previous texture shared the same underlying
GPU source, this destroyed a live GPU resource causing a crash on any backend.
Fixed by guarding: previousTexture.destroy(!isSameSource).

Root cause 3 — Retained VideoFrame / ImageBitmap lifetime bugs:
The resolveDetachedVideoFrameSource method had complex per-backend branching
(retained VideoFrame path for WebGPU, ImageBitmap cache, canvas staging) that
produced hard-to-reproduce texture lifetime bugs. Simplified to always use
stageVideoFrameOnCanvas for all backends. Removed now-unused fields
retainedSceneBitmapTimestamp and retainedBackgroundBitmapTimestamp.

## UI Improvements — Editor design polish

1. Sidebar rail navigation redesign (EditorSidebar)
   - New animated active-section indicator using Framer Motion layoutId with
     SVG inverted corner curves — connects the active icon flush into the
     settings panel content area (macOS-style tab indicator)
   - Replaced motion.button wrapper with plain button + motion.span for icon
   - Icon size normalised to h-[24px] w-[24px]
   - whileHover opacity added for inactive icons

2. Fullscreen preview mode (EditorPreviewPanel + EditorShell + index.css)
   - index.css: body.preview-fullscreen class hides [data-editor-header],
     [data-editor-sidebar], [data-editor-timeline], [data-editor-announcement]
     via display:none — zero JS for the hide/show
   - EditorShell: each panel section wrapped with its data-editor-* attribute
   - EditorPreviewPanel: isFullscreen state, CornersIn exit button top-right
     (hover-reveal with backdrop-blur), controls/toolbar hidden in fullscreen,
     preview margin adapts to fullscreen layout

3. Theme token cleanup — remove hardcoded #2563EB across 17 files
   Every occurrence of bg-[#2563EB], text-[#2563EB], border-[#2563EB]/x,
   data-[state=checked]:bg-[#2563EB], selection:bg-[#2563EB]/30 replaced
   with the semantic utilities bg-primary, text-primary, border-primary/x,
   data-[state=checked]:bg-primary, selection:bg-primary/30.
   This makes the UI respect the --primary CSS variable used for theming.

4. Undo/Redo button polish (EditorHeader)
   - Removed border + background from inactive state
   - Size: h-8 w-8 -> h-7 w-7, icon h-4 w-4 -> h-[14px] w-[14px]
@coderabbitai

coderabbitai Bot commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 3b827c8f-0d88-4052-b14b-5780fb7b6fd9

📥 Commits

Reviewing files that changed from the base of the PR and between b3ea775 and edb3651.

📒 Files selected for processing (32)
  • src/components/ui/select.tsx
  • src/components/ui/switch.tsx
  • src/components/video-editor/AnnotationOverlay.tsx
  • src/components/video-editor/AnnotationSettingsPanel.tsx
  • src/components/video-editor/CaptionListPanel.tsx
  • src/components/video-editor/CropControl.tsx
  • src/components/video-editor/ExportSettingsMenu.tsx
  • src/components/video-editor/ExtensionManager.tsx
  • src/components/video-editor/FormatSelector.tsx
  • src/components/video-editor/KeyboardShortcutsHelp.tsx
  • src/components/video-editor/PlaybackControls.tsx
  • src/components/video-editor/ProjectBrowserDialog.tsx
  • src/components/video-editor/SettingsPanel.tsx
  • src/components/video-editor/ShortcutsConfigDialog.tsx
  • src/components/video-editor/SliderControl.tsx
  • src/components/video-editor/TutorialHelp.tsx
  • src/components/video-editor/VideoPlayback.tsx
  • src/components/video-editor/WebcamCropControl.tsx
  • src/components/video-editor/layout/CropEditorDialog.tsx
  • src/components/video-editor/layout/EditorExportMenu.tsx
  • src/components/video-editor/layout/EditorHeader.tsx
  • src/components/video-editor/layout/EditorPresetMenu.tsx
  • src/components/video-editor/layout/EditorPreviewPanel.tsx
  • src/components/video-editor/layout/EditorShell.tsx
  • src/components/video-editor/layout/EditorSidebar.tsx
  • src/components/video-editor/timeline/ItemGlass.module.css
  • src/components/video-editor/timeline/components/axis/TimelineAxis.tsx
  • src/components/video-editor/timeline/components/markers/KeyframeMarkers.tsx
  • src/components/video-editor/timeline/components/playhead/PlaybackCursor.tsx
  • src/components/video-editor/timeline/components/toolbar/TimelineToolbar.tsx
  • src/index.css
  • src/lib/exporter/modernFrameRenderer.ts
 ____________________________________
< Squash the bug, not the messenger. >
 ------------------------------------
  \
   \   \
        \ /\
        ( )
      .( o ).
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Rajanvik Rajanvik closed this Sep 18, 2026
@Rajanvik
Rajanvik deleted the feat/ui-improvements-and-fullscreen-preview branch September 18, 2026 10:11
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.

1 participant