diff --git a/src/event.c b/src/event.c index 3d06791..4d748f5 100644 --- a/src/event.c +++ b/src/event.c @@ -1366,6 +1366,7 @@ static void handleKeyPress(XEvent * event) case WKBD_WINDOWMENU: if (ISMAPPED(wwin) && ISFOCUSED(wwin)) + if (wwin->frame) OpenWindowMenu(wwin, wwin->frame_x, wwin->frame_y + wwin->frame->top_width, True); break; case WKBD_MINIMIZEALL: @@ -1503,7 +1504,7 @@ static void handleKeyPress(XEvent * event) } break; case WKBD_KEEP_ON_TOP: - if (ISMAPPED(wwin) && ISFOCUSED(wwin)) { + if (ISMAPPED(wwin) && ISFOCUSED(wwin) && wwin->frame) { CloseWindowMenu(scr); if (wwin->frame->core->stacking->window_level != WMFloatingLevel) @@ -1514,7 +1515,7 @@ static void handleKeyPress(XEvent * event) break; case WKBD_KEEP_AT_BOTTOM: - if (ISMAPPED(wwin) && ISFOCUSED(wwin)) { + if (ISMAPPED(wwin) && ISFOCUSED(wwin) && wwin->frame) { CloseWindowMenu(scr); if (wwin->frame->core->stacking->window_level != WMSunkenLevel) @@ -1531,14 +1532,14 @@ static void handleKeyPress(XEvent * event) } break; case WKBD_RAISE: - if (ISMAPPED(wwin) && ISFOCUSED(wwin)) { + if (ISMAPPED(wwin) && ISFOCUSED(wwin) && wwin->frame) { CloseWindowMenu(scr); wRaiseFrame(wwin->frame->core); } break; case WKBD_LOWER: - if (ISMAPPED(wwin) && ISFOCUSED(wwin)) { + if (ISMAPPED(wwin) && ISFOCUSED(wwin) && wwin->frame) { CloseWindowMenu(scr); wLowerFrame(wwin->frame->core); @@ -1549,7 +1550,7 @@ static void handleKeyPress(XEvent * event) * focused one */ wwin = windowUnderPointer(scr); - if (wwin) + if (wwin && wwin->frame) wRaiseLowerFrame(wwin->frame->core); break; case WKBD_SHADE: @@ -1828,7 +1829,7 @@ static void handleKeyPress(XEvent * event) /*toggle */ wwin = scr->focused_window; - if (wwin && wwin->flags.mapped + if (wwin && wwin->flags.mapped && wwin->frame && WIN_WORKSPACE(wwin) == wwin->screen_ptr->current_workspace && !wwin->flags.miniaturized && !wwin->flags.hidden) { int cur_group = wm_backend->xkb_get_group(); diff --git a/src/moveres.c b/src/moveres.c index 0d1f6e7..ecc421a 100644 --- a/src/moveres.c +++ b/src/moveres.c @@ -1338,6 +1338,10 @@ int wKeyboardMoveResizeWindow(WWindow * wwin) WScreen *scr = wwin->screen_ptr; WNativeWindow root = scr->root_win; XEvent event; + + if (!wwin->frame) + return 0; /* Phase 72: Wayland — no frame for keyboard move/resize */ + int w = wwin->frame->core->width; int h = wwin->frame->core->height; int scr_width = wwin->screen_ptr->scr_width; @@ -1705,6 +1709,8 @@ int wMouseMoveWindow(WWindow * wwin, XEvent * ev) if (!IS_MOVABLE(wwin)) return False; + if (!wwin->frame) + return False; /* Phase 72: Wayland — no frame for mouse move */ if (wPreferences.opaque_move && !wPreferences.use_saveunders) { wm_backend->window_set_save_under(wwin->frame->core->window, 1); @@ -2026,6 +2032,10 @@ void wMouseResizeWindow(WWindow * wwin, XEvent * ev) XEvent event; WScreen *scr = wwin->screen_ptr; WNativeWindow root = scr->root_win; + + if (!wwin->frame) + return; /* Phase 72: Wayland — no frame for mouse resize */ + int vert_border = wwin->frame->top_width + wwin->frame->bottom_width; int fw = wwin->frame->core->width; int fh = wwin->frame->core->height; diff --git a/tests/wl-smoke-test.sh b/tests/wl-smoke-test.sh index 2bb9212..135a32e 100755 --- a/tests/wl-smoke-test.sh +++ b/tests/wl-smoke-test.sh @@ -71,6 +71,12 @@ # wMaximizeWindow, wUnmaximizeWindow, wFullscreenWindow, wIconifyWindow, # wDeiconifyWindow so that Wayland windows (frame==NULL) do not crash # when these actions are triggered (build-only check). +# 30. (Phase 72) Early-return guards added to keyboard shortcut handlers +# in event.c (WKBD_KEEP_ON_TOP, WKBD_KEEP_AT_BOTTOM, WKBD_RAISE, +# WKBD_LOWER, WKBD_RAISELOWER, WKBD_WINDOWMENU, WKBD_XKB_TOGGLE) and +# to wKeyboardMoveResizeWindow, wMouseMoveWindow, wMouseResizeWindow in +# moveres.c so Wayland windows do not crash on frame->core access +# (build-only check). # # This test grows as wl_backend vtable slots are implemented. #