From bdfabcf800854838caf3764da5a351b5d00d16fb Mon Sep 17 00:00:00 2001 From: deepend Date: Wed, 18 Feb 2026 00:00:59 -0700 Subject: [PATCH] Standardized GTK3 menu icon resolution so stock-style menu icons are first mapped to the bundled zc-menu-* names (which are backed by data/icons/menu/...), but only for menu-sized icon requests. This keeps non-menu button icons unaffected while making menu icons consistent. Updated menu construction paths to resolve both zc-menu-* and legacy gtk-* stock names through one custom mapping before loading icons from the bundled menu icon assets, with fallback to light theme assets and then theme icon names. This affects both quick/user menus and standard icon menu items. --- src/fe-gtk/gtkutil.c | 58 ++++++++++++++++++++++++++++++++- src/fe-gtk/menu.c | 77 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 131 insertions(+), 4 deletions(-) diff --git a/src/fe-gtk/gtkutil.c b/src/fe-gtk/gtkutil.c index e0074ea0..eda10867 100644 --- a/src/fe-gtk/gtkutil.c +++ b/src/fe-gtk/gtkutil.c @@ -62,6 +62,53 @@ struct file_req int flags; /* FRF_* flags */ }; +#if HAVE_GTK3 +static const char * +gtkutil_menu_custom_icon_from_stock (const char *stock_name) +{ + static const struct + { + const char *stock; + const char *custom_icon; + } icon_map[] = { + { "gtk-new", "zc-menu-new" }, + { "gtk-index", "zc-menu-network-list" }, + { "gtk-revert-to-saved", "zc-menu-load-plugin" }, + { "gtk-redo", "zc-menu-detach" }, + { "gtk-close", "zc-menu-close" }, + { "gtk-quit", "zc-menu-quit" }, + { "gtk-disconnect", "zc-menu-disconnect" }, + { "gtk-connect", "zc-menu-connect" }, + { "gtk-jump-to", "zc-menu-join" }, + { "gtk-preferences", "zc-menu-preferences" }, + { "gtk-clear", "zc-menu-clear" }, + { "gtk-copy", "zc-menu-copy" }, + { "gtk-delete", "zc-menu-delete" }, + { "gtk-add", "zc-menu-add" }, + { "gtk-remove", "zc-menu-remove" }, + { "gtk-spell-check", "zc-menu-spell-check" }, + { "gtk-save", "zc-menu-save" }, + { "gtk-refresh", "zc-menu-refresh" }, + { "gtk-justify-left", "zc-menu-search" }, + { "gtk-find", "zc-menu-find" }, + { "gtk-help", "zc-menu-help" }, + { "gtk-about", "zc-menu-about" }, + }; + size_t i; + + if (!stock_name) + return NULL; + + for (i = 0; i < G_N_ELEMENTS (icon_map); i++) + { + if (strcmp (stock_name, icon_map[i].stock) == 0) + return icon_map[i].custom_icon; + } + + return NULL; +} +#endif + #if HAVE_GTK3 const char * gtkutil_icon_name_from_stock (const char *stock_name) @@ -197,7 +244,16 @@ gtkutil_image_new_from_stock (const char *stock, GtkIconSize size) { #if HAVE_GTK3 GtkWidget *image; - const char *icon_name = gtkutil_icon_name_from_stock (stock); + const char *icon_name; + + icon_name = gtkutil_icon_name_from_stock (stock); + if (size == GTK_ICON_SIZE_MENU) + { + const char *menu_icon_name = gtkutil_menu_custom_icon_from_stock (stock); + + if (menu_icon_name) + icon_name = menu_icon_name; + } image = gtkutil_menu_icon_image_new (icon_name, size); if (image) diff --git a/src/fe-gtk/menu.c b/src/fe-gtk/menu.c index 9df05f2d..4ed52c70 100644 --- a/src/fe-gtk/menu.c +++ b/src/fe-gtk/menu.c @@ -276,6 +276,74 @@ menu_toggle_item (char *label, GtkWidget *menu, void *callback, void *userdata, #if HAVE_GTK3 static const char *menu_icon_theme_variant (void); static GtkWidget *menu_icon_image_from_data_icons (const char *icon_name, const char *theme_variant); + +static const char * +menu_custom_icon_from_stock (const char *stock_name) +{ + static const struct + { + const char *stock; + const char *custom; + } icon_map[] = { + { "zc-menu-new", "new" }, + { "zc-menu-network-list", "network-list" }, + { "zc-menu-load-plugin", "load-plugin" }, + { "zc-menu-detach", "detach" }, + { "zc-menu-close", "close" }, + { "zc-menu-quit", "quit" }, + { "zc-menu-disconnect", "disconnect" }, + { "zc-menu-connect", "connect" }, + { "zc-menu-join", "join" }, + { "zc-menu-chanlist", "chanlist" }, + { "zc-menu-preferences", "preferences" }, + { "zc-menu-clear", "clear" }, + { "zc-menu-copy", "copy" }, + { "zc-menu-delete", "delete" }, + { "zc-menu-add", "add" }, + { "zc-menu-remove", "remove" }, + { "zc-menu-spell-check", "spell-check" }, + { "zc-menu-save", "save" }, + { "zc-menu-refresh", "refresh" }, + { "zc-menu-search", "search" }, + { "zc-menu-find", "find" }, + { "zc-menu-help", "help" }, + { "zc-menu-about", "about" }, + { "gtk-new", "new" }, + { "gtk-index", "network-list" }, + { "gtk-revert-to-saved", "load-plugin" }, + { "gtk-redo", "detach" }, + { "gtk-close", "close" }, + { "gtk-quit", "quit" }, + { "gtk-disconnect", "disconnect" }, + { "gtk-connect", "connect" }, + { "gtk-jump-to", "join" }, + { "gtk-preferences", "preferences" }, + { "gtk-clear", "clear" }, + { "gtk-copy", "copy" }, + { "gtk-delete", "delete" }, + { "gtk-add", "add" }, + { "gtk-remove", "remove" }, + { "gtk-spell-check", "spell-check" }, + { "gtk-save", "save" }, + { "gtk-refresh", "refresh" }, + { "gtk-justify-left", "search" }, + { "gtk-find", "find" }, + { "gtk-help", "help" }, + { "gtk-about", "about" }, + }; + size_t i; + + if (!stock_name) + return NULL; + + for (i = 0; i < G_N_ELEMENTS (icon_map); i++) + { + if (strcmp (stock_name, icon_map[i].stock) == 0) + return icon_map[i].custom; + } + + return NULL; +} #endif GtkWidget * @@ -316,7 +384,8 @@ menu_quick_item (char *cmd, char *label, GtkWidget * menu, int flags, icon_name = gtkutil_icon_name_from_stock (icon); if (!icon_name) icon_name = icon; - if (g_str_has_prefix (icon_name, "zc-menu-")) + custom_icon = menu_custom_icon_from_stock (icon); + if (!custom_icon && g_str_has_prefix (icon_name, "zc-menu-")) custom_icon = icon_name + strlen ("zc-menu-"); #endif #if !HAVE_GTK3 @@ -2239,9 +2308,11 @@ create_icon_menu (char *labeltext, void *stock_name, int is_stock) { #if HAVE_GTK3 icon_name = stock_name; - if (g_str_has_prefix (icon_name, "zc-menu-")) - { + custom_icon = menu_custom_icon_from_stock (stock_name); + if (!custom_icon && g_str_has_prefix (icon_name, "zc-menu-")) custom_icon = icon_name + strlen ("zc-menu-"); + if (custom_icon) + { theme_variant = menu_icon_theme_variant (); image = menu_icon_image_from_data_icons (custom_icon, theme_variant); if (!image)