Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

win: rework how events for unmapped windows are handled #546

Merged
merged 7 commits into from
Nov 29, 2020

Conversation

yshui
Copy link
Owner

@yshui yshui commented Nov 27, 2020

Make unmapped window events work mostly like a mapped window, except
flags set on unmapped windows aren't processed until the window is
mapped.

Hopefully this unifies some of the code paths and reduce corner cases.

Should fix #525

Signed-off-by: Yuxuan Shui yshuiv7@gmail.com

TODO

@yshui
Copy link
Owner Author

yshui commented Nov 27, 2020

@tryone144 would appreciate if you can give this a look, thanks.

@codecov
Copy link

codecov bot commented Nov 27, 2020

Codecov Report

Merging #546 (0f97561) into next (bf5a9ca) will increase coverage by 0.44%.
The diff coverage is 88.09%.

Impacted file tree graph

@@            Coverage Diff             @@
##             next     #546      +/-   ##
==========================================
+ Coverage   37.76%   38.21%   +0.44%     
==========================================
  Files          46       46              
  Lines        9055     9056       +1     
==========================================
+ Hits         3420     3461      +41     
+ Misses       5635     5595      -40     
Impacted Files Coverage Δ
src/picom.c 68.39% <66.66%> (-0.39%) ⬇️
src/event.c 69.63% <88.23%> (+3.98%) ⬆️
src/win.c 69.11% <91.07%> (+2.86%) ⬆️
src/win.h 50.00% <100.00%> (+8.33%) ⬆️

src/win.c Show resolved Hide resolved
src/win.c Show resolved Hide resolved
src/win.c Show resolved Hide resolved
src/win.c Show resolved Hide resolved
src/win.c Show resolved Hide resolved
src/win.c Show resolved Hide resolved
@yshui yshui requested a review from tryone144 November 27, 2020 05:45
@yshui
Copy link
Owner Author

yshui commented Nov 27, 2020

Observed a crash on this. investigating...

Update: fixed.

@yshui yshui force-pushed the window-state-update branch 4 times, most recently from e855586 to 5286bdb Compare November 27, 2020 20:39
Copy link
Collaborator

@tryone144 tryone144 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some comments to clarify. But looks good overall.

  • Some questions left regarding destroy_backend().
  • We could add assertion checks to, e.g., win_on_win_size_change() to be only called on "mapped" windows like already done in win_set_shadow().
  • Is the xinerama screen properly initialized in fill_win or by a configure event, or does this introduce a regression?
  • Todo note in map_win_start() regarding win_on_factor_change().

