WINGs/wclient_wl: clear input focus refs on toplevel destroy

When a popup toplevel is destroyed (e.g., menu editor submenu closes),
its WLClientToplevel struct is freed.  If wlc_kbd_focused or
wlc_ptr_focused pointed to it, subsequent input events dereferenced
the dangling pointer and crashed (saw it in keyboard_handle_leave).

Clear both refs in wl_client_view_destroy_backing before freeing.
This commit is contained in:
Window Maker 2026-05-24 19:05:35 +02:00
parent b040b5c7fe
commit bf356c2567
1 changed files with 9 additions and 2 deletions

View File

@ -417,8 +417,15 @@ wl_client_view_commit(unsigned long id)
static void
wl_client_view_destroy_backing(unsigned long id)
{
extern WLClientToplevel *wlc_kbd_focused;
extern WLClientToplevel *wlc_ptr_focused;
WLClientToplevel *top = wlc_top_find((WNativeWindow)id);
if (!top) return;
/* Clear any input-focus references that point to this toplevel
* before we free it, so subsequent input events don't dereference
* a dangling pointer. */
if (wlc_kbd_focused == top) wlc_kbd_focused = NULL;
if (wlc_ptr_focused == top) wlc_ptr_focused = NULL;
if (top->wmaker_popup) wmaker_popup_v1_destroy(top->wmaker_popup);
if (top->xdg_toplevel) xdg_toplevel_destroy(top->xdg_toplevel);
if (top->xdg_surface) xdg_surface_destroy(top->xdg_surface);
@ -608,7 +615,7 @@ wlc_xkb_mod_mask(struct xkb_state *state)
static double wlc_ptr_x, wlc_ptr_y;
static uint32_t wlc_ptr_focus_serial;
uint32_t wlc_ptr_button_serial; /* serial of most recent button press */
static WLClientToplevel *wlc_ptr_focused;
WLClientToplevel *wlc_ptr_focused;
unsigned int wlc_ptr_button_state;
static unsigned int wlc_ptr_mods;
static W_View *wlc_ptr_child_focus;
@ -871,7 +878,7 @@ static const struct wl_pointer_listener pointer_listener = {
/* Keyboard */
/* ------------------------------------------------------------------ */
static WLClientToplevel *wlc_kbd_focused;
WLClientToplevel *wlc_kbd_focused;
static void
keyboard_handle_keymap(void *data, struct wl_keyboard *k,