From 41daf2464231dfaa6dd42cf27591fd076fb72681 Mon Sep 17 00:00:00 2001 From: e-tho Date: Sat, 5 Apr 2025 02:32:33 +0200 Subject: [PATCH] [Dmenu][Script] Add support for fallback icons This adds support for fallback icons in dmenu mode using comma-separated values in the icon metadata. When the primary icon is not found, subsequent icons in the list will be tried until one is successfully loaded. Example usage: "Firefox\0icon\x1ffirefox,web-browser,application-x-executable" --- doc/rofi-script.5.markdown | 4 ++-- source/modes/dmenu.c | 31 ++++++++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/doc/rofi-script.5.markdown b/doc/rofi-script.5.markdown index 9d5d41c3..35a4fcfd 100644 --- a/doc/rofi-script.5.markdown +++ b/doc/rofi-script.5.markdown @@ -138,7 +138,7 @@ For example: The following options are supported: -- **icon**: Set the icon for that row. +- **icon**: Set the icon for that row. Multiple fallback icons can be specified using comma-separated values. - **display**: Replace the displayed string. (Original string will still be used for filtering) @@ -158,7 +158,7 @@ The following options are supported: multiple entries can be passed using the `\x1f` separator. ```bash - echo -en "aap\0icon\x1ffolder\x1finfo\x1ftest\n" + echo -en "aap\0icon\x1ffolder,inode-directory\x1finfo\x1ftest\n" ``` ## Executing external program diff --git a/source/modes/dmenu.c b/source/modes/dmenu.c index fd55af21..55b1d323 100644 --- a/source/modes/dmenu.c +++ b/source/modes/dmenu.c @@ -720,11 +720,36 @@ static cairo_surface_t *dmenu_get_icon(const Mode *sw, if (dr->icon_name == NULL) { return NULL; } - uint32_t uid = dr->icon_fetch_uid = + // Check if we have multiple icons + if (strchr(dr->icon_name, ',') == NULL) { + // Single icon case + uint32_t uid = dr->icon_fetch_uid = rofi_icon_fetcher_query(dr->icon_name, height); - dr->icon_fetch_size = height; + dr->icon_fetch_size = height; - return rofi_icon_fetcher_get(uid); + return rofi_icon_fetcher_get(uid); + } else { + // Multiple icons case + cairo_surface_t *icon_surface = NULL; + char *icon_name_copy = g_strdup(dr->icon_name); + char *icon_iter = icon_name_copy; + char *icon = NULL; + // Try each icon in the comma-separated list until one is found + while ((icon = strsep(&icon_iter, ",")) != NULL) { + // Try to fetch this icon + uint32_t uid = rofi_icon_fetcher_query(icon, height); + icon_surface = rofi_icon_fetcher_get(uid); + // If we found an icon, store the successful parameters and break the loop + if (icon_surface != NULL) { + dr->icon_fetch_uid = uid; + dr->icon_fetch_size = height; + break; + } + } + // Free the copy of the icon list + g_free(icon_name_copy); + return icon_surface; + } } static void dmenu_finish(DmenuModePrivateData *pd, RofiViewState *state,