From 264679a2d13a907160e80bc0efa1e28cf3352f5b Mon Sep 17 00:00:00 2001 From: Window Maker Date: Sat, 23 May 2026 15:19:52 +0200 Subject: [PATCH] WINGs: port wwindow.c to vtable dispatch (Phase D) Removes all direct Xlib calls from wwindow.c (25 calls eliminated). ICCM/EWMH property setting dispatched through W_ViewBackend slots: - window_set_title, window_set_icon_title, window_set_icon_image - window_realize (WM_CLASS, WM_HINTS, WM_PROTOCOLS, transient-for) - window_set_geometry (WM_NORMAL_HINTS) - window_withdraw (XWithdrawWindow) X11 backend implements full property setting. Wayland backend is no-op (compositor-internal windows). Struct moved to wwindow_p.h for backend access. --- WINGs/wview_wl.c | 43 ++++- WINGs/wview_x11.c | 12 +- WINGs/wwindow.c | 473 +++++++++++----------------------------------- WINGs/wwindow_p.h | 49 +++++ 4 files changed, 201 insertions(+), 376 deletions(-) create mode 100644 WINGs/wwindow_p.h diff --git a/WINGs/wview_wl.c b/WINGs/wview_wl.c index 486bba8..7ebdfac 100644 --- a/WINGs/wview_wl.c +++ b/WINGs/wview_wl.c @@ -547,6 +547,37 @@ static void wl_flush(void *vctx) (void)vctx; } +static void wl_window_set_title(void *vctx, W_View *view, const char *title) +{ + (void)vctx; (void)view; (void)title; +} + +static void wl_window_set_icon_title(void *vctx, W_View *view, const char *title) +{ + (void)vctx; (void)view; (void)title; +} + +static void wl_window_set_icon_image(void *vctx, W_View *view, RImage *image) +{ + (void)vctx; (void)view; (void)image; +} + +static void wl_window_realize(void *vctx, W_View *view, const char *name, + const char *class, W_View *owner) +{ + (void)vctx; (void)view; (void)name; (void)class; (void)owner; +} + +static void wl_window_set_geometry(void *vctx, W_View *view) +{ + (void)vctx; (void)view; +} + +static void wl_window_withdraw(void *vctx, W_View *view) +{ + (void)vctx; (void)view; +} + const W_ViewBackend W_ViewBackendWL = { .screen_init = wl_screen_init, .screen_fini = wl_screen_fini, @@ -573,12 +604,12 @@ const W_ViewBackend W_ViewBackendWL = { .clipboard_store = wl_clipboard_store, .clipboard_fetch = wl_clipboard_fetch, .drag_begin = wl_drag_begin, - .window_set_title = NULL, - .window_set_icon_title = NULL, - .window_set_icon_image = NULL, - .window_realize = NULL, - .window_set_geometry = NULL, - .window_withdraw = NULL, + .window_set_title = wl_window_set_title, + .window_set_icon_title = wl_window_set_icon_title, + .window_set_icon_image = wl_window_set_icon_image, + .window_realize = wl_window_realize, + .window_set_geometry = wl_window_set_geometry, + .window_withdraw = wl_window_withdraw, .pointer_grab = NULL, .pointer_ungrab = NULL, .bell = NULL, diff --git a/WINGs/wview_x11.c b/WINGs/wview_x11.c index c20da04..f9d8c59 100644 --- a/WINGs/wview_x11.c +++ b/WINGs/wview_x11.c @@ -498,12 +498,12 @@ const W_ViewBackend W_ViewBackendX11 = { .clipboard_store = x11_clipboard_store, .clipboard_fetch = x11_clipboard_fetch, .drag_begin = NULL, - .window_set_title = NULL, - .window_set_icon_title = NULL, - .window_set_icon_image = NULL, - .window_realize = NULL, - .window_set_geometry = NULL, - .window_withdraw = NULL, + .window_set_title = x11_window_set_title, + .window_set_icon_title = x11_window_set_icon_title, + .window_set_icon_image = x11_window_set_icon_image, + .window_realize = x11_window_realize, + .window_set_geometry = x11_window_set_geometry, + .window_withdraw = x11_window_withdraw, .pointer_grab = NULL, .pointer_ungrab = NULL, .bell = NULL, diff --git a/WINGs/wwindow.c b/WINGs/wwindow.c index 90a6bb7..7f00b2e 100644 --- a/WINGs/wwindow.c +++ b/WINGs/wwindow.c @@ -1,54 +1,9 @@ -#include - #include "wconfig.h" -#include "WINGsP.h" +#include "wwindow_p.h" -#include "GNUstep.h" - -#include - -typedef struct W_Window { - W_Class widgetClass; - W_View *view; - - struct W_Window *nextPtr; /* next in the window list */ - - struct W_Window *owner; - - char *title; - - WMPixmap *miniImage; /* miniwindow */ - char *miniTitle; - - char *wname; - - WMSize resizeIncrement; - WMSize baseSize; - WMSize minSize; - WMSize maxSize; - WMPoint minAspect; - WMPoint maxAspect; - - WMPoint upos; - WMPoint ppos; - - WMAction *closeAction; - void *closeData; - - int level; - - struct { - unsigned style:4; - unsigned configured:1; - unsigned documentEdited:1; - - unsigned setUPos:1; - unsigned setPPos:1; - unsigned setAspect:1; - } flags; -} _Window; +#include "../src/GNUstep.h" static void willResizeWindow(W_ViewDelegate *, WMView *, unsigned *, unsigned *); @@ -99,7 +54,12 @@ void WMChangePanelOwner(WMWindow * win, WMWindow * newOwner) win->owner = newOwner; if (win->view->flags.realized && newOwner) { - XSetTransientForHint(win->view->screen->display, win->view->window, newOwner->view->window); + W_Screen *scr = win->view->screen; + const W_ViewBackend *vb = scr->viewBackend; + if (vb->window_realize) + vb->window_realize(scr->viewBackendCtx, win->view, + win->wname, WMGetApplicationName(), + newOwner->view); } } @@ -149,91 +109,6 @@ WMWindow *WMCreateWindowWithStyle(WMScreen * screen, const char *name, int style return win; } -static void setWindowTitle(WMWindow * win, const char *title) -{ - WMScreen *scr = win->view->screen; - XTextProperty property; - int result; - - result = XmbTextListToTextProperty(scr->display, (char **)&title, 1, XStdICCTextStyle, &property); - if (result == XNoMemory || result == XLocaleNotSupported) { - wwarning(_("window title conversion error... using STRING encoding")); - XStoreName(scr->display, win->view->window, title); - } else { - XSetWMName(scr->display, win->view->window, &property); - if (property.value) - XFree(property.value); - } - - XChangeProperty(scr->display, win->view->window, - scr->netwmName, scr->utf8String, 8, - PropModeReplace, (unsigned char *)title, strlen(title)); -} - -static void setMiniwindowTitle(WMWindow * win, const char *title) -{ - WMScreen *scr = win->view->screen; - XTextProperty property; - int result; - - result = XmbTextListToTextProperty(scr->display, (char **)&title, 1, XStdICCTextStyle, &property); - if (result == XNoMemory || result == XLocaleNotSupported) { - wwarning(_("icon title conversion error... using STRING encoding")); - XSetIconName(scr->display, win->view->window, title); - } else { - XSetWMIconName(scr->display, win->view->window, &property); - if (property.value) - XFree(property.value); - } - - XChangeProperty(scr->display, win->view->window, - scr->netwmIconName, scr->utf8String, 8, - PropModeReplace, (unsigned char *)title, strlen(title)); -} - -static void setMiniwindow(WMWindow *win, RImage *image) -{ - WMScreen *scr = win->view->screen; - unsigned long *data; - int x, y; - int o; - - if (!image) - return; - - data = wmalloc((image->width * image->height + 2) * sizeof(long)); - - o = 0; - data[o++] = image->width; - data[o++] = image->height; - - for (y = 0; y < image->height; y++) { - for (x = 0; x < image->width; x++) { - unsigned long pixel; - int offs = (x + y * image->width); - - if (image->format == RRGBFormat) { - pixel = ((unsigned long) image->data[offs * 3 ]) << 16; - pixel |= ((unsigned long) image->data[offs * 3 + 1]) << 8; - pixel |= ((unsigned long) image->data[offs * 3 + 2]); - } else { - pixel = ((unsigned long) image->data[offs * 4 ]) << 16; - pixel |= ((unsigned long) image->data[offs * 4 + 1]) << 8; - pixel |= ((unsigned long) image->data[offs * 4 + 2]); - pixel |= ((unsigned long) image->data[offs * 4 + 3]) << 24; - } - - data[o++] = pixel; - } - } - - XChangeProperty(scr->display, win->view->window, scr->netwmIcon, - XA_CARDINAL, 32, PropModeReplace, - (unsigned char *)data, (image->width * image->height + 2)); - - wfree(data); -} - void WMSetWindowTitle(WMWindow * win, const char *title) { wassertr(title != NULL); @@ -244,51 +119,26 @@ void WMSetWindowTitle(WMWindow * win, const char *title) win->title = wstrdup(title); if (win->view->flags.realized) { - setWindowTitle(win, title); + W_Screen *scr = win->view->screen; + const W_ViewBackend *vb = scr->viewBackend; + if (vb->window_set_title) + vb->window_set_title(scr->viewBackendCtx, win->view, title); } } void WMSetWindowCloseAction(WMWindow * win, WMAction * action, void *clientData) { - Atom *atoms = NULL; - Atom *newAtoms; - int count; - WMScreen *scr = win->view->screen; - - if (win->view->flags.realized) { - if (action && !win->closeAction) { - if (!XGetWMProtocols(scr->display, win->view->window, &atoms, &count)) { - count = 0; - } - newAtoms = wmalloc((count + 1) * sizeof(Atom)); - if (count > 0) - memcpy(newAtoms, atoms, count * sizeof(Atom)); - newAtoms[count++] = scr->deleteWindowAtom; - XSetWMProtocols(scr->display, win->view->window, newAtoms, count); - if (atoms) - XFree(atoms); - wfree(newAtoms); - } else if (!action && win->closeAction) { - int i, ncount; - - if (XGetWMProtocols(scr->display, win->view->window, &atoms, &count) && count > 0) { - newAtoms = wmalloc((count - 1) * sizeof(Atom)); - ncount = 0; - for (i = 0; i < count; i++) { - if (atoms[i] != scr->deleteWindowAtom) { - newAtoms[i] = atoms[i]; - ncount++; - } - } - XSetWMProtocols(scr->display, win->view->window, newAtoms, ncount); - if (atoms) - XFree(atoms); - wfree(newAtoms); - } - } - } win->closeAction = action; win->closeData = clientData; + + if (win->view->flags.realized) { + W_Screen *scr = win->view->screen; + const W_ViewBackend *vb = scr->viewBackend; + if (vb->window_realize) + vb->window_realize(scr->viewBackendCtx, win->view, + win->wname, WMGetApplicationName(), + win->owner ? win->owner->view : NULL); + } } static void willResizeWindow(W_ViewDelegate * self, WMView * view, unsigned *width, unsigned *height) @@ -313,159 +163,18 @@ static void willResizeWindow(W_ViewDelegate * self, WMView * view, unsigned *wid } } -static void setSizeHints(WMWindow * win) -{ - XSizeHints *hints; - - hints = XAllocSizeHints(); - if (!hints) { - wwarning("could not allocate memory for window size hints"); - return; - } - - hints->flags = 0; - - if (win->flags.setPPos) { - hints->flags |= PPosition; - hints->x = win->ppos.x; - hints->y = win->ppos.y; - } - if (win->flags.setUPos) { - hints->flags |= USPosition; - hints->x = win->upos.x; - hints->y = win->upos.y; - } - if (win->minSize.width > 0 && win->minSize.height > 0) { - hints->flags |= PMinSize; - hints->min_width = win->minSize.width; - hints->min_height = win->minSize.height; - } - if (win->maxSize.width > 0 && win->maxSize.height > 0) { - hints->flags |= PMaxSize; - hints->max_width = win->maxSize.width; - hints->max_height = win->maxSize.height; - } - if (win->baseSize.width > 0 && win->baseSize.height > 0) { - hints->flags |= PBaseSize; - hints->base_width = win->baseSize.width; - hints->base_height = win->baseSize.height; - } - if (win->resizeIncrement.width > 0 && win->resizeIncrement.height > 0) { - hints->flags |= PResizeInc; - hints->width_inc = win->resizeIncrement.width; - hints->height_inc = win->resizeIncrement.height; - } - if (win->flags.setAspect) { - hints->flags |= PAspect; - hints->min_aspect.x = win->minAspect.x; - hints->min_aspect.y = win->minAspect.y; - hints->max_aspect.x = win->maxAspect.x; - hints->max_aspect.y = win->maxAspect.y; - } - - if (hints->flags) { - XSetWMNormalHints(win->view->screen->display, win->view->window, hints); - } - XFree(hints); -} - -static void writeGNUstepWMAttr(WMScreen * scr, Window window, GNUstepWMAttributes * attr) -{ - unsigned long data[9]; - - /* handle idiot compilers where array of CARD32 != struct of CARD32 */ - data[0] = attr->flags; - data[1] = attr->window_style; - data[2] = attr->window_level; - data[3] = 0; /* reserved */ - /* The X protocol says XIDs are 32bit */ - data[4] = attr->miniaturize_pixmap; - data[5] = attr->close_pixmap; - data[6] = attr->miniaturize_mask; - data[7] = attr->close_mask; - data[8] = attr->extra_flags; - XChangeProperty(scr->display, window, scr->attribsAtom, scr->attribsAtom, - 32, PropModeReplace, (unsigned char *)data, 9); -} - -static void setWindowMakerHints(WMWindow * win) -{ - GNUstepWMAttributes attribs; - WMScreen *scr = WMWidgetScreen(win); - - memset(&attribs, 0, sizeof(GNUstepWMAttributes)); - attribs.flags = GSWindowStyleAttr | GSWindowLevelAttr | GSExtraFlagsAttr; - - if (win->minSize.width == win->maxSize.width && win->minSize.height == win->maxSize.height) - win->flags.style &= ~WMResizableWindowMask; - attribs.window_style = win->flags.style; - - attribs.window_level = win->level; - if (win->flags.documentEdited) - attribs.extra_flags = GSDocumentEditedFlag; - else - attribs.extra_flags = 0; - - writeGNUstepWMAttr(scr, win->view->window, &attribs); -} - static void realizeWindow(WMWindow * win) { - XWMHints *hints; - XClassHint *classHint; - WMScreen *scr = win->view->screen; - Atom atoms[4]; - int count; + W_Screen *scr = win->view->screen; + const W_ViewBackend *vb = scr->viewBackend; - if (!scr->display) - return; + if (vb->window_realize) + vb->window_realize(scr->viewBackendCtx, win->view, + win->wname, WMGetApplicationName(), + win->owner ? win->owner->view : NULL); - classHint = XAllocClassHint(); - classHint->res_name = win->wname; - classHint->res_class = WMGetApplicationName(); - XSetClassHint(scr->display, win->view->window, classHint); - XFree(classHint); - - hints = XAllocWMHints(); - hints->flags = 0; - if (!scr->aflags.simpleApplication) { - hints->flags |= WindowGroupHint; - hints->window_group = scr->groupLeader; - } - if (win->miniImage) { - hints->flags |= IconPixmapHint; - hints->icon_pixmap = WMGetPixmapXID(win->miniImage); - hints->icon_mask = WMGetPixmapMaskXID(win->miniImage); - if (hints->icon_mask != None) { - hints->flags |= IconMaskHint; - } - } - if (hints->flags != 0) - XSetWMHints(scr->display, win->view->window, hints); - XFree(hints); - - count = 0; - if (win->closeAction) { - atoms[count++] = scr->deleteWindowAtom; - } - - if (count > 0) - XSetWMProtocols(scr->display, win->view->window, atoms, count); - - if (win->title || win->miniTitle) - XmbSetWMProperties(scr->display, win->view->window, win->title, - win->miniTitle, NULL, 0, NULL, NULL, NULL); - - setWindowMakerHints(win); - - setSizeHints(win); - - if (win->owner) { - XSetTransientForHint(scr->display, win->view->window, win->owner->view->window); - } - - if (win->title) - setWindowTitle(win, win->title); + if (vb->window_set_geometry) + vb->window_set_geometry(scr->viewBackendCtx, win->view); } void WMSetWindowAspectRatio(WMWindow * win, int minX, int minY, int maxX, int maxY) @@ -475,8 +184,12 @@ void WMSetWindowAspectRatio(WMWindow * win, int minX, int minY, int maxX, int ma win->minAspect.y = minY; win->maxAspect.x = maxX; win->maxAspect.y = maxY; - if (win->view->flags.realized) - setSizeHints(win); + if (win->view->flags.realized) { + W_Screen *scr = win->view->screen; + const W_ViewBackend *vb = scr->viewBackend; + if (vb->window_set_geometry) + vb->window_set_geometry(scr->viewBackendCtx, win->view); + } } void WMSetWindowInitialPosition(WMWindow * win, int x, int y) @@ -484,8 +197,12 @@ void WMSetWindowInitialPosition(WMWindow * win, int x, int y) win->flags.setPPos = 1; win->ppos.x = x; win->ppos.y = y; - if (win->view->flags.realized) - setSizeHints(win); + if (win->view->flags.realized) { + W_Screen *scr = win->view->screen; + const W_ViewBackend *vb = scr->viewBackend; + if (vb->window_set_geometry) + vb->window_set_geometry(scr->viewBackendCtx, win->view); + } WMMoveWidget(win, x, y); } @@ -494,8 +211,12 @@ void WMSetWindowUserPosition(WMWindow * win, int x, int y) win->flags.setUPos = 1; win->upos.x = x; win->upos.y = y; - if (win->view->flags.realized) - setSizeHints(win); + if (win->view->flags.realized) { + W_Screen *scr = win->view->screen; + const W_ViewBackend *vb = scr->viewBackend; + if (vb->window_set_geometry) + vb->window_set_geometry(scr->viewBackendCtx, win->view); + } WMMoveWidget(win, x, y); } @@ -503,16 +224,24 @@ void WMSetWindowMinSize(WMWindow * win, unsigned width, unsigned height) { win->minSize.width = width; win->minSize.height = height; - if (win->view->flags.realized) - setSizeHints(win); + if (win->view->flags.realized) { + W_Screen *scr = win->view->screen; + const W_ViewBackend *vb = scr->viewBackend; + if (vb->window_set_geometry) + vb->window_set_geometry(scr->viewBackendCtx, win->view); + } } void WMSetWindowMaxSize(WMWindow * win, unsigned width, unsigned height) { win->maxSize.width = width; win->maxSize.height = height; - if (win->view->flags.realized) - setSizeHints(win); + if (win->view->flags.realized) { + W_Screen *scr = win->view->screen; + const W_ViewBackend *vb = scr->viewBackend; + if (vb->window_set_geometry) + vb->window_set_geometry(scr->viewBackendCtx, win->view); + } } void WMSetWindowBaseSize(WMWindow * win, unsigned width, unsigned height) @@ -520,23 +249,37 @@ void WMSetWindowBaseSize(WMWindow * win, unsigned width, unsigned height) /* TODO: validate sizes */ win->baseSize.width = width; win->baseSize.height = height; - if (win->view->flags.realized) - setSizeHints(win); + if (win->view->flags.realized) { + W_Screen *scr = win->view->screen; + const W_ViewBackend *vb = scr->viewBackend; + if (vb->window_set_geometry) + vb->window_set_geometry(scr->viewBackendCtx, win->view); + } } void WMSetWindowResizeIncrements(WMWindow * win, unsigned wIncr, unsigned hIncr) { win->resizeIncrement.width = wIncr; win->resizeIncrement.height = hIncr; - if (win->view->flags.realized) - setSizeHints(win); + if (win->view->flags.realized) { + W_Screen *scr = win->view->screen; + const W_ViewBackend *vb = scr->viewBackend; + if (vb->window_set_geometry) + vb->window_set_geometry(scr->viewBackendCtx, win->view); + } } void WMSetWindowLevel(WMWindow * win, int level) { win->level = level; - if (win->view->flags.realized) - setWindowMakerHints(win); + if (win->view->flags.realized) { + W_Screen *scr = win->view->screen; + const W_ViewBackend *vb = scr->viewBackend; + if (vb->window_realize) + vb->window_realize(scr->viewBackendCtx, win->view, + win->wname, WMGetApplicationName(), + win->owner ? win->owner->view : NULL); + } } void WMSetWindowDocumentEdited(WMWindow * win, Bool flag) @@ -544,15 +287,25 @@ void WMSetWindowDocumentEdited(WMWindow * win, Bool flag) flag = ((flag == 0) ? 0 : 1); if (win->flags.documentEdited != flag) { win->flags.documentEdited = flag; - if (win->view->flags.realized) - setWindowMakerHints(win); + if (win->view->flags.realized) { + W_Screen *scr = win->view->screen; + const W_ViewBackend *vb = scr->viewBackend; + if (vb->window_realize) + vb->window_realize(scr->viewBackendCtx, win->view, + win->wname, WMGetApplicationName(), + win->owner ? win->owner->view : NULL); + } } } void WMSetWindowMiniwindowImage(WMWindow * win, RImage * image) { - if (win->view->flags.realized) - setMiniwindow(win, image); + if (win->view->flags.realized) { + W_Screen *scr = win->view->screen; + const W_ViewBackend *vb = scr->viewBackend; + if (vb->window_set_icon_image) + vb->window_set_icon_image(scr->viewBackendCtx, win->view, image); + } } void WMSetWindowMiniwindowPixmap(WMWindow * win, WMPixmap * pixmap) @@ -567,27 +320,12 @@ void WMSetWindowMiniwindowPixmap(WMWindow * win, WMPixmap * pixmap) win->miniImage = NULL; if (win->view->flags.realized) { - XWMHints *hints; - - hints = XGetWMHints(win->view->screen->display, win->view->window); - if (!hints) { - hints = XAllocWMHints(); - if (!hints) { - wwarning("could not allocate memory for WM hints"); - return; - } - hints->flags = 0; - } - if (pixmap) { - hints->flags |= IconPixmapHint; - hints->icon_pixmap = WMGetPixmapXID(pixmap); - hints->icon_mask = WMGetPixmapMaskXID(pixmap); - if (hints->icon_mask != None) { - hints->flags |= IconMaskHint; - } - } - XSetWMHints(win->view->screen->display, win->view->window, hints); - XFree(hints); + W_Screen *scr = win->view->screen; + const W_ViewBackend *vb = scr->viewBackend; + if (vb->window_realize) + vb->window_realize(scr->viewBackendCtx, win->view, + win->wname, WMGetApplicationName(), + win->owner ? win->owner->view : NULL); } } } @@ -605,7 +343,10 @@ void WMSetWindowMiniwindowTitle(WMWindow * win, const char *title) win->miniTitle = NULL; if (win->view->flags.realized) { - setMiniwindowTitle(win, title); + W_Screen *scr = win->view->screen; + const W_ViewBackend *vb = scr->viewBackend; + if (vb->window_set_icon_title) + vb->window_set_icon_title(scr->viewBackendCtx, win->view, title); } } } @@ -614,8 +355,12 @@ void WMCloseWindow(WMWindow * win) { WMUnmapWidget(win); /* withdraw the window */ - if (win->view->flags.realized) - XWithdrawWindow(win->view->screen->display, win->view->window, win->view->screen->screen); + if (win->view->flags.realized) { + W_Screen *scr = win->view->screen; + const W_ViewBackend *vb = scr->viewBackend; + if (vb->window_withdraw) + vb->window_withdraw(scr->viewBackendCtx, win->view); + } } static void handleEvents(WMEvent * event, void *clientData) diff --git a/WINGs/wwindow_p.h b/WINGs/wwindow_p.h new file mode 100644 index 0000000..58d7ac1 --- /dev/null +++ b/WINGs/wwindow_p.h @@ -0,0 +1,49 @@ +/* wwindow_p.h - private _Window struct for vtable backends */ + +#ifndef _WWINDOW_P_H_ +#define _WWINDOW_P_H_ + +#include "WINGsP.h" + +typedef struct W_Window { + W_Class widgetClass; + W_View *view; + + struct W_Window *nextPtr; /* next in the window list */ + + struct W_Window *owner; + + char *title; + + WMPixmap *miniImage; /* miniwindow */ + char *miniTitle; + + char *wname; + + WMSize resizeIncrement; + WMSize baseSize; + WMSize minSize; + WMSize maxSize; + WMPoint minAspect; + WMPoint maxAspect; + + WMPoint upos; + WMPoint ppos; + + WMAction *closeAction; + void *closeData; + + int level; + + struct { + unsigned style:4; + unsigned configured:1; + unsigned documentEdited:1; + + unsigned setUPos:1; + unsigned setPPos:1; + unsigned setAspect:1; + } flags; +} _Window; + +#endif /* _WWINDOW_P_H_ */