From f86d294223f161f9ec54be274ec99712d6584efe Mon Sep 17 00:00:00 2001 From: Levi Neely Date: Sat, 28 Mar 2026 22:00:42 +0100 Subject: [PATCH] =?UTF-8?q?wayland:=20Phase=2019=20=E2=80=94=20guard=20fra?= =?UTF-8?q?mewin.c=20X11=20rendering=20against=20dpy=3D=3DNULL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the Wayland backend is active dpy is NULL; all X11 drawing calls in framewin.c (XMapRaised, XSetWindowBackground, XSetWindowBorder, XSetWindowBorderWidth, XSetWindowBackgroundPixmap, XClearWindow, XDrawLine) must be skipped to prevent SIGSEGV when managing XWayland or synthetic frame windows. Changes: - allocFrameBorderPixel: early return when !dpy (no X11 colormap) - wFrameWindowUpdateBorders: guard XSetWindowBorderWidth and XSetWindowBorder blocks; guard XMapRaised/XSetWindowBackground in button-creation branches; guard XMapWindow/XLowerWindow for resizebar - wFrameWindowChangeState: guard XSetWindowBorder block - wFrameWindowHideButton: guard XUnmapWindow calls - wFrameWindowShowButton: guard XMapWindow and XClearWindow calls - updateTexture: early return when !dpy - remakeTexture: guard resizebar XSetWindowBackgroundPixmap/XClearWindow - wFrameWindowPaint: guard entire resizebar XDrawLine section Frame window structure (wCoreCreate, descriptor setup, stacking) still runs normally; only the visual rendering is skipped in Wayland mode. Co-Authored-By: Claude Sonnet 4.6 --- src/framewin.c | 132 ++++++++++++++++++++++++++++--------------------- 1 file changed, 77 insertions(+), 55 deletions(-) diff --git a/src/framewin.c b/src/framewin.c index 7dc2377..8d9004c 100644 --- a/src/framewin.c +++ b/src/framewin.c @@ -62,6 +62,10 @@ static void allocFrameBorderPixel(Colormap colormap, const char *color_name, uns *pixel = NULL; + /* Phase 19: Wayland — no X11 colormap to query */ + if (!dpy) + return; + if (! wGetColorForColormap(colormap, color_name, &xcol)) return; @@ -237,19 +241,20 @@ void wFrameWindowUpdateBorders(WFrameWindow * fwin, int flags) if (width < theight * 4) fwin->flags.lbutton_dont_fit = 1; - else + else if (dpy) XMapRaised(dpy, fwin->left_button->window); } else if (wPreferences.new_style == TS_OLD) { fwin->left_button = wCoreCreate(fwin->titlebar, 3, (theight - bsize) / 2, bsize, bsize); - XSetWindowBackground(dpy, fwin->left_button->window, - scr->widget_texture->normal.pixel); + if (dpy) + XSetWindowBackground(dpy, fwin->left_button->window, + scr->widget_texture->normal.pixel); if (width < theight * 3) fwin->flags.lbutton_dont_fit = 1; - else + else if (dpy) XMapRaised(dpy, fwin->left_button->window); } else { @@ -257,12 +262,13 @@ void wFrameWindowUpdateBorders(WFrameWindow * fwin, int flags) wCoreCreate(fwin->titlebar, 3, (theight-bsize)/2, bsize, bsize); - XSetWindowBackground(dpy, fwin->left_button->window, - scr->widget_texture->dark.pixel); + if (dpy) + XSetWindowBackground(dpy, fwin->left_button->window, + scr->widget_texture->dark.pixel); if (width < theight * 3) fwin->flags.lbutton_dont_fit = 1; - else + else if (dpy) XMapRaised(dpy, fwin->left_button->window); } @@ -275,19 +281,20 @@ void wFrameWindowUpdateBorders(WFrameWindow * fwin, int flags) if (width < theight * 4) fwin->flags.languagebutton_dont_fit = 1; - else + else if (dpy) XMapRaised(dpy, fwin->language_button->window); } else { fwin->language_button = wCoreCreate(fwin->titlebar, bsize + 6, (theight - bsize) / 2, bsize, bsize); - XSetWindowBackground(dpy, fwin->language_button->window, - scr->widget_texture->normal.pixel); + if (dpy) + XSetWindowBackground(dpy, fwin->language_button->window, + scr->widget_texture->normal.pixel); if (width < theight * 3) fwin->flags.languagebutton_dont_fit = 1; - else + else if (dpy) XMapRaised(dpy, fwin->language_button->window); } } @@ -302,26 +309,29 @@ void wFrameWindowUpdateBorders(WFrameWindow * fwin, int flags) fwin->right_button = wCoreCreate(fwin->titlebar, width - bsize - 3, (theight - bsize) / 2, bsize, bsize); - XSetWindowBackground(dpy, fwin->right_button->window, - scr->widget_texture->normal.pixel); + if (dpy) + XSetWindowBackground(dpy, fwin->right_button->window, + scr->widget_texture->normal.pixel); } else { fwin->right_button = wCoreCreate(fwin->titlebar, width-bsize-3, (theight-bsize)/2, bsize, bsize); - XSetWindowBackground(dpy, fwin->right_button->window, - scr->widget_texture->dark.pixel); + if (dpy) + XSetWindowBackground(dpy, fwin->right_button->window, + scr->widget_texture->dark.pixel); } if (width < theight * 2) fwin->flags.rbutton_dont_fit = 1; - else + else if (dpy) XMapRaised(dpy, fwin->right_button->window); } if (wPreferences.new_style == TS_NEW) updateTitlebar(fwin); - XMapRaised(dpy, fwin->titlebar->window); + if (dpy) + XMapRaised(dpy, fwin->titlebar->window); fwin->flags.need_texture_remake = 1; } @@ -342,8 +352,10 @@ void wFrameWindowUpdateBorders(WFrameWindow * fwin, int flags) fwin->resizebar_corner_width = 0; } - XMapWindow(dpy, fwin->resizebar->window); - XLowerWindow(dpy, fwin->resizebar->window); + if (dpy) { + XMapWindow(dpy, fwin->resizebar->window); + XLowerWindow(dpy, fwin->resizebar->window); + } fwin->flags.need_texture_remake = 1; } else { @@ -364,10 +376,12 @@ void wFrameWindowUpdateBorders(WFrameWindow * fwin, int flags) if (height + fwin->top_width + fwin->bottom_width != fwin->core->height && !(flags & WFF_IS_SHADED)) wFrameWindowResize(fwin, width, height + fwin->top_width + fwin->bottom_width); - if (flags & WFF_BORDER) - XSetWindowBorderWidth(dpy, fwin->core->window, scr->frame_border_width); - else - XSetWindowBorderWidth(dpy, fwin->core->window, 0); + if (dpy) { + if (flags & WFF_BORDER) + XSetWindowBorderWidth(dpy, fwin->core->window, scr->frame_border_width); + else + XSetWindowBorderWidth(dpy, fwin->core->window, 0); + } /* setup object descriptors */ if (fwin->titlebar) { @@ -413,17 +427,18 @@ void wFrameWindowUpdateBorders(WFrameWindow * fwin, int flags) allocFrameBorderPixel(fwin->colormap, WMGetColorRGBDescription(scr->frame_focused_border_color), &fwin->focused_border_pixel); allocFrameBorderPixel(fwin->colormap, WMGetColorRGBDescription(scr->frame_selected_border_color), &fwin->selected_border_pixel); - if (flags & WFF_SELECTED) { - if (fwin->selected_border_pixel) - XSetWindowBorder(dpy, fwin->core->window, *fwin->selected_border_pixel); - } - else { - if (fwin->flags.state == WS_FOCUSED) { - if (fwin->focused_border_pixel) - XSetWindowBorder(dpy, fwin->core->window, *fwin->focused_border_pixel); + if (dpy) { + if (flags & WFF_SELECTED) { + if (fwin->selected_border_pixel) + XSetWindowBorder(dpy, fwin->core->window, *fwin->selected_border_pixel); } else { - if (fwin->border_pixel) - XSetWindowBorder(dpy, fwin->core->window, *fwin->border_pixel); + if (fwin->flags.state == WS_FOCUSED) { + if (fwin->focused_border_pixel) + XSetWindowBorder(dpy, fwin->core->window, *fwin->focused_border_pixel); + } else { + if (fwin->border_pixel) + XSetWindowBorder(dpy, fwin->core->window, *fwin->border_pixel); + } } } } @@ -478,12 +493,14 @@ void wFrameWindowChangeState(WFrameWindow * fwin, int state) fwin->flags.state = state; fwin->flags.need_texture_change = 1; - if (fwin->flags.state == WS_FOCUSED) { - if (fwin->focused_border_pixel) - XSetWindowBorder(dpy, fwin->core->window, *fwin->focused_border_pixel); - } else { - if (fwin->border_pixel) - XSetWindowBorder(dpy, fwin->core->window, *fwin->border_pixel); + if (dpy) { + if (fwin->flags.state == WS_FOCUSED) { + if (fwin->focused_border_pixel) + XSetWindowBorder(dpy, fwin->core->window, *fwin->focused_border_pixel); + } else { + if (fwin->border_pixel) + XSetWindowBorder(dpy, fwin->core->window, *fwin->border_pixel); + } } wFrameWindowPaint(fwin); } @@ -560,17 +577,17 @@ static void updateTitlebar(WFrameWindow * fwin) void wFrameWindowHideButton(WFrameWindow * fwin, int flags) { if ((flags & WFF_RIGHT_BUTTON) && fwin->right_button) { - XUnmapWindow(dpy, fwin->right_button->window); + if (dpy) XUnmapWindow(dpy, fwin->right_button->window); fwin->flags.hide_right_button = 1; } if ((flags & WFF_LEFT_BUTTON) && fwin->left_button) { - XUnmapWindow(dpy, fwin->left_button->window); + if (dpy) XUnmapWindow(dpy, fwin->left_button->window); fwin->flags.hide_left_button = 1; } #ifdef XKB_BUTTON_HINT if ((flags & WFF_LANGUAGE_BUTTON) && fwin->language_button) { - XUnmapWindow(dpy, fwin->language_button->window); + if (dpy) XUnmapWindow(dpy, fwin->language_button->window); fwin->flags.hide_language_button = 1; } #endif @@ -582,7 +599,7 @@ void wFrameWindowHideButton(WFrameWindow * fwin, int flags) #ifdef XKB_BUTTON_HINT updateTitlebar(fwin); #else - XClearWindow(dpy, fwin->titlebar->window); + if (dpy) XClearWindow(dpy, fwin->titlebar->window); wFrameWindowPaint(fwin); #endif } @@ -594,7 +611,7 @@ void wFrameWindowShowButton(WFrameWindow * fwin, int flags) { if ((flags & WFF_RIGHT_BUTTON) && fwin->right_button && fwin->flags.hide_right_button) { - if (!fwin->flags.rbutton_dont_fit) + if (!fwin->flags.rbutton_dont_fit && dpy) XMapWindow(dpy, fwin->right_button->window); fwin->flags.hide_right_button = 0; @@ -602,7 +619,7 @@ void wFrameWindowShowButton(WFrameWindow * fwin, int flags) #ifdef XKB_BUTTON_HINT if ((flags & WFF_LANGUAGE_BUTTON) && fwin->language_button && fwin->flags.hide_language_button) { - if (!fwin->flags.languagebutton_dont_fit) + if (!fwin->flags.languagebutton_dont_fit && dpy) XMapWindow(dpy, fwin->language_button->window); fwin->flags.hide_language_button = 0; @@ -611,7 +628,7 @@ void wFrameWindowShowButton(WFrameWindow * fwin, int flags) if ((flags & WFF_LEFT_BUTTON) && fwin->left_button && fwin->flags.hide_left_button) { - if (!fwin->flags.lbutton_dont_fit) + if (!fwin->flags.lbutton_dont_fit && dpy) XMapWindow(dpy, fwin->left_button->window); fwin->flags.hide_left_button = 0; @@ -621,7 +638,7 @@ void wFrameWindowShowButton(WFrameWindow * fwin, int flags) if (wPreferences.new_style == TS_NEW) { updateTitlebar(fwin); } else { - XClearWindow(dpy, fwin->titlebar->window); + if (dpy) XClearWindow(dpy, fwin->titlebar->window); wFrameWindowPaint(fwin); } checkTitleSize(fwin); @@ -782,6 +799,10 @@ static void updateTexture(WFrameWindow * fwin) int i; unsigned long pixel; + /* Phase 19: Wayland — no X11 connection to update window backgrounds */ + if (!dpy) + return; + i = fwin->flags.state; if (fwin->titlebar) { if (fwin->title_texture[i]->any.type != WTEX_SOLID) { @@ -907,13 +928,14 @@ static void remakeTexture(WFrameWindow * fwin, int state) } /* this part should be in updateTexture() */ - if (fwin->resizebar_texture[0]->any.type != WTEX_SOLID) - XSetWindowBackgroundPixmap(dpy, fwin->resizebar->window, fwin->resizebar_back[0]); - else - XSetWindowBackground(dpy, fwin->resizebar->window, - fwin->resizebar_texture[0]->solid.normal.pixel); - - XClearWindow(dpy, fwin->resizebar->window); + if (dpy) { + if (fwin->resizebar_texture[0]->any.type != WTEX_SOLID) + XSetWindowBackgroundPixmap(dpy, fwin->resizebar->window, fwin->resizebar_back[0]); + else + XSetWindowBackground(dpy, fwin->resizebar->window, + fwin->resizebar_texture[0]->solid.normal.pixel); + XClearWindow(dpy, fwin->resizebar->window); + } } } @@ -961,7 +983,7 @@ void wFrameWindowPaint(WFrameWindow * fwin) fwin->titlebar->height, (WTexSolid *) fwin->title_texture[state], WREL_RAISED); } - if (fwin->resizebar && !fwin->flags.repaint_only_titlebar + if (dpy && fwin->resizebar && !fwin->flags.repaint_only_titlebar && fwin->resizebar_texture[0]->any.type == WTEX_SOLID) { Window win; int w, h;