mirror of
https://github.com/swaywm/sway.git
synced 2026-04-16 08:21:30 -04:00
Extends former behavior to include loading of icons if they are
specified as an absolute path. Fixes size selection for SVG (scalable) icons relying on whose nominal size read via gdk-pixbuf loader may not correctly indicate that they can be scaled to neatly fill the available scale e.g., symbolic icons from Adwaita specify a nominal size of 16x16.
This commit is contained in:
parent
478c77a69b
commit
c8cc27c49e
4 changed files with 50 additions and 23 deletions
|
|
@ -1,3 +1,4 @@
|
|||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <sfdo-basedir.h>
|
||||
#include <sfdo-desktop.h>
|
||||
|
|
@ -6,16 +7,24 @@
|
|||
#include "log.h"
|
||||
#include "sfdo.h"
|
||||
|
||||
// this extends libsfdo's behavior to also handle icons specified as absolute paths
|
||||
char *sfdo_icon_lookup_extended(struct sfdo *sfdo, char *icon_name, int target_size, int scale) {
|
||||
int lookup_options = SFDO_ICON_THEME_LOOKUP_OPTIONS_DEFAULT;
|
||||
struct sfdo_icon_file *icon_file = \
|
||||
sfdo_icon_theme_lookup(sfdo->icon_theme, icon_name, SFDO_NT, \
|
||||
target_size, scale, lookup_options);
|
||||
char *icon_path = NULL;
|
||||
if (icon_file && icon_file != SFDO_ICON_FILE_INVALID) {
|
||||
icon_path = strdup(sfdo_icon_file_get_path(icon_file, NULL));
|
||||
if (icon_name[0] == '/') {
|
||||
struct stat sb;
|
||||
if (!stat(icon_name, &sb)) {
|
||||
icon_path = strdup(icon_name);
|
||||
}
|
||||
} else {
|
||||
int lookup_options = SFDO_ICON_THEME_LOOKUP_OPTIONS_DEFAULT;
|
||||
struct sfdo_icon_file *icon_file = \
|
||||
sfdo_icon_theme_lookup(sfdo->icon_theme, icon_name, SFDO_NT, \
|
||||
target_size, scale, lookup_options);
|
||||
if (icon_file && icon_file != SFDO_ICON_FILE_INVALID) {
|
||||
icon_path = strdup(sfdo_icon_file_get_path(icon_file, NULL));
|
||||
}
|
||||
sfdo_icon_file_destroy(icon_file);
|
||||
}
|
||||
sfdo_icon_file_destroy(icon_file);
|
||||
return icon_path;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,6 @@
|
|||
#define _SWAYBAR_IMAGE_H
|
||||
#include <cairo.h>
|
||||
|
||||
cairo_surface_t *load_image(const char *path);
|
||||
cairo_surface_t *load_image(const char *path, int target_size, int scale);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -104,11 +104,27 @@ static cairo_surface_t* gdk_cairo_image_surface_create_from_pixbuf(
|
|||
}
|
||||
#endif // HAVE_GDK_PIXBUF
|
||||
|
||||
cairo_surface_t *load_image(const char *path) {
|
||||
cairo_surface_t *load_image(const char *path, int target_size, int scale) {
|
||||
cairo_surface_t *image;
|
||||
#if HAVE_GDK_PIXBUF
|
||||
GError *err = NULL;
|
||||
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(path, &err);
|
||||
GdkPixbuf *pixbuf = NULL;
|
||||
// svg images should be loaded at target size. the size read from an svg
|
||||
// file is only nominal and can lead to an image too small for the avaialble
|
||||
// space compared to bitmap icons selected at the nearest available size
|
||||
int i = strlen(path) - 1;
|
||||
// this is naive and assumes ascii, utf-8, or another encoding
|
||||
// that encodes these letters as single bytes
|
||||
if ((i > 2) &&
|
||||
(path[i] == 'g' || path[i] == 'G') && \
|
||||
(path[i - 1] == 'v' || path[i - 1] == 'V') && \
|
||||
(path[i - 2] == 's' || path[i - 2] == 'S') && \
|
||||
(path[i - 3] == '.' )) {
|
||||
pixbuf = gdk_pixbuf_new_from_file_at_scale(path, -1, target_size, \
|
||||
true, &err);
|
||||
} else {
|
||||
pixbuf = gdk_pixbuf_new_from_file(path, &err);
|
||||
}
|
||||
if (!pixbuf) {
|
||||
sway_log(SWAY_ERROR, "Failed to load background image (%s).",
|
||||
err->message);
|
||||
|
|
|
|||
|
|
@ -421,8 +421,7 @@ static enum hotspot_event_handling icon_hotspot_callback(
|
|||
return HOTSPOT_PROCESS;
|
||||
}
|
||||
|
||||
static void reload_sni(struct swaybar_sni *sni, char *icon_theme,
|
||||
int target_size) {
|
||||
static void reload_sni(struct swaybar_sni *sni, char *icon_theme, int target_size) {
|
||||
char *icon_name = sni->status[0] == 'N' ?
|
||||
sni->attention_icon_name : sni->icon_name;
|
||||
if (icon_name) {
|
||||
|
|
@ -437,20 +436,15 @@ static void reload_sni(struct swaybar_sni *sni, char *icon_theme,
|
|||
icon_name, target_size, icon_theme,
|
||||
&sni->min_size, &sni->max_size);
|
||||
#else
|
||||
// TODO: at some point we will need to make this scaling-aware
|
||||
int scale = 1;
|
||||
struct sfdo *sfdo = sni->tray->bar->config->sfdo;
|
||||
if (sfdo) {
|
||||
int lookup_options = SFDO_ICON_THEME_LOOKUP_OPTIONS_DEFAULT;
|
||||
int scale = 1;
|
||||
struct sfdo_icon_file *icon_file = \
|
||||
sfdo_icon_theme_lookup(sfdo->icon_theme, icon_name, SFDO_NT, \
|
||||
target_size, scale, lookup_options);
|
||||
if (!icon_file || icon_file == SFDO_ICON_FILE_INVALID) {
|
||||
sway_log(SWAY_ERROR, "sfdo: icon %s invalid or not found in theme %s at size %d", \
|
||||
icon_path = sfdo_icon_lookup_extended(sfdo, icon_name, target_size, scale);
|
||||
if (!icon_path) {
|
||||
sway_log(SWAY_DEBUG, "sfdo: icon %s invalid or not found in theme %s at size %d", \
|
||||
icon_name, icon_theme, target_size);
|
||||
} else {
|
||||
icon_path = strdup(sfdo_icon_file_get_path(icon_file, NULL));
|
||||
}
|
||||
sfdo_icon_file_destroy(icon_file);
|
||||
}
|
||||
#endif
|
||||
#if !HAVE_LIBSFDO
|
||||
|
|
@ -458,9 +452,17 @@ static void reload_sni(struct swaybar_sni *sni, char *icon_theme,
|
|||
#endif
|
||||
if (icon_path) {
|
||||
cairo_surface_destroy(sni->icon);
|
||||
sni->icon = load_image(icon_path);
|
||||
sni->icon = load_image(icon_path, target_size, scale);
|
||||
free(icon_path);
|
||||
return;
|
||||
} else {
|
||||
// the :( icon won't be drawn for a missing icon and whichever old icon was
|
||||
// loaded will persist if this is not done. one might not have noticed this
|
||||
// for tray items that have only one icon loaded only once, successfully or
|
||||
// unsuccessfully. items with multiple icons, such as fcitx5 or other input
|
||||
// method frameworks make the problem apparent
|
||||
free(sni->icon);
|
||||
sni->icon = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue