From dfac01a478b66ccdbc4f8a89d00bb8ecfdb9c4a5 Mon Sep 17 00:00:00 2001 From: Levi Neely <141506390+lneely@users.noreply.github.com> Date: Wed, 13 May 2026 10:24:21 +0200 Subject: [PATCH] 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. --- src/actions.c | 4 ++-- src/appicon.c | 4 ++-- src/backend/backend.h | 35 ++++++++++++++++++++++++++++++++ src/backend/wayland/wl_backend.c | 20 ++++++++++++++++++ src/backend/x11/x11_backend.c | 23 +++++++++++++++++++++ src/client.c | 2 +- src/defaults.c | 4 ++-- src/dockedapp.c | 4 ++-- src/menu.c | 26 ++++++++++++------------ src/menu.h | 2 ++ src/screen.c | 2 +- 11 files changed, 103 insertions(+), 23 deletions(-) diff --git a/src/actions.c b/src/actions.c index d820f8b..9dec494 100644 --- a/src/actions.c +++ b/src/actions.c @@ -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); } diff --git a/src/appicon.c b/src/appicon.c index 01081d0..e016f2d 100644 --- a/src/appicon.c +++ b/src/appicon.c @@ -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); diff --git a/src/backend/backend.h b/src/backend/backend.h index 7fbcd91..fd75c18 100644 --- a/src/backend/backend.h +++ b/src/backend/backend.h @@ -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; /* diff --git a/src/backend/wayland/wl_backend.c b/src/backend/wayland/wl_backend.c index 6826adb..4948b84 100644 --- a/src/backend/wayland/wl_backend.c +++ b/src/backend/wayland/wl_backend.c @@ -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, }; diff --git a/src/backend/x11/x11_backend.c b/src/backend/x11/x11_backend.c index 6c4ca65..a696406 100644 --- a/src/backend/x11/x11_backend.c +++ b/src/backend/x11/x11_backend.c @@ -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, }; /* diff --git a/src/client.c b/src/client.c index 1c94d0e..eade7b5 100644 --- a/src/client.c +++ b/src/client.c @@ -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; diff --git a/src/defaults.c b/src/defaults.c index ba2307c..c42d0d1 100644 --- a/src/defaults.c +++ b/src/defaults.c @@ -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) diff --git a/src/dockedapp.c b/src/dockedapp.c index 199eb4a..6de3c7d 100644 --- a/src/dockedapp.c +++ b/src/dockedapp.c @@ -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); diff --git a/src/menu.c b/src/menu.c index dacdf48..214a37d 100644 --- a/src/menu.c +++ b/src/menu.c @@ -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); } diff --git a/src/menu.h b/src/menu.h index 60ff955..5d0512e 100644 --- a/src/menu.h +++ b/src/menu.h @@ -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 diff --git a/src/screen.c b/src/screen.c index 669d5d2..7fa3cf4 100644 --- a/src/screen.c +++ b/src/screen.c @@ -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);