diff --git a/include/mode-private.h b/include/mode-private.h index a64cc6fd..26f85527 100644 --- a/include/mode-private.h +++ b/include/mode-private.h @@ -61,6 +61,7 @@ typedef char *(*_mode_get_display_value)(const Mode *sw, * @param sw The #Mode pointer * @param selected_line The selected line * @param height The height of the icon + * @param scale The scale of the icon * * Obtains the icon if available * @@ -68,7 +69,8 @@ typedef char *(*_mode_get_display_value)(const Mode *sw, */ typedef cairo_surface_t *(*_mode_get_icon)(const Mode *sw, unsigned int selected_line, - unsigned int height); + unsigned int height, + guint scale); /** * @param sw The #Mode pointer diff --git a/include/mode.h b/include/mode.h index 3825ee43..b8839cd4 100644 --- a/include/mode.h +++ b/include/mode.h @@ -133,13 +133,14 @@ char *mode_get_display_value(const Mode *mode, unsigned int selected_line, * @param mode The mode to query * @param selected_line The entry to query * @param height The desired height of the icon. + * @param scale The desired scale of the icon. * * Returns the icon for the selected_line * * @returns allocated new cairo_surface_t if applicable */ cairo_surface_t *mode_get_icon(Mode *mode, unsigned int selected_line, - unsigned int height); + unsigned int height, guint scale); /** * @param mode The mode to query diff --git a/include/modes/dmenuscriptshared.h b/include/modes/dmenuscriptshared.h index a1808d21..56af76dc 100644 --- a/include/modes/dmenuscriptshared.h +++ b/include/modes/dmenuscriptshared.h @@ -13,6 +13,7 @@ typedef struct { /** Async icon fetch handler. */ uint32_t icon_fetch_uid; uint32_t icon_fetch_size; + guint icon_fetch_scale; /** Hidden meta keywords. */ char *meta; diff --git a/include/rofi-icon-fetcher.h b/include/rofi-icon-fetcher.h index 5394db5d..6556623a 100644 --- a/include/rofi-icon-fetcher.h +++ b/include/rofi-icon-fetcher.h @@ -26,8 +26,9 @@ void rofi_icon_fetcher_destroy(void); /** * @param name The name of the icon to fetch. * @param size The size of the icon to fetch. + * @param scale The scale of the icon to fetch. * - * Query the icon-theme for icon with name and size. + * Query the icon-theme for icon with name, size, and scale. * The returned icon will be the best match for the requested size, it should * still be resized to the actual size. * @@ -35,14 +36,16 @@ void rofi_icon_fetcher_destroy(void); * * @returns the uid identifying the request. */ -uint32_t rofi_icon_fetcher_query(const char *name, const int size); +uint32_t rofi_icon_fetcher_query(const char *name, const int size, + const guint scale); /** * @param name The name of the icon to fetch. * @param wsize The width of the icon to fetch. * @param hsize The height of the icon to fetch. + * @param scale The scale of the icon to fetch. * - * Query the icon-theme for icon with name and size. + * Query the icon-theme for icon with name, size, and scale. * The returned icon will be the best match for the requested size, it should * still be resized to the actual size. For icons it will take the min of wsize * and hsize. @@ -52,7 +55,7 @@ uint32_t rofi_icon_fetcher_query(const char *name, const int size); * @returns the uid identifying the request. */ uint32_t rofi_icon_fetcher_query_advanced(const char *name, const int wsize, - const int hsize); + const int hsize, const guint scale); /** * @param uid The unique id representing the matching request. diff --git a/include/rofi-types.h b/include/rofi-types.h index 807a2556..2172a187 100644 --- a/include/rofi-types.h +++ b/include/rofi-types.h @@ -192,6 +192,7 @@ typedef struct { RofiScaleType scaling; int wsize; int hsize; + guint scale; RofiDirection dir; double angle; diff --git a/include/theme.h b/include/theme.h index 45faa67c..b9c33c54 100644 --- a/include/theme.h +++ b/include/theme.h @@ -83,12 +83,12 @@ typedef struct ThemeWidget { } ThemeWidget; /** - * Global pointer to the current active theme. + * Display scale. */ -extern ThemeWidget *rofi_theme; +typedef guint (*disp_scale_func)(void); /** - * Used to store theme. + * Global pointer to the current active theme. */ extern ThemeWidget *rofi_theme; @@ -468,4 +468,9 @@ void rofi_theme_print_parsed_files(int is_term); */ GList *rofi_theme_get_list_distance(const widget *widget, const char *property); GList *rofi_theme_get_list_strings(const widget *widget, const char *property); + +/** + * @param func The function pointer to scale getter. + */ +void rofi_theme_set_disp_scale_func(disp_scale_func func); #endif diff --git a/source/mode.c b/source/mode.c index 02c4aaee..66bd659d 100644 --- a/source/mode.c +++ b/source/mode.c @@ -73,11 +73,11 @@ char *mode_get_display_value(const Mode *mode, unsigned int selected_line, } cairo_surface_t *mode_get_icon(Mode *mode, unsigned int selected_line, - unsigned int height) { + unsigned int height, guint scale) { g_assert(mode != NULL); if (mode->_get_icon != NULL) { - cairo_surface_t *icon = mode->_get_icon(mode, selected_line, height); + cairo_surface_t *icon = mode->_get_icon(mode, selected_line, height, scale); if (icon) { return icon; } @@ -98,7 +98,7 @@ cairo_surface_t *mode_get_icon(Mode *mode, unsigned int selected_line, rofi_theme_find_property(wid, P_STRING, "fallback-icon", TRUE); if (p != NULL && (p->type == P_STRING && p->value.s)) { mode->fallback_icon_fetch_uid = - rofi_icon_fetcher_query(p->value.s, height); + rofi_icon_fetcher_query(p->value.s, height, scale); return NULL; } } diff --git a/source/modes/combi.c b/source/modes/combi.c index 9e548906..bebbcaf7 100644 --- a/source/modes/combi.c +++ b/source/modes/combi.c @@ -285,12 +285,12 @@ static char *combi_get_completion(const Mode *sw, unsigned int index) { } static cairo_surface_t *combi_get_icon(const Mode *sw, unsigned int index, - unsigned int height) { + unsigned int height, guint scale) { CombiModePrivateData *pd = mode_get_private_data(sw); for (unsigned i = 0; i < pd->num_switchers; i++) { if (index >= pd->starts[i] && index < (pd->starts[i] + pd->lengths[i])) { - cairo_surface_t *icon = - mode_get_icon(pd->switchers[i].mode, index - pd->starts[i], height); + cairo_surface_t *icon = mode_get_icon( + pd->switchers[i].mode, index - pd->starts[i], height, scale); return icon; } } diff --git a/source/modes/dmenu.c b/source/modes/dmenu.c index d6431f55..e308862c 100644 --- a/source/modes/dmenu.c +++ b/source/modes/dmenu.c @@ -56,8 +56,9 @@ static int dmenu_mode_init(Mode *sw); static int dmenu_token_match(const Mode *sw, rofi_int_matcher **tokens, unsigned int index); -static cairo_surface_t * -dmenu_get_icon(const Mode *sw, unsigned int selected_line, unsigned int height); +static cairo_surface_t *dmenu_get_icon(const Mode *sw, + unsigned int selected_line, + unsigned int height, guint scale); static char *dmenu_get_message(const Mode *sw); static inline unsigned int bitget(uint32_t const *const array, @@ -132,6 +133,7 @@ static void read_add_block(DmenuModePrivateData *pd, Block **block, char *data, // Init. (*block)->values[(*block)->length].icon_fetch_uid = 0; (*block)->values[(*block)->length].icon_fetch_size = 0; + (*block)->values[(*block)->length].icon_fetch_scale = 0; (*block)->values[(*block)->length].icon_name = NULL; (*block)->values[(*block)->length].meta = NULL; (*block)->values[(*block)->length].info = NULL; @@ -162,6 +164,7 @@ static void read_add(DmenuModePrivateData *pd, char *data, gsize len) { // Init. pd->cmd_list[pd->cmd_list_length].icon_fetch_uid = 0; pd->cmd_list[pd->cmd_list_length].icon_fetch_size = 0; + pd->cmd_list[pd->cmd_list_length].icon_fetch_scale = 0; pd->cmd_list[pd->cmd_list_length].icon_name = NULL; pd->cmd_list[pd->cmd_list_length].meta = NULL; pd->cmd_list[pd->cmd_list_length].info = NULL; @@ -678,7 +681,8 @@ static char *dmenu_get_message(const Mode *sw) { } static cairo_surface_t *dmenu_get_icon(const Mode *sw, unsigned int selected_line, - unsigned int height) { + unsigned int height, + guint scale) { DmenuModePrivateData *pd = (DmenuModePrivateData *)mode_get_private_data(sw); g_return_val_if_fail(pd->cmd_list != NULL, NULL); @@ -686,12 +690,14 @@ static cairo_surface_t *dmenu_get_icon(const Mode *sw, if (dr->icon_name == NULL) { return NULL; } - if (dr->icon_fetch_uid > 0 && dr->icon_fetch_size == height) { + if (dr->icon_fetch_uid > 0 && dr->icon_fetch_size == height && + dr->icon_fetch_scale == scale) { return rofi_icon_fetcher_get(dr->icon_fetch_uid); } uint32_t uid = dr->icon_fetch_uid = - rofi_icon_fetcher_query(dr->icon_name, height); + rofi_icon_fetcher_query(dr->icon_name, height, scale); dr->icon_fetch_size = height; + dr->icon_fetch_scale = scale; return rofi_icon_fetcher_get(uid); } diff --git a/source/modes/drun.c b/source/modes/drun.c index 7d4ae187..b779f3a7 100644 --- a/source/modes/drun.c +++ b/source/modes/drun.c @@ -130,6 +130,7 @@ typedef struct { /* UID for the icon to display */ uint32_t icon_fetch_uid; uint32_t icon_fetch_size; + guint icon_fetch_scale; /* Type of desktop file */ DRunDesktopEntryType type; } DRunModeEntry; @@ -621,6 +622,7 @@ static void read_desktop_file(DRunModePrivateData *pd, const char *root, pd->entry_list[pd->cmd_list_length].icon_size = 0; pd->entry_list[pd->cmd_list_length].icon_fetch_uid = 0; pd->entry_list[pd->cmd_list_length].icon_fetch_size = 0; + pd->entry_list[pd->cmd_list_length].icon_fetch_scale = 0; pd->entry_list[pd->cmd_list_length].root = g_strdup(root); pd->entry_list[pd->cmd_list_length].path = g_strdup(path); pd->entry_list[pd->cmd_list_length].desktop_id = g_strdup(id); @@ -1329,20 +1331,23 @@ static char *_get_display_value(const Mode *sw, unsigned int selected_line, } static cairo_surface_t *_get_icon(const Mode *sw, unsigned int selected_line, - unsigned int height) { + unsigned int height, guint scale) { DRunModePrivateData *pd = (DRunModePrivateData *)mode_get_private_data(sw); if (pd->file_complete) { - return pd->completer->_get_icon(pd->completer, selected_line, height); + return pd->completer->_get_icon(pd->completer, selected_line, height, + scale); } g_return_val_if_fail(pd->entry_list != NULL, NULL); DRunModeEntry *dr = &(pd->entry_list[selected_line]); if (dr->icon_name != NULL) { - if (dr->icon_fetch_uid > 0 && dr->icon_fetch_size == height) { + if (dr->icon_fetch_uid > 0 && dr->icon_fetch_size == height && + dr->icon_fetch_scale == scale) { cairo_surface_t *icon = rofi_icon_fetcher_get(dr->icon_fetch_uid); return icon; } - dr->icon_fetch_uid = rofi_icon_fetcher_query(dr->icon_name, height); + dr->icon_fetch_uid = rofi_icon_fetcher_query(dr->icon_name, height, scale); dr->icon_fetch_size = height; + dr->icon_fetch_scale = scale; cairo_surface_t *icon = rofi_icon_fetcher_get(dr->icon_fetch_uid); return icon; } diff --git a/source/modes/filebrowser.c b/source/modes/filebrowser.c index dc793da6..4a76dcc9 100644 --- a/source/modes/filebrowser.c +++ b/source/modes/filebrowser.c @@ -91,6 +91,7 @@ typedef struct { enum FBFileType type; uint32_t icon_fetch_uid; uint32_t icon_fetch_size; + guint icon_fetch_scale; gboolean link; time_t time; } FBFile; @@ -242,6 +243,7 @@ static void get_file_browser(Mode *sw) { pd->array[pd->array_length].type = UP; pd->array[pd->array_length].icon_fetch_uid = 0; pd->array[pd->array_length].icon_fetch_size = 0; + pd->array[pd->array_length].icon_fetch_scale = 0; pd->array[pd->array_length].link = FALSE; pd->array[pd->array_length].time = -1; pd->array_length++; @@ -274,6 +276,7 @@ static void get_file_browser(Mode *sw) { (rd->d_type == DT_DIR) ? DIRECTORY : RFILE; pd->array[pd->array_length].icon_fetch_uid = 0; pd->array[pd->array_length].icon_fetch_size = 0; + pd->array[pd->array_length].icon_fetch_scale = 0; pd->array[pd->array_length].link = FALSE; if (file_browser_config.sorting_method == FB_SORT_TIME) { @@ -294,6 +297,7 @@ static void get_file_browser(Mode *sw) { g_build_filename(cdir, rd->d_name, NULL); pd->array[pd->array_length].icon_fetch_uid = 0; pd->array[pd->array_length].icon_fetch_size = 0; + pd->array[pd->array_length].icon_fetch_scale = 0; pd->array[pd->array_length].link = TRUE; // Default to file. pd->array[pd->array_length].type = RFILE; @@ -567,20 +571,22 @@ static int file_browser_token_match(const Mode *sw, rofi_int_matcher **tokens, } static cairo_surface_t *_get_icon(const Mode *sw, unsigned int selected_line, - unsigned int height) { + unsigned int height, guint scale) { FileBrowserModePrivateData *pd = (FileBrowserModePrivateData *)mode_get_private_data(sw); g_return_val_if_fail(pd->array != NULL, NULL); FBFile *dr = &(pd->array[selected_line]); - if (dr->icon_fetch_uid > 0 && dr->icon_fetch_size == height) { + if (dr->icon_fetch_uid > 0 && dr->icon_fetch_size == height && + dr->icon_fetch_scale == scale) { return rofi_icon_fetcher_get(dr->icon_fetch_uid); } if (rofi_icon_fetcher_file_is_image(dr->path)) { - dr->icon_fetch_uid = rofi_icon_fetcher_query(dr->path, height); + dr->icon_fetch_uid = rofi_icon_fetcher_query(dr->path, height, scale); } else { - dr->icon_fetch_uid = rofi_icon_fetcher_query(icon_name[dr->type], height); + dr->icon_fetch_uid = rofi_icon_fetcher_query(icon_name[dr->type], height, scale); } dr->icon_fetch_size = height; + dr->icon_fetch_scale = scale; return rofi_icon_fetcher_get(dr->icon_fetch_uid); } diff --git a/source/modes/run.c b/source/modes/run.c index 1393471f..fff2c17d 100644 --- a/source/modes/run.c +++ b/source/modes/run.c @@ -66,6 +66,7 @@ typedef struct { char *entry; uint32_t icon_fetch_uid; uint32_t icon_fetch_size; + guint icon_fetch_scale; /* Surface holding the icon. */ cairo_surface_t *icon; } RunEntry; @@ -534,23 +535,26 @@ static char *run_get_message(const Mode *sw) { return NULL; } static cairo_surface_t *_get_icon(const Mode *sw, unsigned int selected_line, - unsigned int height) { + unsigned int height, guint scale) { RunModePrivateData *pd = (RunModePrivateData *)mode_get_private_data(sw); if (pd->file_complete) { - return pd->completer->_get_icon(pd->completer, selected_line, height); + return pd->completer->_get_icon(pd->completer, selected_line, height, + scale); } g_return_val_if_fail(pd->cmd_list != NULL, NULL); RunEntry *dr = &(pd->cmd_list[selected_line]); - if (dr->icon_fetch_uid > 0 && dr->icon_fetch_size == height) { + if (dr->icon_fetch_uid > 0 && dr->icon_fetch_size == height && + dr->icon_fetch_scale == scale) { cairo_surface_t *icon = rofi_icon_fetcher_get(dr->icon_fetch_uid); return icon; } /** lookup icon */ char **str = g_strsplit(dr->entry, " ", 2); if (str) { - dr->icon_fetch_uid = rofi_icon_fetcher_query(str[0], height); + dr->icon_fetch_uid = rofi_icon_fetcher_query(str[0], height, scale); dr->icon_fetch_size = height; + dr->icon_fetch_scale = scale; g_strfreev(str); cairo_surface_t *icon = rofi_icon_fetcher_get(dr->icon_fetch_uid); return icon; diff --git a/source/modes/script.c b/source/modes/script.c index 5a705c36..3529e734 100644 --- a/source/modes/script.c +++ b/source/modes/script.c @@ -233,6 +233,7 @@ static DmenuScriptEntry *execute_executor(Mode *sw, char *arg, retv[(*length)].info = NULL; retv[(*length)].icon_fetch_uid = 0; retv[(*length)].icon_fetch_size = 0; + retv[(*length)].icon_fetch_scale = 0; retv[(*length)].nonselectable = FALSE; if (buf_length > 0 && (read_length > (ssize_t)buf_length)) { dmenuscript_parse_entry_extras(sw, &(retv[(*length)]), @@ -445,7 +446,7 @@ static char *script_get_message(const Mode *sw) { } static cairo_surface_t *script_get_icon(const Mode *sw, unsigned int selected_line, - unsigned int height) { + unsigned int height, guint scale) { ScriptModePrivateData *pd = (ScriptModePrivateData *)mode_get_private_data(sw); g_return_val_if_fail(pd->cmd_list != NULL, NULL); @@ -453,11 +454,13 @@ static cairo_surface_t *script_get_icon(const Mode *sw, if (dr->icon_name == NULL) { return NULL; } - if (dr->icon_fetch_uid > 0 && dr->icon_fetch_size == height) { + if (dr->icon_fetch_uid > 0 && dr->icon_fetch_size == height && + dr->icon_fetch_scale == scale) { return rofi_icon_fetcher_get(dr->icon_fetch_uid); } - dr->icon_fetch_uid = rofi_icon_fetcher_query(dr->icon_name, height); + dr->icon_fetch_uid = rofi_icon_fetcher_query(dr->icon_name, height, scale); dr->icon_fetch_size = height; + dr->icon_fetch_scale = scale; return rofi_icon_fetcher_get(dr->icon_fetch_uid); } diff --git a/source/modes/wayland-window.c b/source/modes/wayland-window.c index d48ff4a7..fe7177b1 100644 --- a/source/modes/wayland-window.c +++ b/source/modes/wayland-window.c @@ -95,6 +95,7 @@ typedef struct { unsigned int cached_icon_uid; unsigned int cached_icon_size; + guint cached_icon_scale; } ForeignToplevelHandle; static void foreign_toplevel_handle_free(ForeignToplevelHandle *self) { @@ -571,7 +572,7 @@ static char *_get_display_value(const Mode *sw, unsigned int selected_line, } static cairo_surface_t *_get_icon(const Mode *sw, unsigned int selected_line, - unsigned int height) { + unsigned int height, guint scale) { WaylandWindowModePrivateData *pd = (WaylandWindowModePrivateData *)mode_get_private_data(sw); @@ -586,7 +587,8 @@ static cairo_surface_t *_get_icon(const Mode *sw, unsigned int selected_line, return NULL; } - if (toplevel->cached_icon_uid > 0 && toplevel->cached_icon_size == height) { + if (toplevel->cached_icon_uid > 0 && toplevel->cached_icon_size == height && + toplevel->cached_icon_scale == scale) { return rofi_icon_fetcher_get(toplevel->cached_icon_uid); } @@ -597,7 +599,8 @@ static cairo_surface_t *_get_icon(const Mode *sw, unsigned int selected_line, */ gchar *app_id_lower = g_utf8_strdown(toplevel->app_id, -1); toplevel->cached_icon_size = height; - toplevel->cached_icon_uid = rofi_icon_fetcher_query(app_id_lower, height); + toplevel->cached_icon_scale = scale; + toplevel->cached_icon_uid = rofi_icon_fetcher_query(app_id_lower, height, scale); g_free(app_id_lower); return rofi_icon_fetcher_get(toplevel->cached_icon_uid); diff --git a/source/modes/window.c b/source/modes/window.c index 7932eded..b009da9b 100644 --- a/source/modes/window.c +++ b/source/modes/window.c @@ -126,6 +126,7 @@ typedef struct { gboolean icon_checked; uint32_t icon_fetch_uid; uint32_t icon_fetch_size; + guint icon_fetch_scale; gboolean thumbnail_checked; } client; @@ -1043,13 +1044,13 @@ static cairo_surface_t *get_net_wm_icon(xcb_window_t xid, return surface; } static cairo_surface_t *_get_icon(const Mode *sw, unsigned int selected_line, - unsigned int size) { + unsigned int size, guint scale) { WindowModePrivateData *rmpd = mode_get_private_data(sw); client *c = window_client(rmpd, rmpd->ids->array[selected_line]); if (c == NULL) { return NULL; } - if (c->icon_fetch_size != size) { + if (c->icon_fetch_size != size || c->icon_fetch_scale != scale) { if (c->icon) { cairo_surface_destroy(c->icon); c->icon = NULL; @@ -1057,6 +1058,7 @@ static cairo_surface_t *_get_icon(const Mode *sw, unsigned int selected_line, c->thumbnail_checked = FALSE; c->icon_checked = FALSE; } + // TODO: apply scaling to the following two routines if (config.window_thumbnail && c->thumbnail_checked == FALSE) { c->icon = x11_helper_get_screenshot_surface_window(c->window, size); c->thumbnail_checked = TRUE; @@ -1066,16 +1068,19 @@ static cairo_surface_t *_get_icon(const Mode *sw, unsigned int selected_line, c->icon_checked = TRUE; } if (c->icon == NULL && c->class) { - if (c->icon_fetch_uid > 0) { + if (c->icon_fetch_uid > 0 && c->icon_fetch_size == size && + c->icon_fetch_scale == scale) { return rofi_icon_fetcher_get(c->icon_fetch_uid); } char *class_lower = g_utf8_strdown(c->class, -1); - c->icon_fetch_uid = rofi_icon_fetcher_query(class_lower, size); + c->icon_fetch_uid = rofi_icon_fetcher_query(class_lower, size, scale); g_free(class_lower); c->icon_fetch_size = size; + c->icon_fetch_scale = scale; return rofi_icon_fetcher_get(c->icon_fetch_uid); } c->icon_fetch_size = size; + c->icon_fetch_scale = scale; return c->icon; } diff --git a/source/rofi-icon-fetcher.c b/source/rofi-icon-fetcher.c index fd9fd25b..456119d8 100644 --- a/source/rofi-icon-fetcher.c +++ b/source/rofi-icon-fetcher.c @@ -38,6 +38,7 @@ #include #include +#include "display.h" #include "keyb.h" #include "view.h" @@ -78,6 +79,7 @@ typedef struct { uint32_t uid; int wsize; int hsize; + guint scale; cairo_surface_t *surface; IconFetcherNameEntry *entry; @@ -321,7 +323,7 @@ static void rofi_icon_fetcher_worker(thread_state *sdata, } else { icon_path = icon_path_ = nk_xdg_theme_get_icon( rofi_icon_fetcher_data->xdg_context, themes, NULL, sentry->entry->name, - MIN(sentry->wsize, sentry->hsize), 1, TRUE); + MIN(sentry->wsize, sentry->hsize), sentry->scale, TRUE); if (icon_path_ == NULL) { g_debug("failed to get icon %s(%dx%d): n/a", sentry->entry->name, sentry->wsize, sentry->hsize); @@ -345,9 +347,15 @@ static void rofi_icon_fetcher_worker(thread_state *sdata, return; } + int width = sentry->wsize, height = sentry->hsize; + if (width > 0) + width *= sentry->scale; + if (height > 0) + height *= sentry->scale; + GError *error = NULL; - GdkPixbuf *pb = gdk_pixbuf_new_from_file_at_scale( - icon_path, sentry->wsize, sentry->hsize, TRUE, &error); + GdkPixbuf *pb = + gdk_pixbuf_new_from_file_at_scale(icon_path, width, height, TRUE, &error); if (error != NULL) { g_warning("Failed to load image: %s", error->message); g_error_free(error); @@ -365,7 +373,7 @@ static void rofi_icon_fetcher_worker(thread_state *sdata, } uint32_t rofi_icon_fetcher_query_advanced(const char *name, const int wsize, - const int hsize) { + const int hsize, const guint scale) { g_debug("Query: %s(%dx%d)", name, wsize, hsize); IconFetcherNameEntry *entry = g_hash_table_lookup(rofi_icon_fetcher_data->icon_cache, name); @@ -378,7 +386,8 @@ uint32_t rofi_icon_fetcher_query_advanced(const char *name, const int wsize, for (GList *iter = g_list_first(entry->sizes); iter; iter = g_list_next(iter)) { sentry = iter->data; - if (sentry->wsize == wsize && sentry->hsize == hsize) { + if (sentry->wsize == wsize && sentry->hsize == hsize && + sentry->scale == scale) { return sentry->uid; } } @@ -388,6 +397,7 @@ uint32_t rofi_icon_fetcher_query_advanced(const char *name, const int wsize, sentry->uid = ++(rofi_icon_fetcher_data->last_uid); sentry->wsize = wsize; sentry->hsize = hsize; + sentry->scale = scale; sentry->entry = entry; sentry->surface = NULL; @@ -401,7 +411,8 @@ uint32_t rofi_icon_fetcher_query_advanced(const char *name, const int wsize, return sentry->uid; } -uint32_t rofi_icon_fetcher_query(const char *name, const int size) { +uint32_t rofi_icon_fetcher_query(const char *name, const int size, + const guint scale) { g_debug("Query: %s(%d)", name, size); IconFetcherNameEntry *entry = g_hash_table_lookup(rofi_icon_fetcher_data->icon_cache, name); @@ -414,7 +425,8 @@ uint32_t rofi_icon_fetcher_query(const char *name, const int size) { for (GList *iter = g_list_first(entry->sizes); iter; iter = g_list_next(iter)) { sentry = iter->data; - if (sentry->wsize == size && sentry->hsize == size) { + if (sentry->wsize == size && sentry->hsize == size && + sentry->scale == scale) { return sentry->uid; } } @@ -424,6 +436,7 @@ uint32_t rofi_icon_fetcher_query(const char *name, const int size) { sentry->uid = ++(rofi_icon_fetcher_data->last_uid); sentry->wsize = size; sentry->hsize = size; + sentry->scale = scale; sentry->entry = entry; sentry->surface = NULL; diff --git a/source/rofi.c b/source/rofi.c index 6475db00..9eb633f0 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -1166,6 +1166,7 @@ int main(int argc, char *argv[]) { } TICK_N("Setup late Display"); + rofi_theme_set_disp_scale_func(display_scale); rofi_theme_parse_process_conditionals(); rofi_theme_parse_process_links(); TICK_N("Theme setup"); diff --git a/source/theme.c b/source/theme.c index 778e523c..f656911d 100644 --- a/source/theme.c +++ b/source/theme.c @@ -48,6 +48,7 @@ #include GList *parsed_config_files = NULL; +static disp_scale_func disp_scale = NULL; void rofi_theme_free_parsed_files(void) { g_list_free_full(parsed_config_files, g_free); @@ -1074,6 +1075,7 @@ void rofi_theme_get_color(const widget *widget, const char *property, static gboolean rofi_theme_get_image_inside(Property *p, const widget *widget, const char *property, cairo_t *d) { + const guint scale = disp_scale ? disp_scale() : 1; if (p) { if (p->type == P_INHERIT) { if (widget->parent) { @@ -1104,16 +1106,18 @@ static gboolean rofi_theme_get_image_inside(Property *p, const widget *widget, break; } if (p->value.image.surface_id == 0 || p->value.image.wsize != wsize || - p->value.image.hsize != hsize) { - p->value.image.surface_id = - rofi_icon_fetcher_query_advanced(p->value.image.url, wsize, hsize); + p->value.image.hsize != hsize || p->value.image.scale != scale) { + p->value.image.surface_id = rofi_icon_fetcher_query_advanced( + p->value.image.url, wsize, hsize, scale); p->value.image.wsize = wsize; p->value.image.hsize = hsize; + p->value.image.scale = scale; } cairo_surface_t *img = rofi_icon_fetcher_get(p->value.image.surface_id); if (img != NULL) { cairo_pattern_t *pat = cairo_pattern_create_for_surface(img); + cairo_surface_set_device_scale(img, scale, scale); cairo_pattern_set_extend(pat, CAIRO_EXTEND_REPEAT); cairo_set_source(d, pat); cairo_pattern_destroy(pat); @@ -1674,3 +1678,7 @@ gboolean rofi_theme_has_property(const widget *widget, const char *property) { Property *p = rofi_theme_find_property(wid, P_STRING, property, FALSE); return rofi_theme_has_property_inside(p, widget, property); } + +void rofi_theme_set_disp_scale_func(disp_scale_func func) { + disp_scale = func; +} diff --git a/source/view.c b/source/view.c index 627ab52d..c75326b3 100644 --- a/source/view.c +++ b/source/view.c @@ -476,8 +476,8 @@ static void selection_changed_callback(G_GNUC_UNUSED listview *lv, int icon_height = widget_get_desired_height(WIDGET(state->icon_current_entry), WIDGET(state->icon_current_entry)->w); - cairo_surface_t *icon = - mode_get_icon(state->sw, state->line_map[index], icon_height); + cairo_surface_t *icon = mode_get_icon(state->sw, state->line_map[index], + icon_height, display_scale()); icon_set_surface(state->icon_current_entry, icon); } else { icon_set_surface(state->icon_current_entry, NULL); @@ -496,8 +496,8 @@ static void update_callback(textbox *t, icon *ico, unsigned int index, if (ico) { int icon_height = widget_get_desired_height(WIDGET(ico), WIDGET(ico)->w); - cairo_surface_t *icon = - mode_get_icon(state->sw, state->line_map[index], icon_height); + cairo_surface_t *icon = mode_get_icon(state->sw, state->line_map[index], + icon_height, display_scale()); icon_set_surface(ico, icon); } if (t) { diff --git a/source/widgets/icon.c b/source/widgets/icon.c index a669d220..240263e9 100644 --- a/source/widgets/icon.c +++ b/source/widgets/icon.c @@ -28,6 +28,7 @@ /** The log domain of this widget. */ #define G_LOG_DOMAIN "Widgets.Icon" +#include "display.h" #include "widgets/icon.h" #include "theme.h" #include "widgets/widget-internal.h" @@ -169,7 +170,7 @@ icon *icon_create(widget *parent, const char *name) { const char *filename = rofi_theme_get_string(WIDGET(b), "filename", NULL); if (filename) { - b->icon_fetch_id = rofi_icon_fetcher_query(filename, b->size); + b->icon_fetch_id = rofi_icon_fetcher_query(filename, b->size, display_scale()); } b->yalign = rofi_theme_get_double(WIDGET(b), "vertical-align", 0.5); b->yalign = MAX(0, MIN(1.0, b->yalign)); diff --git a/source/xcb/display.c b/source/xcb/display.c index 7161932c..5db4bead 100644 --- a/source/xcb/display.c +++ b/source/xcb/display.c @@ -1895,6 +1895,8 @@ static void xcb_display_revert_input_focus(void) { xcb_flush(xcb->connection); } +static guint xcb_display_scale(void) { return 1; } + static const struct _view_proxy *xcb_display_view_proxy(void) { return xcb_view_proxy; } @@ -1909,6 +1911,7 @@ static display_proxy display_ = { .monitor_active = xcb_display_monitor_active, .set_input_focus = xcb_display_set_input_focus, .revert_input_focus = xcb_display_revert_input_focus, + .scale = xcb_display_scale, .view = xcb_display_view_proxy, }; diff --git a/test/box-test.c b/test/box-test.c index 6463a2cc..8e642e97 100644 --- a/test/box-test.c +++ b/test/box-test.c @@ -72,12 +72,14 @@ unsigned int test = 0; ThemeWidget *rofi_configuration = NULL; uint32_t rofi_icon_fetcher_query(G_GNUC_UNUSED const char *name, - G_GNUC_UNUSED const int size) { + G_GNUC_UNUSED const int size, + G_GNUC_UNUSED const guint scale) { return 0; } uint32_t rofi_icon_fetcher_query_advanced(G_GNUC_UNUSED const char *name, G_GNUC_UNUSED const int wsize, - G_GNUC_UNUSED const int hsize) { + G_GNUC_UNUSED const int hsize, + G_GNUC_UNUSED const guint scale) { return 0; } diff --git a/test/helper-config-cmdline-parser.c b/test/helper-config-cmdline-parser.c index c5f10af0..028e9291 100644 --- a/test/helper-config-cmdline-parser.c +++ b/test/helper-config-cmdline-parser.c @@ -57,12 +57,14 @@ static int test = 0; #include "theme.h" ThemeWidget *rofi_theme = NULL; uint32_t rofi_icon_fetcher_query(G_GNUC_UNUSED const char *name, - G_GNUC_UNUSED const int size) { + G_GNUC_UNUSED const int size, + G_GNUC_UNUSED const guint scale) { return 0; } uint32_t rofi_icon_fetcher_query_advanced(G_GNUC_UNUSED const char *name, G_GNUC_UNUSED const int wsize, - G_GNUC_UNUSED const int hsize) { + G_GNUC_UNUSED const int hsize, + G_GNUC_UNUSED const guint scale) { return 0; } diff --git a/test/helper-expand.c b/test/helper-expand.c index 01602f58..aa708f5d 100644 --- a/test/helper-expand.c +++ b/test/helper-expand.c @@ -59,12 +59,14 @@ ThemeWidget *rofi_theme = NULL; void rofi_clear_error_messages(void) {} void rofi_clear_warning_messages(void) {} uint32_t rofi_icon_fetcher_query(G_GNUC_UNUSED const char *name, - G_GNUC_UNUSED const int size) { + G_GNUC_UNUSED const int size, + G_GNUC_UNUSED const guint scale) { return 0; } uint32_t rofi_icon_fetcher_query_advanced(G_GNUC_UNUSED const char *name, G_GNUC_UNUSED const int wsize, - G_GNUC_UNUSED const int hsize) { + G_GNUC_UNUSED const int hsize, + G_GNUC_UNUSED const guint scale) { return 0; } diff --git a/test/helper-pidfile.c b/test/helper-pidfile.c index b7a397ec..e2a3dc57 100644 --- a/test/helper-pidfile.c +++ b/test/helper-pidfile.c @@ -48,12 +48,14 @@ static int test = 0; ThemeWidget *rofi_theme = NULL; uint32_t rofi_icon_fetcher_query(G_GNUC_UNUSED const char *name, - G_GNUC_UNUSED const int size) { + G_GNUC_UNUSED const int size, + G_GNUC_UNUSED const guint scale) { return 0; } uint32_t rofi_icon_fetcher_query_advanced(G_GNUC_UNUSED const char *name, G_GNUC_UNUSED const int wsize, - G_GNUC_UNUSED const int hsize) { + G_GNUC_UNUSED const int hsize, + G_GNUC_UNUSED const guint scale) { return 0; } diff --git a/test/helper-test.c b/test/helper-test.c index 003f4ebc..8dd45cbb 100644 --- a/test/helper-test.c +++ b/test/helper-test.c @@ -73,14 +73,16 @@ gboolean rofi_theme_parse_string(G_GNUC_UNUSED const char *string) { } uint32_t rofi_icon_fetcher_query(G_GNUC_UNUSED const char *name, - G_GNUC_UNUSED const int size) { + G_GNUC_UNUSED const int size, + G_GNUC_UNUSED const guint scale) { return 0; } void rofi_clear_error_messages(void) {} void rofi_clear_warning_messages(void) {} uint32_t rofi_icon_fetcher_query_advanced(G_GNUC_UNUSED const char *name, G_GNUC_UNUSED const int wsize, - G_GNUC_UNUSED const int hsize) { + G_GNUC_UNUSED const int hsize, + G_GNUC_UNUSED const guint scale) { return 0; } diff --git a/test/helper-tokenize.c b/test/helper-tokenize.c index b26f2b6c..6ce59b6a 100644 --- a/test/helper-tokenize.c +++ b/test/helper-tokenize.c @@ -45,12 +45,14 @@ ThemeWidget *rofi_theme = NULL; uint32_t rofi_icon_fetcher_query(G_GNUC_UNUSED const char *name, - G_GNUC_UNUSED const int size) { + G_GNUC_UNUSED const int size, + G_GNUC_UNUSED const guint scale) { return 0; } uint32_t rofi_icon_fetcher_query_advanced(G_GNUC_UNUSED const char *name, G_GNUC_UNUSED const int wsize, - G_GNUC_UNUSED const int hsize) { + G_GNUC_UNUSED const int hsize, + G_GNUC_UNUSED const guint scale) { return 0; } void rofi_clear_error_messages(void) {} diff --git a/test/mode-test.c b/test/mode-test.c index f9e3b946..14cdc42e 100644 --- a/test/mode-test.c +++ b/test/mode-test.c @@ -50,12 +50,14 @@ ThemeWidget *rofi_theme = NULL; uint32_t rofi_icon_fetcher_query(G_GNUC_UNUSED const char *name, - G_GNUC_UNUSED const int size) { + G_GNUC_UNUSED const int size, + G_GNUC_UNUSED const guint scale) { return 0; } uint32_t rofi_icon_fetcher_query_advanced(G_GNUC_UNUSED const char *name, G_GNUC_UNUSED const int wsize, - G_GNUC_UNUSED const int hsize) { + G_GNUC_UNUSED const int hsize, + G_GNUC_UNUSED const guint scale) { return 0; } void rofi_clear_error_messages(void) {} diff --git a/test/scrollbar-test.c b/test/scrollbar-test.c index 33a3e85b..46a9aabe 100644 --- a/test/scrollbar-test.c +++ b/test/scrollbar-test.c @@ -63,12 +63,14 @@ unsigned int test = 0; ThemeWidget *rofi_configuration = NULL; uint32_t rofi_icon_fetcher_query(G_GNUC_UNUSED const char *name, - G_GNUC_UNUSED const int size) { + G_GNUC_UNUSED const int size, + G_GNUC_UNUSED const guint scale) { return 0; } uint32_t rofi_icon_fetcher_query_advanced(G_GNUC_UNUSED const char *name, G_GNUC_UNUSED const int wsize, - G_GNUC_UNUSED const int hsize) { + G_GNUC_UNUSED const int hsize, + G_GNUC_UNUSED const guint scale) { return 0; } diff --git a/test/textbox-test.c b/test/textbox-test.c index 92fc2600..9ad0d33a 100644 --- a/test/textbox-test.c +++ b/test/textbox-test.c @@ -60,12 +60,14 @@ unsigned int normal_window_mode = 0; ThemeWidget *rofi_configuration = NULL; uint32_t rofi_icon_fetcher_query(G_GNUC_UNUSED const char *name, - G_GNUC_UNUSED const int size) { + G_GNUC_UNUSED const int size, + G_GNUC_UNUSED const guint scale) { return 0; } uint32_t rofi_icon_fetcher_query_advanced(G_GNUC_UNUSED const char *name, G_GNUC_UNUSED const int wsize, - G_GNUC_UNUSED const int hsize) { + G_GNUC_UNUSED const int hsize, + G_GNUC_UNUSED const guint scale) { return 0; } diff --git a/test/theme-parser-test.c b/test/theme-parser-test.c index e1d571c6..ab845357 100644 --- a/test/theme-parser-test.c +++ b/test/theme-parser-test.c @@ -45,15 +45,16 @@ #define REAL_COMPARE_DELTA 0.001 uint32_t rofi_icon_fetcher_query(G_GNUC_UNUSED const char *name, - G_GNUC_UNUSED const int size) { + G_GNUC_UNUSED const int size, + G_GNUC_UNUSED const guint scale) { return 0; } void rofi_clear_error_messages(void) {} void rofi_clear_warning_messages(void) {} -uint32_t -rofi_icon_fetcher_query_advanced(G_GNUC_UNUSED const char *name, - G_GNUC_UNUSED G_GNUC_UNUSED const int wsize, - G_GNUC_UNUSED const int hsize) { +uint32_t rofi_icon_fetcher_query_advanced(G_GNUC_UNUSED const char *name, + G_GNUC_UNUSED const int wsize, + G_GNUC_UNUSED const int hsize, + G_GNUC_UNUSED const guint scale) { return 0; } diff --git a/test/widget-test.c b/test/widget-test.c index 69f32132..30a7951f 100644 --- a/test/widget-test.c +++ b/test/widget-test.c @@ -49,12 +49,14 @@ unsigned int test = 0; ThemeWidget *rofi_configuration = NULL; uint32_t rofi_icon_fetcher_query(G_GNUC_UNUSED const char *name, - G_GNUC_UNUSED const int size) { + G_GNUC_UNUSED const int size, + G_GNUC_UNUSED const guint scale) { return 0; } uint32_t rofi_icon_fetcher_query_advanced(G_GNUC_UNUSED const char *name, G_GNUC_UNUSED const int wsize, - G_GNUC_UNUSED const int hsize) { + G_GNUC_UNUSED const int hsize, + G_GNUC_UNUSED const guint scale) { return 0; }