Repository: electron/electron (language: cpp)

Issue:
Video afterimages remain
### Preflight Checklist

- [x] I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/main/CONTRIBUTING.md) for this project.
- [x] I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/main/CODE_OF_CONDUCT.md) that this project adheres to.
- [x] I have searched the [issue tracker](https://www.github.com/electron/electron/issues) for a bug report that matches the one I want to file, without success.

### Electron Version

35.0.0

### What operating system(s) are you using?

macOS

### Operating System Version

macOS 15.3.1

### What arch are you using?

arm64 (including Apple Silicon)

### Last Known Working Electron version

34.3.1

### Expected Behavior

Rotating `<video>` with `transform:rotate()` does not leave the video image.

### Actual Behavior

This video is a somewhat unusual media viewer that I am developing.
The landscape on the left is an image, and the rabbit on the right is a video.

in v34.3.1
<video src="https://github.com/user-attachments/assets/c6a1bb00-23a6-4ad0-beeb-ca2ffbfac15e">

Each has a `<img>` and `<video>` placed in a window with a transparent background, and is rotated with CSS `transform:rotate()` in response to the wheel event.


There were no problems up to Electron v34.3.1. However, after updating to Electron v35.0.0, an afterimage remained when rotating the video.

in v35.0.0
<video src="https://github.com/user-attachments/assets/afe3015f-fedf-4736-98c4-3140d3d6ee5e">

There is no problem with images. It only occurs with videos.


I haven't changed any code. I've just updated the Electron version.
I think this is an Electron issue.

### Testcase Gist URL

_No response_

### Additional Information

_No response_


Discussion / hints:
This might very well be a bug in Chromium.

I'd recommend:

1. Testing if this happens in the Chromium (Google Chrome) version that Electron 35 uses. If yes, please file a bug directly with Chromium and link to it here.
2. If it doesn't happen in Chromium, please provide a minimal code example that allows maintainers to reproduce this issue, preferably through Electron Fiddle.
I have spent a lot of time, researched, and gone through trial and error, but I have concluded that it is not possible to reproduce and confirm the issue in pure Chromium, which is unrelated to Electron.

As shown in the shared reproduction video, the condition for reproducing the issue is that the window background color must be transparent. I have confirmed that even in Electron v35, the issue does not occur when `transparent: false` is specified during window creation.

In order to have a transparent window background, the only way is to use Electron to create the window. Even if the issue is reproduced in such a window, it would not be possible to determine whether the cause is related to Electron or Chromium.

I believe it is not possible to verify this issue purely in Chromium without Electron. If there is a way to do so, I would appreciate any guidance.


Thanks for the update!

What you might try for reproducing it in Chromium: Put your code into an iframe with transparent background. Similar to what was done here: https://issues.chromium.org/issues/391907157 / https://github.com/electron/electron/issues/45206

We discussed this in a meeting and the consensus was that the issue is probably somewhere in Chromium's rendering logic.

My own guess is that the rendering logic is not invalidating certain parts of the window, i.e. it's not triggering those areas to be repainted.

It could be that it's some edge case that never happens in Chromium itself because of the transparency requirement. However, I think you might be able to trigger it in Chromium through the iframe workaround.

Getting an issue up in Chromium with some code that reproduces it is definitely the fastest way to get this resolved.

That said, for any issue, either Chromium or Electron will need a minimal reproducible example, so I'm adding the `blocked/need-repro` label.
<!-- blocked/need-repro -->

Hello @sdr0x07b6. Thanks for reporting this and helping to make Electron better!

Would it be possible for you to make a standalone testcase with only the code necessary to reproduce the issue? For example, [Electron Fiddle](https://www.electronjs.org/fiddle) is a great tool for making small test cases and makes it easy to publish your test case to a [gist](https://gist.github.com) that Electron maintainers can use.

Stand-alone test cases make fixing issues go more smoothly: it ensure everyone's looking at the same issue, it removes all unnecessary variables from the equation, and it can also provide the basis for automated regression tests.

Now adding the https://github.com/electron/electron/labels/blocked%2Fneed-repro label for this reason. After you make a test case, please link to it in a followup comment. This issue will be closed in 10 days if the above is not addressed.
Hi, I found the same issue. I created this simple example using Electron Fiddle where the renders are stacked repeatedly instead of refreshing between animation frames. https://gist.github.com/16a93bcc4156b58e0c3adebdbef71be6

Note that `transparent: true` is required, but the other conditions are more stringent. For example, `blur` and `rotate3d` are not required to trigger this bug, but they will trigger this abnormal behavior in some combinations.

Fix patch:
diff --git a/shell/browser/native_window_mac.mm b/shell/browser/native_window_mac.mm
index 37ff7da6d625f..dbeceb836ea77 100644
--- a/shell/browser/native_window_mac.mm
+++ b/shell/browser/native_window_mac.mm
@@ -196,6 +196,9 @@ static bool FromV8(v8::Isolate* isolate,
   params.type = views::Widget::InitParams::TYPE_WINDOW;
   // Allow painting before shown, to be later disabled in ElectronNSWindow.
   params.headless_mode = true;
+  if (IsTranslucent()) {
+    params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent;
+  }
   params.native_widget =
       new ElectronNativeWidgetMac(this, windowType, styleMask, widget());
   widget()->Init(std::move(params));


Test patch: