mirror of
https://github.com/yshui/picom.git
synced 2025-04-07 17:44:04 -04:00
Merge pull request #1337 from yshui/leader-wm-consistency
Fix NULL dereference when refreshing window leader with an inconsistent wm tree
This commit is contained in:
commit
5f69580cc8
2 changed files with 27 additions and 0 deletions
|
@ -1448,6 +1448,8 @@ static void unredirect(session_t *ps) {
|
|||
/// keeps an internal queue of events, so we have to be 100% sure no events are
|
||||
/// left in that queue before we go to sleep.
|
||||
static void handle_x_events(struct session *ps) {
|
||||
bool wm_was_consistent = wm_is_consistent(ps->wm);
|
||||
|
||||
if (ps->vblank_scheduler) {
|
||||
vblank_handle_x_events(ps->vblank_scheduler);
|
||||
}
|
||||
|
@ -1478,6 +1480,12 @@ static void handle_x_events(struct session *ps) {
|
|||
log_fatal("X11 server connection broke (error %d)", err);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (wm_is_consistent(ps->wm) != wm_was_consistent && !wm_was_consistent) {
|
||||
log_debug("Window tree has just become consistent, queueing redraw.");
|
||||
ps->pending_updates = true;
|
||||
queue_redraw(ps);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_x_events_ev(EV_P attr_unused, ev_prepare *w, int revents attr_unused) {
|
||||
|
|
19
src/wm/wm.c
19
src/wm/wm.c
|
@ -236,6 +236,22 @@ void wm_refresh_leaders(struct wm *wm) {
|
|||
if (!wm->needs_leader_refresh) {
|
||||
return;
|
||||
}
|
||||
if (!wm_is_consistent(wm)) {
|
||||
// The window tree has not been fully replicated, we might be missing
|
||||
// windows, so we couldn't refresh the leaders here, but also can't leave
|
||||
// them NULL. So we just set them to themselves.
|
||||
log_debug("Window tree is not consistent, setting all leaders to "
|
||||
"themselves");
|
||||
list_foreach(struct wm_tree_node, i, &wm->tree.root->children, siblings) {
|
||||
if (i->is_zombie) {
|
||||
// Don't change anything about a zombie window.
|
||||
continue;
|
||||
}
|
||||
i->leader_final = i;
|
||||
}
|
||||
return;
|
||||
}
|
||||
log_debug("Refreshing window leaders");
|
||||
wm->needs_leader_refresh = false;
|
||||
list_foreach(struct wm_tree_node, i, &wm->tree.root->children, siblings) {
|
||||
if (i->is_zombie) {
|
||||
|
@ -249,6 +265,9 @@ void wm_refresh_leaders(struct wm *wm) {
|
|||
continue;
|
||||
}
|
||||
wm_find_leader(wm, i);
|
||||
BUG_ON_NULL(i->leader_final);
|
||||
log_verbose("Window %#010x has leader %#010x", i->id.x,
|
||||
i->leader_final->id.x);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue