Phase 80c: add vtable slots for cross-mode rendering functions

Add vtable slots: icon_select, icon_change_title, clip_icon_paint,
drawer_icon_paint, balloon_init, do_kaboom, menu_paint_entry,
menu_draw_frame.

Replace policy call sites with vtable dispatch. Make paintEntry and
drawFrame in menu.c non-static as wMenuPaintEntry/wMenuDrawFrame.

X11 backend calls the mechanism functions; Wayland backend is no-op.
wFrameWindowPaint now only reached through X11 backend's frame_paint.
This commit is contained in:
Levi Neely 2026-05-13 10:24:21 +02:00
parent 9cfe322573
commit dfac01a478
11 changed files with 103 additions and 23 deletions

View File

@ -1544,7 +1544,7 @@ void wIconifyWindow(WWindow *wwin)
*/
if (wwin->flags.selected && !wPreferences.disable_miniwindows
&& !wwin->flags.net_handle_icon)
wIconSelect(wwin->icon);
wm_backend->icon_select(wwin->icon);
WMPostNotificationName(WMNChangedState, wwin, "iconify");
@ -1597,7 +1597,7 @@ void wDeiconifyWindow(WWindow *wwin)
if (!wPreferences.disable_miniwindows && !wwin->flags.net_handle_icon
&& wwin->icon != NULL) {
if (wwin->icon->selected)
wIconSelect(wwin->icon);
wm_backend->icon_select(wwin->icon);
wm_backend->window_unmap(wwin->icon->core->window);
}

View File

@ -1049,8 +1049,8 @@ Bool wHandleAppIconMove(WAppIcon *aicon, XEvent *event)
* wDockDetach(), because else DoKaboom() will fail.
*/
if (aicon->icon->selected)
wIconSelect(aicon->icon);
DoKaboom(scr, aicon->icon->core->window, x, y);
wm_backend->icon_select(aicon->icon);
wm_backend->do_kaboom(scr, (WNativeWindow)aicon->icon->core->window, x, y);
}
}
wDockDetach(originalDock, aicon);

View File

@ -47,6 +47,7 @@ typedef struct WIcon WIcon;
typedef struct WProtocols WProtocols;
typedef struct WShortKey WShortKey;
typedef struct MWMHints MWMHints;
typedef struct WMenu WMenu;
/*
* WMBackend -- vtable for all display-system operations.
@ -1640,6 +1641,40 @@ typedef struct WMBackend {
*/
void (*event_handle_signal_exit)(void);
/* ------------------------------------------------------------------ */
/* Icon interaction (Phase 80c) */
/* ------------------------------------------------------------------ */
void (*icon_select)(WIcon *icon);
void (*icon_change_title)(WIcon *icon, WWindow *wwin);
/* ------------------------------------------------------------------ */
/* Clip/Drawer icon rendering (Phase 80c) */
/* ------------------------------------------------------------------ */
void (*clip_icon_paint)(WAppIcon *aicon);
void (*drawer_icon_paint)(WAppIcon *aicon);
/* ------------------------------------------------------------------ */
/* Balloon tooltips (Phase 80c) */
/* ------------------------------------------------------------------ */
void (*balloon_init)(WScreen *scr);
/* ------------------------------------------------------------------ */
/* Superfluous effects (Phase 80c) */
/* ------------------------------------------------------------------ */
void (*do_kaboom)(WScreen *scr, WNativeWindow win, int x, int y);
/* ------------------------------------------------------------------ */
/* Menu rendering (Phase 80c) */
/* ------------------------------------------------------------------ */
void (*menu_paint_entry)(WMenu *menu, int index, int selected);
void (*menu_draw_frame)(WScreen *scr, WNativeWindow win,
int y, int w, int h, int type);
} WMBackend;
/*

View File

@ -6168,6 +6168,18 @@ static void wl_event_handle_signal_exit(void)
wm_backend->event_loop_terminate();
}
static void wl_noop_icon_select(WIcon *icon) { (void)icon; }
static void wl_noop_icon_change_title(WIcon *icon, WWindow *wwin) { (void)icon; (void)wwin; }
static void wl_noop_clip_icon_paint(WAppIcon *aicon) { (void)aicon; }
static void wl_noop_drawer_icon_paint(WAppIcon *aicon) { (void)aicon; }
static void wl_noop_balloon_init(WScreen *scr) { (void)scr; }
static void wl_noop_do_kaboom(WScreen *scr, WNativeWindow win, int x, int y)
{ (void)scr; (void)win; (void)x; (void)y; }
static void wl_noop_menu_paint_entry(WMenu *menu, int index, int selected)
{ (void)menu; (void)index; (void)selected; }
static void wl_noop_menu_draw_frame(WScreen *scr, WNativeWindow win, int y, int w, int h, int type)
{ (void)scr; (void)win; (void)y; (void)w; (void)h; (void)type; }
/* ------------------------------------------------------------------ */
/* vtable */
/* ------------------------------------------------------------------ */
@ -6369,4 +6381,12 @@ const WMBackend wl_backend = {
.appicon_bounce = wl_noop_appicon_bounce,
.manage_all_windows = wl_noop_manage_all_windows,
.event_handle_signal_exit = wl_event_handle_signal_exit,
.icon_select = wl_noop_icon_select,
.icon_change_title = wl_noop_icon_change_title,
.clip_icon_paint = wl_noop_clip_icon_paint,
.drawer_icon_paint = wl_noop_drawer_icon_paint,
.balloon_init = wl_noop_balloon_init,
.do_kaboom = wl_noop_do_kaboom,
.menu_paint_entry = wl_noop_menu_paint_entry,
.menu_draw_frame = wl_noop_menu_draw_frame,
};