src/picom.c Outdated
Comment on lines 405 to 413
if (w->state == WSTATE_MAPPED) {
win_release_images(ps->backend_data, w);
} else {
// Unmapped windows could still have shadow images.
// And they might have image stale flags set by events.
assert(!w->win_image);
assert(!w->shadow_image);
win_clear_flags(
w, WIN_FLAGS_PIXMAP_STALE | WIN_FLAGS_SHADOW_STALE);
win_release_images(ps->backend_data, w);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think mapped windows can also have stale shadows (related to #395 and #479 (comment)) letting win_release_images() fail. Back then I couldn't reproduce this artificially, though.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting, I wonder why. I think destroy_backend can only be reached after the critical section, so the stale flags should already be handled for mapped windows.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • paint_preprocess() -> unredirect() -> destroy_backend() is called after the critical section before rendering and should be safe.
  • session_destroy() -> unredirect() -> destroy_backend() is called in main after session_run() returns. Are we safe there?
  • handle_root_flags() -> configure_root() -> destroy_backend() is called IN the critical section BEFORE the stale flags have been handled. This might fail if pixmaps get invalidated during a root-change (i.e. screen size changes?). I have a testcase for that, but I can't get the timing right to trigger this.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, 2 and 3 are not safe.

I don't see a good solution beside always clear the stale flags, so that's what I'll do.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you post your testcase for 3 somewhere? Thanks.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you post your testcase for 3 somewhere? Thanks.

https://gist.github.com/tryone144/1103f5107448fecf5e7e02a6cf4ffb02

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, looking at the code, I think IMAGES_STALE flags are only set by win_process_update_flags, and immediately handled later in win_process_image_flags; except for one case, where map_win_start is called in handle_new_windows.

That seems to be the only case where it's possible for destroy_backend to see a image stale flag.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like with this PR, we don't have to call map_win_start in handle_new_windows anymore. So we can eliminate case 3 (if my previous point is correct).

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tryone144 i'm going to merge this for now.

src/win.c Show resolved Hide resolved
src/win.c Show resolved Hide resolved
src/win.c Show resolved Hide resolved
src/win.c Show resolved Hide resolved
src/win.c Show resolved Hide resolved
src/win.c Show resolved Hide resolved
src/win.c Show resolved Hide resolved
src/win.c Outdated Show resolved Hide resolved
src/win.c Show resolved Hide resolved
// TODO(yshui) can we just replace calls below with win_on_factor_change?

// Update window focus state
win_update_focused(ps, w);
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is called in win_process_update_flags -> win_on_factor_change

src/win.c Show resolved Hide resolved
@yshui
Copy link
Owner Author

yshui commented Nov 28, 2020

I deleted two more update calls from map_win_start

@yshui yshui force-pushed the window-state-update branch 2 times, most recently from 3f48ea6 to f1da2c2 Compare November 28, 2020 03:10
@yshui
Copy link
Owner Author

yshui commented Nov 28, 2020

@tryone144 Actually, my impression about what caused #525 is wrong. It's not a window received an update when it's unmapped, it happens because a window's pixmap is invalidated, then the window immediately got unmapped.

This PR should still fix the problem though.

@tryone144
Copy link
Collaborator

@yshui I think the failure in win_on_win_size_change in #525 is just a secondary issue. The main problem was the handling of events for windows that just became unmapped.
We just never got to the point where we refreshed the invalidated pixmaps since win_size is handled before and failed.

@yshui
Copy link
Owner Author

yshui commented Nov 28, 2020

@tryone144

The main problem was the handling of events for windows that just became unmapped.

Right. It's just my impression of what happens first was wrong.

yshui added a commit that referenced this pull request Nov 28, 2020
Reference: #546 (comment)

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
Copy link
Collaborator

@tryone144 tryone144 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just nitpicking. 😉

src/picom.c Outdated Show resolved Hide resolved
src/picom.c Outdated Show resolved Hide resolved
src/picom.c Outdated Show resolved Hide resolved
Make unmapped window events work mostly like a mapped window, except
flags set on unmapped windows aren't processed until the window is
mapped.

Hopefully this unifies some of the code paths and reduce corner cases.

Should fix #525

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
While working on this PR, I introduced a bug where shadow images for
unmapped windows aren't properly recreated after unredirect/redirect.

The shadow image is freed during unredirect, OTOH redirect only set
IMAGE_STALE flags for mapped window, thus the shadow images for unmapped
windows will be missing.

This bug is already fixed in the previous commit. But the testcase is
good to keep nonetheless.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
Reference: #546 (comment)

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
Set WIN_FLAGS_MAPPED instead, it will be handled later. Previously, we
call map_win_start because we need the geometry of the window, which is
updated in map_win_start. Now, we get the geometry in fill_win, so
map_win_start is not needed anymore.

Eliminate a case where destroy_backend could see IMAGES_STALE flags set
on windows.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
After 60f733d, we can be sure stale
flags won't be seen in destroy_backend.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
@yshui yshui merged commit fb38bf0 into next Nov 29, 2020
@yshui yshui deleted the window-state-update branch November 29, 2020 00:20
This was referenced Nov 29, 2020
FT-Labs pushed a commit to FT-Labs/picom that referenced this pull request Jan 23, 2023
Reference: yshui#546 (comment)

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
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.

Picom Crashes after some time
2 participants