wayland: fix double-free crash when destroying shared WApplication

When main_window_desc is the real WWindow (found via wWindowFor rather
than created by makeMainWindow), wApplicationDestroy must not call
wWindowDestroy on it — the window is still managed and will be destroyed
by wUnmanageWindow. Add shared_main_desc flag to track ownership.
This commit is contained in:
lkn 2026-06-21 17:43:42 +02:00
parent 29550b58cb
commit 5325a51b64
2 changed files with 12 additions and 8 deletions

View File

@ -117,7 +117,9 @@ WApplication *wApplicationCreate(WWindow * wwin)
/* If the main_window is also the client window (Wayland native apps),
* reuse the existing WWindow which already has a frame. */
wapp->main_window_desc = wWindowFor(main_window);
if (!wapp->main_window_desc) {
if (wapp->main_window_desc) {
wapp->flags.shared_main_desc = 1;
} else {
wapp->main_window_desc = makeMainWindow(scr, main_window);
if (!wapp->main_window_desc) {
wfree(wapp);
@ -194,13 +196,14 @@ void wApplicationDestroy(WApplication *wapp)
/* Remove application icon */
removeAppIconFor(wapp);
wwin = wWindowFor(wapp->main_window_desc->client_win);
wWindowDestroy(wapp->main_window_desc);
if (wwin) {
/* undelete client window context that was deleted in
* wWindowDestroy */
wm_backend->context_save(wwin->client_win, WM_CTX_CLIENT_WIN, &wwin->client_descriptor);
if (!wapp->flags.shared_main_desc) {
wwin = wWindowFor(wapp->main_window_desc->client_win);
wWindowDestroy(wapp->main_window_desc);
if (wwin) {
/* undelete client window context that was deleted in
* wWindowDestroy */
wm_backend->context_save(wwin->client_win, WM_CTX_CLIENT_WIN, &wwin->client_descriptor);
}
}
wfree(wapp);
}

View File

@ -41,6 +41,7 @@ typedef struct WApplication {
unsigned int hidden:1;
unsigned int emulated:1;
unsigned int bouncing:1;
unsigned int shared_main_desc:1;
} flags;
} WApplication;