diff --git a/src/session.c b/src/session.c index ee26bbb..da05994 100644 --- a/src/session.c +++ b/src/session.c @@ -219,7 +219,7 @@ static WMPropList *makeWindowState(WWindow * wwin, WApplication * wapp) name = WMCreatePLString(buffer); cmd = WMCreatePLString(command); - workspace = WMCreatePLString(scr->workspaces[wwin->frame->workspace]->name); + workspace = WMCreatePLString(scr->workspaces[WIN_WORKSPACE(wwin)]->name); shaded = wwin->flags.shaded ? sYes : sNo; miniaturized = wwin->flags.miniaturized ? sYes : sNo; diff --git a/src/switchmenu.c b/src/switchmenu.c index 7fb7e8e..ad56304 100644 --- a/src/switchmenu.c +++ b/src/switchmenu.c @@ -160,7 +160,7 @@ static int menuIndexForWindow(WMenu * menu, WWindow * wwin, int old_pos) move_down = 1; if (IS_OMNIPRESENT(tw) || (tw != wwin && - tw->frame->workspace >= wwin->frame->workspace)) + WIN_WORKSPACE(tw) >= WIN_WORKSPACE(wwin))) return idx - move_down; } @@ -219,7 +219,7 @@ void UpdateSwitchMenu(WScreen * scr, WWindow * wwin, int action) snprintf(entry->rtext, MAX_WORKSPACENAME_WIDTH, "[*]"); else snprintf(entry->rtext, MAX_WORKSPACENAME_WIDTH, "[%s]", - scr->workspaces[wwin->frame->workspace]->name); + scr->workspaces[WIN_WORKSPACE(wwin)]->name); if (wwin->flags.hidden) { entry->flags.indicator_type = MI_HIDDEN; @@ -277,7 +277,7 @@ void UpdateSwitchMenu(WScreen * scr, WWindow * wwin, int action) } else { snprintf(entry->rtext, MAX_WORKSPACENAME_WIDTH, "[%s]", - scr->workspaces[wwin->frame->workspace]->name); + scr->workspaces[WIN_WORKSPACE(wwin)]->name); } rt = entry->rtext; @@ -350,12 +350,12 @@ static void UpdateSwitchMenuWorkspace(WScreen *scr, int workspace) for (i = 0; i < menu->entry_no; i++) { wwin = (WWindow *) menu->entries[i]->clientdata; - if (wwin->frame->workspace == workspace && !IS_OMNIPRESENT(wwin)) { + if (WIN_WORKSPACE(wwin) == workspace && !IS_OMNIPRESENT(wwin)) { if (IS_OMNIPRESENT(wwin)) snprintf(menu->entries[i]->rtext, MAX_WORKSPACENAME_WIDTH, "[*]"); else snprintf(menu->entries[i]->rtext, MAX_WORKSPACENAME_WIDTH, "[%s]", - scr->workspaces[wwin->frame->workspace]->name); + scr->workspaces[WIN_WORKSPACE(wwin)]->name); menu->flags.realized = 0; } } diff --git a/src/window.c b/src/window.c index 1ca8490..be7bce6 100644 --- a/src/window.c +++ b/src/window.c @@ -445,13 +445,14 @@ Bool wWindowObscuresWindow(WWindow *wwin, WWindow *obscured) { int w1, h1, w2, h2; - w1 = wwin->frame->core->width; - h1 = wwin->frame->core->height; - w2 = obscured->frame->core->width; - h2 = obscured->frame->core->height; + /* Phase 69: Wayland windows have no frame; use client geometry. */ + w1 = wwin->frame ? (int)wwin->frame->core->width : (int)wwin->client.width; + h1 = wwin->frame ? (int)wwin->frame->core->height : (int)wwin->client.height; + w2 = obscured->frame ? (int)obscured->frame->core->width : (int)obscured->client.width; + h2 = obscured->frame ? (int)obscured->frame->core->height : (int)obscured->client.height; if (!IS_OMNIPRESENT(wwin) && !IS_OMNIPRESENT(obscured) - && wwin->frame->workspace != obscured->frame->workspace) + && WIN_WORKSPACE(wwin) != WIN_WORKSPACE(obscured)) return False; if (wwin->frame_x + w1 < obscured->frame_x @@ -1704,7 +1705,7 @@ void wWindowFocusPrev(WWindow *wwin, Bool inSameWorkspace) tmp = tmp->prev; if (inSameWorkspace) - while (tmp && (tmp->frame->workspace != wwin->frame->workspace)) + while (tmp && (WIN_WORKSPACE(tmp) != WIN_WORKSPACE(wwin))) tmp = tmp->next; wWindowSingleFocus(tmp); @@ -1719,7 +1720,7 @@ void wWindowFocusNext(WWindow *wwin, Bool inSameWorkspace) tmp = wwin->prev; if (inSameWorkspace) - while (tmp && (tmp->frame->workspace != wwin->frame->workspace)) + while (tmp && (WIN_WORKSPACE(tmp) != WIN_WORKSPACE(wwin))) tmp = tmp->prev; wWindowSingleFocus(tmp); @@ -2239,7 +2240,7 @@ void wWindowSaveState(WWindow *wwin) int i; memset(data, 0, sizeof(long) * 10); - data[0] = wwin->frame->workspace; + data[0] = WIN_WORKSPACE(wwin); data[1] = wwin->flags.miniaturized; data[2] = wwin->flags.shaded; data[3] = wwin->flags.hidden; diff --git a/src/window.h b/src/window.h index 42c74c0..453f85e 100644 --- a/src/window.h +++ b/src/window.h @@ -307,6 +307,10 @@ typedef struct WWindow { #define IS_RESIZABLE(w) (!(WFLAGP((w), no_resizable) || (w)->flags.fullscreen)) #define IS_OMNIPRESENT(w) ((w)->flags.omnipresent | WFLAGP(w, omnipresent)) #define WINDOW_LEVEL(w) ((w)->frame->core->stacking->window_level) +/* Phase 69: safe workspace read for windows that may have no frame (Wayland). + * frame->workspace is the authoritative slot for X11 windows; wwin->workspace + * is the fallback set in wManageWindow for Wayland windows. */ +#define WIN_WORKSPACE(w) ((w)->frame ? (w)->frame->workspace : (w)->workspace) /* * Changes to this must update wWindowSaveState/getSavedState diff --git a/tests/wl-smoke-test.sh b/tests/wl-smoke-test.sh index d430a81..9eccb8a 100755 --- a/tests/wl-smoke-test.sh +++ b/tests/wl-smoke-test.sh @@ -61,6 +61,9 @@ # 26. (Phase 68) placement.c guards: calcSumOfCoveredAreas/window_overlaps # skip frameless (Wayland) windows safely; frame->workspace accesses # in icon-placement helpers use wwin->workspace fallback. +# 27. (Phase 69) WIN_WORKSPACE(w) macro added; frame->workspace reads in +# wWindowFocusPrev/Next, wWindowObscuresWindow, wWindowSaveState, +# session.c, and switchmenu.c replaced with the macro. # # This test grows as wl_backend vtable slots are implemented. #