fix: defer setmon() after scene_surface creation to prevent segfault on window map
Root cause: applyrules() called setmon() which called resize(), but resize() dereferences c->scene_surface->node before c->scene_surface was created in mapnotify(). Fix by storing target monitor/tags in pending_mon/pending_tags fields and calling setmon() after scene nodes exist. The crash affected all new windows, not just Firefox (which was the first tested).
This commit is contained in:
@@ -67,6 +67,10 @@ typedef struct Client {
|
|||||||
bool can_fullscreen;
|
bool can_fullscreen;
|
||||||
ClientRuleEffects rule_effects;
|
ClientRuleEffects rule_effects;
|
||||||
|
|
||||||
|
/* Deferred monitor/tags — set by applyrules, used by setmon in mapnotify */
|
||||||
|
Monitor *pending_mon;
|
||||||
|
uint32_t pending_tags;
|
||||||
|
|
||||||
/* COLD — wl_listeners (set up once, rarely touched after) */
|
/* COLD — wl_listeners (set up once, rarely touched after) */
|
||||||
struct wl_listener commit;
|
struct wl_listener commit;
|
||||||
struct wl_listener map;
|
struct wl_listener map;
|
||||||
|
|||||||
+7
-4
@@ -492,7 +492,8 @@ static void applyrules(Client *c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
c->isfloating |= client_is_float_type(c);
|
c->isfloating |= client_is_float_type(c);
|
||||||
setmon(c, mon, newtags);
|
c->pending_mon = mon;
|
||||||
|
c->pending_tags = newtags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void client_arr_add(Client *c) {
|
static void client_arr_add(Client *c) {
|
||||||
@@ -956,10 +957,9 @@ static void commitnotify(struct wl_listener *listener, void *data) {
|
|||||||
* a wrong monitor.
|
* a wrong monitor.
|
||||||
*/
|
*/
|
||||||
applyrules(c);
|
applyrules(c);
|
||||||
if (c->mon) {
|
if (c->pending_mon) {
|
||||||
client_set_scale(client_surface(c), c->mon->wlr_output->scale);
|
client_set_scale(client_surface(c), c->pending_mon->wlr_output->scale);
|
||||||
}
|
}
|
||||||
setmon(c, nullptr, 0); /* Make sure to reapply rules in mapnotify() */
|
|
||||||
|
|
||||||
wlr_xdg_toplevel_set_wm_capabilities(
|
wlr_xdg_toplevel_set_wm_capabilities(
|
||||||
c->surface.xdg->toplevel, WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN);
|
c->surface.xdg->toplevel, WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN);
|
||||||
@@ -2289,6 +2289,9 @@ static void mapnotify(struct wl_listener *listener, void *data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Deferred setmon — scene nodes now exist */
|
||||||
|
setmon(c, c->pending_mon, c->pending_tags);
|
||||||
|
|
||||||
if (c->isfullscreen)
|
if (c->isfullscreen)
|
||||||
setfullscreen(c, 1);
|
setfullscreen(c, 1);
|
||||||
if (c->border_bg)
|
if (c->border_bg)
|
||||||
|
|||||||
Reference in New Issue
Block a user