View File

@ -66,6 +66,8 @@
#include "../../wcore.h"
#include "../../dock.h"
#include "../../texture.h"
#include "../../menu.h"
#include "../../balloon.h"
#include "../backend.h"
#include "x11_compat.h"
#include "x11_backend.h"
@ -2921,6 +2923,19 @@ static void x11_event_handle_signal_exit(void)
Shutdown(WSExitMode);
}
/* -------------------------------------------------------------------- */
/* Icon/Clip/Balloon/Menu (Phase 80c) */
/* -------------------------------------------------------------------- */
static void x11_icon_select(WIcon *icon) { wIconSelect(icon); }
static void x11_icon_change_title(WIcon *icon, WWindow *wwin) { wIconChangeTitle(icon, wwin); }
static void x11_clip_icon_paint(WAppIcon *aicon) { wClipIconPaint(aicon); }
static void x11_drawer_icon_paint(WAppIcon *aicon) { wDrawerIconPaint(aicon); }
static void x11_balloon_init(WScreen *scr) { wBalloonInitialize(scr); }
static void x11_do_kaboom(WScreen *scr, WNativeWindow win, int x, int y) { DoKaboom(scr, (Window)win, x, y); }
static void x11_menu_paint_entry(WMenu *menu, int index, int selected) { wMenuPaintEntry(menu, index, selected); }
static void x11_menu_draw_frame(WScreen *scr, WNativeWindow win, int y, int w, int h, int type) { wMenuDrawFrame(scr, (Window)win, y, w, h, type); }
/* -------------------------------------------------------------------- */
/* Backend vtable instance and active-backend pointer */
/* -------------------------------------------------------------------- */
@ -3101,6 +3116,14 @@ const WMBackend x11_backend = {
.appicon_bounce = x11_appicon_bounce,
.manage_all_windows = x11_manage_all_windows,
.event_handle_signal_exit = x11_event_handle_signal_exit,
.icon_select = x11_icon_select,
.icon_change_title = x11_icon_change_title,
.clip_icon_paint = x11_clip_icon_paint,
.drawer_icon_paint = x11_drawer_icon_paint,
.balloon_init = x11_balloon_init,
.do_kaboom = x11_do_kaboom,
.menu_paint_entry = x11_menu_paint_entry,
.menu_draw_frame = x11_menu_draw_frame,
};
/*

View File

@ -265,7 +265,7 @@ void wClientCheckProperty(WWindow * wwin, XPropertyEvent * event)
case WA_WM_ICON_NAME:
/* Title has changed, update the icon title */
if (wwin->icon) {
wIconChangeTitle(wwin->icon, wwin);
wm_backend->icon_change_title(wwin->icon, wwin);
wm_backend->icon_paint(wwin->icon);
}
break;

View File

