https://bugs.kde.org/show_bug.cgi?id=528239
Bug ID: 528239
Summary: Scripted shader effect: window snapshot stays
empty/transparent when another window already animates
with the same effect (CrossFadeEffect::redirect /
drawWindow recursion guard)
Classification: Plasma
Product: kwin
Version First 6.8.2
Reported In:
Platform: Arch Linux
OS: Linux
Status: REPORTED
Severity: minor
Priority: NOR
Component: effects-various
Assignee: [email protected]
Reporter: [email protected]
Target Milestone: ---
When a scripted effect applies a fragment shader to windows (via `animate()`
with `Effect.ShaderUniform`, which goes through `AnimationEffect` and
`CrossFadeEffect`), the snapshot of a window is empty and transparent if the
same effect is already active for another window. The shader then draws a black
or invisible window.
STEPS TO REPRODUCE
1. Use a scripted effect that animates windows with a fragment shader (for
example a Burn-My-Windows style close or minimize effect).
2. Start the effect on a window and, while it is still running, start it on a
second window (for example by minimizing two windows in quick succession).
ACTUAL RESULTS
The second window has no content in the shader. The shader receives an empty,
transparent snapshot, which becomes black or invisible, and at the end the real
window flashes back. With a single window at a time it works correctly.
EXPECTED RESULTS
The snapshot of the second window contains the real window, like it does for a
single window.
ANALYSIS (read from the source of v6.8.2; I have not run a patched build)
- In `CrossFadeEffect::redirect()` (`src/effect/offscreeneffect.cpp`) the
window is added to `d->windows` before the snapshot is rendered by
`maybeRender()`.
- `OffscreenData::maybeRender()` renders the window with
`effects->drawWindow()`, which goes through all active effects. A scripted
effect counts as active while it has animations (`AnimationEffect::isActive`),
so when it is already running for another window, the call reaches
`CrossFadeEffect::drawWindow()` of the same effect again.
- That function only paints the real window if `data.crossFadeProgress() > 0 ||
it == d->windows.end()`. During the snapshot the progress is 0 and the window
is already registered, so nothing is painted.
- `m_recursionGuard` prevents an endless loop, but it makes the function return
without painting, so the snapshot stays empty.
- `OffscreenEffect::drawWindow()` handles this differently: when its recursion
guard is set, it paints the real window.
- The same code is in master.
SUGGESTED CHANGE (not tested)
Let `CrossFadeEffect::drawWindow()` also paint the real window when the
recursion guard is set, like `OffscreenEffect::drawWindow()` does:
- if (data.crossFadeProgress() > 0 || it == d->windows.end()) {
+ if (it == d->windows.end() || it->second->m_recursionGuard ||
data.crossFadeProgress() > 0) {
This only changes behavior while a snapshot is being taken, because only then
is the guard set.
ENVIRONMENT
KWin 6.8.2 (Arch package 6.8.2-1.1), Wayland.
--
You are receiving this mail because:
You are watching all bug changes.