]> git.mdlowis.com Git - proto/labwc.git/commitdiff
icon-loader: load SVG icons at max scale of any usable output
authorJohn Lindgren <john@jlindgren.net>
Mon, 7 Oct 2024 01:24:34 +0000 (21:24 -0400)
committerJohn Lindgren <john@jlindgren.net>
Mon, 7 Oct 2024 01:24:34 +0000 (21:24 -0400)
- Add a new function to get the maximum scale of all usable outputs
- Pass the maximum output scale through to img_svg_load(), which
  ultimately calls cairo_surface_set_device_scale() before rendering

include/icon-loader.h
include/img/img-svg.h
include/labwc.h
src/icon-loader.c
src/img/img-svg.c
src/output.c
src/ssd/ssd-titlebar.c
src/theme.c

index e6741ddb5842e6a65188a162f1df4b9cb5f5ce35..846d20a2a21b28740185483ea68831f2b0ba216a 100644 (file)
@@ -7,6 +7,6 @@ struct server;
 void icon_loader_init(struct server *server);
 void icon_loader_finish(struct server *server);
 struct lab_data_buffer *icon_loader_lookup(struct server *server,
-       const char *app_id, int size, int scale);
+       const char *app_id, int size, float scale);
 
 #endif /* LABWC_ICON_LOADER_H */
index 6843774d0337303f90ea73d70dded0846b693d97..c8acc71c54d0a15429cbb81a5eaa9cc16b8b2071 100644 (file)
@@ -5,6 +5,6 @@
 struct lab_data_buffer;
 
 void img_svg_load(const char *filename, struct lab_data_buffer **buffer,
-       int size);
+       int size, float scale);
 
 #endif /* LABWC_IMG_SVG_H */
index ce593e12a3b00521cd54c2097fa2e5310fd37514..0a6c3a1744d2342e7cf283f55556c6159a65142c 100644 (file)
@@ -546,6 +546,14 @@ struct wlr_box output_usable_area_scaled(struct output *output);
 void handle_output_power_manager_set_mode(struct wl_listener *listener,
        void *data);
 void output_enable_adaptive_sync(struct wlr_output *output, bool enabled);
+
+/**
+ * output_max_scale() - get maximum scale factor of all usable outputs.
+ * Used when loading/rendering resources (e.g. icons) that may be
+ * displayed on any output.
+ */
+float output_max_scale(struct server *server);
+
 void new_tearing_hint(struct wl_listener *listener, void *data);
 
 void server_init(struct server *server);
index 60f82029004a2d963154e86086e691623ab86271..b824f5d53a0523afa2a052f141fd2d1f936d5160 100644 (file)
@@ -5,6 +5,7 @@
 #include <string.h>
 #include <strings.h>
 #include <wlr/util/log.h>
+#include "common/macros.h"
 #include "common/mem.h"
 #include "common/string-helpers.h"
 #include "config.h"
@@ -219,7 +220,8 @@ get_db_entry_by_id_fuzzy(struct sfdo_desktop_db *db, const char *app_id)
 }
 
 struct lab_data_buffer *
