Handle more (hopefully all) edge-cases when updating `opacity_target_old`:
* `MAPPING` transitions to `FADING` if new target is reached. Otherwise
no update.
* `FADING` clamps to current `opacity` if old target is too small.
* `UNMAPPING`/`DESTROYING` clamps to current `opacity` if old target is
too small.
* Add new field `opacity_target_old` to `struct managed_win` for
tracking relevant `opacity_target` changes.
* Smoothly fade blur-texture opacity on window opacity changes (based on
window opacity), when the window was or will be fully transparent
(`w->opacity ~< 0.004`).
* Fixed alpha-clipping of the blur-texture when using `inactive-opacity` or
repeatedly setting window opacity with large fade intervals (should fix#314).
These two flags are intended for subtly different things. I can probably
justify the distinction, but it's definitely difficult to explain. And
there is no obvious benefits to keep them separate.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
Commits reverted:
b652e8b58dbdf809d039e9ab970989481ac54f67
While those commits themselves could be useful even if they don't
completely fix#299, they come with the risks of introduce more
unforeseen bugs, which outweigh their benefit, so revert them.
A brief explanation of their problem:
The fix hinges on the destroy event of the client window to work.
However, the client window could be destroyed so fast, before we even
handle the map, or even the create, event of the frame. And we won't be
listening for substructure events on the frame at the point the client
window is destroyed. Thus completely miss the client window destroy
event.
Because of the inherent racy nature of Xorg, this approach is really
difficult to make work.
Fixes#371
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
So we can pick up destroy notify of the client windows. Because we need
the destroy notify of the client window to trigger a client window
recheck on the frame window. This is to handle the case where a frame
window is later reused, and the case where multiple client windows are
momentarily attached to the same frame[1].
This will also cause events previously unseen to be generated. Most of
the events would be ignored, because they don't have a corresponding
managed window. Change has been made to ev_reparent_notify, so it would
handle the case where a client window is reparented from one frame to
another[2]. Previously such events are not received by picom.
Related[1]: e9ab970989
Related[2]: 481ac54f67
Related: #299
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
We detach the client window from its frame when it's destroyed, so later
a new window can be attached to that frame. But turns out that's not
enough.
When i3 restarts, it attaches a placeholder window to the frame, then
the real window, and only after that, it will destroy the placeholder.
The real window will fail to attach as the frame already has a client.
When the placeholder is destroyed, we have to call recheck client to
pick up the real window that failed to attach previously.
Related: #299
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
Basically, don't ignore the reparent notify if the window is already a
client window. We already unmark it from its previous frame, so this
commit make sure it gets marked with its new frame.
Related: #299
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
We do nothing when a non-wm-frame window is destroyed. This will cause
trouble if a wm-frame window is reused (i.e. its child is destroyed then
a new child is reparented to it), because we didn't clear client_win.
So this commit adds a call to win_unmark_client for that case.
Related: #299
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
Removed unnecessary if statement and unnecessary /dev/null redirect on line 19
Line 26 can use argless printf rather than echo -n
Error verbose prints in red and to STDERR rather than to STDOUT
Textually replaced compton with picom where applicable.
Removed unnecessary semicolons after exit commands
I might've missed/screwed something but lets hope that isnt the case 😎
Previously, root ConfigureNotify is handled immediately, by resetting
the backend, which in turn releases all the window images. This puts all
the windows into a state where they don't have images attached, which
they really should be in when the screen is redirected.
(To expand a little, a window without images should only exist if:
* It's an unmanaged window.
* Screen is unredirected.)
Normally, this kind of window could be fine, as the next render phase
will re-acquire images for them. However, if a window in this state is
destroyed with fading enabled, then the render phase won't try to
acquire images for it, causing it to go into the main rendering function
without images attached, and trigger an assertion.
This commit delays the handling of root ConfigureNotify until the render
phase. This way, the images will be immediately re-acquired after they
are released, thus prevent this problem from happening.
Also adds a testcase for this.
Fixes#357
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
x_print_error aborts the program when it sees a redirect_subwindow
failure. A function called x_print_error really shouldn't cause the
program to terminate.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
In configure_root, the root pixmap is freed by destroy_backend, and is
never acquired again.
Usually this doesn't seem to cause any problems, maybe because we
immediately receives a root damage notification. But under rare
circumstances we ended up not showing the wallpaper.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
Frame extents are only updated when the window has frame_opacity < 1.
However, window frames can have inherent transparency, and not having
the frame extents information for those windows breaks blur-background-frame.
Fixes#345
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
The focused state is a derivative state of the raw focused state (i.e.
whether the window is actually focused), with focus rules applied.
Here, we consolidate the calculation of the focused state into the
win_on_factor_change function, and replaced all calls to
win_update_focused with win_on_factor_change.
Also, the opacity update in win_update_focused is moved to
win_on_factor_change, as there could be opacity rules depending on the
focused state, so opacity must only be updated after
win_update_opacity_rule is called.
Related: #266#317
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
Always refresh derivative window states in win_on_factor_change, without
checking if there are rules set.
c2_match is a no-op when there is no rules set. And we want to
consolidate derivative window state updates to one place,
win_on_factor_change is a good choice for that.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>