@ -1312,10 +1312,10 @@ void wDefaultUpdateIcons(WScreen *scr)
}
if (!wPreferences.flags.noclip || wPreferences.flags.clip_merged_in_dock)
wClipIconPaint(scr->clip_icon);
wm_backend->clip_icon_paint(scr->clip_icon);
for (dc = scr->drawers; dc != NULL; dc = dc->next)
wDrawerIconPaint(dc->adrawer->icon_array[0]);
wm_backend->drawer_icon_paint(dc->adrawer->icon_array[0]);
while (wwin) {
if (wwin->icon && wwin->flags.miniaturized)

View File

@ -180,9 +180,9 @@ static void panelBtnCallback(WMWidget * self, void *data)
// Cf dock.c:dockIconPaint(WAppIcon *aicon)?
if (aicon == aicon->icon->core->screen_ptr->clip_icon)
wClipIconPaint(aicon);
wm_backend->clip_icon_paint(aicon);
else if (wIsADrawer(aicon))
wDrawerIconPaint(aicon);
wm_backend->drawer_icon_paint(aicon);
else
wm_backend->appicon_paint(aicon);

View File

@ -619,7 +619,7 @@ void wMenuDestroy(WMenu * menu, int recurse)
#define F_BOTTOM 2
#define F_NONE 3
static void drawFrame(WScreen * scr, Drawable win, int y, int w, int h, int type)
void wMenuDrawFrame(WScreen * scr, Drawable win, int y, int w, int h, int type)
{
XSegment segs[2];
int i;
@ -656,7 +656,7 @@ static void drawFrame(WScreen * scr, Drawable win, int y, int w, int h, int type
XDrawLine(dpy, win, scr->menu_item_auxtexture->dark_gc, 0, y + h - 1, w - 1, y + h - 1);
}
static void paintEntry(WMenu * menu, int index, int selected)
void wMenuPaintEntry(WMenu * menu, int index, int selected)
{
WScreen *scr = menu->frame->screen_ptr;
Window win = menu->menu->window;
@ -695,12 +695,12 @@ static void paintEntry(WMenu * menu, int index, int selected)
if (selected) {
XFillRectangle(dpy, win, WMColorGC(scr->select_color), 1, y + 1, w - 2, h - 3);
if (scr->menu_item_texture->any.type == WTEX_SOLID)
drawFrame(scr, win, y, w, h, type);
wMenuDrawFrame(scr, win, y, w, h, type);
} else {
if (scr->menu_item_texture->any.type == WTEX_SOLID) {
XClearArea(dpy, win, 0, y + 1, w - 1, h - 3, False);
/* draw the frame */
drawFrame(scr, win, y, w, h, type);
wMenuDrawFrame(scr, win, y, w, h, type);
} else {
XClearArea(dpy, win, 0, y, w, h, False);
}
@ -1060,10 +1060,10 @@ static int keyboardMenu(WMenu * menu)
int i;
for (i = 0; i < MENU_BLINK_COUNT; i++) {
paintEntry(menu, sel, False);
wMenuPaintEntry(menu, sel, False);
wm_backend->event_sync(0);
wusleep(MENU_BLINK_DELAY);
paintEntry(menu, sel, True);
wMenuPaintEntry(menu, sel, True);
wm_backend->event_sync(0);
wusleep(MENU_BLINK_DELAY);
}
@ -1185,7 +1185,7 @@ void wMenuPaint(WMenu * menu)
/* paint entries */
for (i = 0; i < menu->entry_no; i++) {
paintEntry(menu, i, i == menu->selected_entry);
wMenuPaintEntry(menu, i, i == menu->selected_entry);
}
}
@ -1194,8 +1194,8 @@ void wMenuSetEnabled(WMenu * menu, int index, int enable)
if (index >= menu->entry_no)
return;
menu->entries[index]->flags.enabled = enable;
paintEntry(menu, index, index == menu->selected_entry);
paintEntry(menu->brother, index, index == menu->selected_entry);
wMenuPaintEntry(menu, index, index == menu->selected_entry);
wMenuPaintEntry(menu->brother, index, index == menu->selected_entry);
}
@ -1218,7 +1218,7 @@ static void selectEntry(WMenu * menu, int entry_no)
/* unselect previous entry */
if (old_entry >= 0) {
paintEntry(menu, old_entry, False);
wMenuPaintEntry(menu, old_entry, False);
entry = menu->entries[old_entry];
/* unmap cascade */
@ -1303,7 +1303,7 @@ static void selectEntry(WMenu * menu, int entry_no)
return;
}
}
paintEntry(menu, entry_no, True);
wMenuPaintEntry(menu, entry_no, True);
}
}
@ -2031,10 +2031,10 @@ static void menuMouseDown(WObjDescriptor * desc, WBackendEvent * event)
int i;
for (i = 0; i < MENU_BLINK_COUNT; i++) {
paintEntry(menu, sel, False);
wMenuPaintEntry(menu, sel, False);
wm_backend->event_sync(0);
wusleep(MENU_BLINK_DELAY);
paintEntry(menu, sel, True);
wMenuPaintEntry(menu, sel, True);
wm_backend->event_sync(0);
wusleep(MENU_BLINK_DELAY);
}

View File

@ -148,4 +148,6 @@ void wMenuSaveState(WScreen *scr);
void wMenuRestoreState(WScreen *scr);
void wMenuPaintEntry(WMenu *menu, int index, int selected);
void wMenuDrawFrame(WScreen *scr, Drawable win, int y, int w, int h, int type);
#endif

View File

@ -268,7 +268,7 @@ WScreen *wScreenInit(int screen_number)
#ifdef BALLOON_TEXT
/* initialize balloon text stuff */
wBalloonInitialize(scr);
wm_backend->balloon_init(scr);
#endif
scr->info_text_font = WMBoldSystemFontOfSize(scr->wmscreen, 12);