-icon_loader_lookup(struct server *server, const char *app_id, int size, int scale)
+icon_loader_lookup(struct server *server, const char *app_id, int size,
+               float scale)
 {
        struct icon_loader *loader = server->icon_loader;
        if (!loader) {
@@ -236,16 +238,23 @@ icon_loader_lookup(struct server *server, const char *app_id, int size, int scal
                icon_name = sfdo_desktop_entry_get_icon(entry, NULL);
        }
 
+       /*
+        * libsfdo doesn't support loading icons for fractional scales,
+        * so round down and increase the icon size to compensate.
+        */
+       int lookup_scale = MAX((int)scale, 1);
+       int lookup_size = lroundf(size * scale / lookup_scale);
+
        struct icon_ctx ctx = {0};
        int ret;
        if (!icon_name) {
                /* fall back to app id */
-               ret = process_rel_name(&ctx, app_id, loader, size, scale);
+               ret = process_rel_name(&ctx, app_id, loader, lookup_size, lookup_scale);
        } else if (icon_name[0] == '/') {
                ret = process_abs_name(&ctx, icon_name);
        } else {
                /* this should be the case for most icons */
-               ret = process_rel_name(&ctx, icon_name, loader, size, scale);
+               ret = process_rel_name(&ctx, icon_name, loader, lookup_size, lookup_scale);
        }
        if (ret < 0) {
                return NULL;
@@ -261,7 +270,7 @@ icon_loader_lookup(struct server *server, const char *app_id, int size, int scal
                break;
        case SFDO_ICON_FILE_FORMAT_SVG:
 #if HAVE_RSVG
-               img_svg_load(ctx.path, &icon_buffer, size * scale);
+               img_svg_load(ctx.path, &icon_buffer, size, scale);
 #endif
                break;
        case SFDO_ICON_FILE_FORMAT_XPM:
index 498c1bd0932fc2cdd67ed07ac48aeed10dc0cb64..baab5faabc1f2afd2065457398ef5d9850982061 100644 (file)
@@ -15,8 +15,8 @@
 #include "labwc.h"
 
 void
-img_svg_load(const char *filename, struct lab_data_buffer **buffer,
-               int size)
+img_svg_load(const char *filename, struct lab_data_buffer **buffer, int size,
+               float scale)
 {
        if (*buffer) {
                wlr_buffer_drop(&(*buffer)->base);
@@ -39,7 +39,7 @@ img_svg_load(const char *filename, struct lab_data_buffer **buffer,
                return;
        }
 
-       *buffer = buffer_create_cairo(size, size, 1.0);
+       *buffer = buffer_create_cairo(size, size, scale);
        cairo_surface_t *image = (*buffer)->surface;
        cairo_t *cr = (*buffer)->cairo;
 
index e0cb3ae8bc3fac4e43ed25ea3a5dbdc22079754d..58743e31d8dec5ae2ea31b102572d0153ad8f033 100644 (file)
@@ -1067,3 +1067,17 @@ output_enable_adaptive_sync(struct wlr_output *output, bool enabled)
                        enabled ? "en" : "dis", output->name);
        }
 }
+
+float
+output_max_scale(struct server *server)
+{
+       /* Never return less than 1, in case outputs are disabled */
+       float scale = 1;
+       struct output *output;
+       wl_list_for_each(output, &server->outputs, link) {
+               if (output_is_usable(output)) {
+                       scale = MAX(scale, output->wlr_output->scale);
+               }
+       }
+       return scale;
+}
index ca5a8dde25536175ff69b4ea46becadf8f7f3614..530b92103e0e4759d9c300359ce0ff2e37ce98b3 100644 (file)
@@ -604,8 +604,16 @@ ssd_update_window_icon(struct ssd *ssd)
        int hpad = theme->window_button_width / 10;
        int icon_size = MIN(theme->window_button_width - 2 * hpad,
                theme->title_height - 2 * theme->padding_height);
-       /* TODO: take into account output scales */
-       int icon_scale = 1;
+
+       /*
+        * Load/render icons at the max scale of any usable output (at
+        * this point in time). We don't want to be constantly reloading
+        * icons as views are moved between outputs.
+        *
+        * TODO: currently there's no signal to reload/render icons if
+        * outputs are reconfigured and the max scale changes.
+        */
+       float icon_scale = output_max_scale(ssd->view->server);
 
        struct lab_data_buffer *icon_buffer = icon_loader_lookup(
                ssd->view->server, app_id, icon_size, icon_scale);
index 886ffa15fe577af994fa4172bc0f97eb60f4d2df..32bcfa2364c0a10b8d1276261f96a5218fddac34 100644 (file)
@@ -257,7 +257,8 @@ load_button(struct theme *theme, struct button *b, int active)
                int size = theme->title_height - 2 * theme->padding_height;
                get_button_filename(filename, sizeof(filename), b->name,
                        active ? "-active.svg" : "-inactive.svg");
-               img_svg_load(filename, buffer, size);
+               /* TODO: account for output scale */
+               img_svg_load(filename, buffer, size, 1);
        }
 #endif