Skip to content

Commit

Permalink
Convert applet icons from pixbuf to surfaces
Browse files Browse the repository at this point in the history
This improves support for HiDPI by loading properly scaled surfaces for applets.
  • Loading branch information
vkareh authored and raveit65 committed May 12, 2018
1 parent e83811d commit 311ae4e
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 135 deletions.
1 change: 1 addition & 0 deletions battstat/battstat_applet.c
Expand Up @@ -214,6 +214,7 @@ static GdkColor darkred[] = {
their XPM format (as stored in pixmaps.h). This should only be done once
since they are global variables.
*/
/* FIXME: We should be using named icons here... */
static void
initialise_global_pixmaps( void )
{
Expand Down
24 changes: 16 additions & 8 deletions cpufreq/src/cpufreq-applet.c
Expand Up @@ -62,7 +62,7 @@ struct _CPUFreqApplet {
GtkWidget *box;
GtkWidget *labels_box;
GtkWidget *container;
GdkPixbuf *pixbufs[5];
cairo_surface_t *surfaces[5];

gint max_label_width;
gint max_perc_width;
Expand Down Expand Up @@ -245,9 +245,9 @@ cpufreq_applet_dispose (GObject *widget)
}

for (i = 0; i <= 3; i++) {
if (applet->pixbufs[i]) {
g_object_unref (G_OBJECT (applet->pixbufs[i]));
applet->pixbufs[i] = NULL;
if (applet->surfaces[i]) {
cairo_surface_destroy (applet->surfaces[i]);
applet->surfaces[i] = NULL;
}
}

Expand Down Expand Up @@ -646,6 +646,8 @@ static void
cpufreq_applet_pixmap_set_image (CPUFreqApplet *applet, gint perc)
{
gint image;
gint scale;
gint size = 24; /* FIXME */

/* 0-29 -> 25%
* 30-69 -> 50%
Expand All @@ -663,12 +665,18 @@ cpufreq_applet_pixmap_set_image (CPUFreqApplet *applet, gint perc)
else
image = 4;

if (applet->pixbufs[image] == NULL) {
applet->pixbufs[image] = gdk_pixbuf_new_from_file_at_size (cpufreq_icons[image],
24, 24, NULL);
scale = gtk_widget_get_scale_factor (GTK_WIDGET (applet->icon));

if (applet->surfaces[image] == NULL) {
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_scale (cpufreq_icons[image],
size * scale,
size * scale,
TRUE,
NULL);
applet->surfaces[image] = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, NULL);
}

gtk_image_set_from_pixbuf (GTK_IMAGE (applet->icon), applet->pixbufs[image]);
gtk_image_set_from_surface (GTK_IMAGE (applet->icon), applet->surfaces[image]);
}

static gboolean
Expand Down
97 changes: 48 additions & 49 deletions drivemount/drive-button.c
Expand Up @@ -339,9 +339,10 @@ drive_button_update (gpointer user_data)
GtkIconTheme *icon_theme;
GtkIconInfo *icon_info;
GIcon *icon;
int width, height;
GdkPixbuf *pixbuf = NULL, *scaled;
GdkPixbuf *tmp_pixbuf = NULL;
int width, height, scale;
cairo_t *cr;
cairo_surface_t *surface = NULL;
cairo_surface_t *tmp_surface = NULL;
GtkRequisition button_req, image_req;
char *display_name, *tip;

Expand All @@ -351,10 +352,11 @@ drive_button_update (gpointer user_data)

/* base the icon size on the desired button size */
drive_button_reset_popup (self);
scale = gtk_widget_get_scale_factor (GTK_WIDGET (self));
gtk_widget_get_preferred_size (GTK_WIDGET (self), NULL, &button_req);
gtk_widget_get_preferred_size (gtk_bin_get_child (GTK_BIN (self)), NULL, &image_req);
width = self->icon_size - (button_req.width - image_req.width);
height = self->icon_size - (button_req.height - image_req.height);
width = (self->icon_size - (button_req.width - image_req.width)) / scale;
height = (self->icon_size - (button_req.height - image_req.height)) / scale;

/* if no volume or mount, display general image */
if (!self->volume && !self->mount)
Expand All @@ -363,23 +365,20 @@ drive_button_update (gpointer user_data)
screen = gtk_widget_get_screen (GTK_WIDGET (self));
icon_theme = gtk_icon_theme_get_for_screen (screen); //m
// note - other good icon would be emblem-unreadable
icon_info = gtk_icon_theme_lookup_icon (icon_theme, "media-floppy",
MIN (width, height),
GTK_ICON_LOOKUP_USE_BUILTIN);
icon_info = gtk_icon_theme_lookup_icon_for_scale (icon_theme, "media-floppy",
MIN (width, height), scale,
GTK_ICON_LOOKUP_USE_BUILTIN);
if (icon_info) {
pixbuf = gtk_icon_info_load_icon (icon_info, NULL);
surface = gtk_icon_info_load_surface (icon_info, NULL, NULL);
g_object_unref (icon_info);
}

if (!pixbuf)
if (!surface)
return FALSE;
scaled = gdk_pixbuf_scale_simple (pixbuf, width, height, GDK_INTERP_BILINEAR);
if (scaled) {
g_object_unref (pixbuf);
pixbuf = scaled;
}

if (gtk_bin_get_child (GTK_BIN (self)) != NULL)
gtk_image_set_from_pixbuf (GTK_IMAGE (gtk_bin_get_child (GTK_BIN (self))), pixbuf);
gtk_image_set_from_surface (GTK_IMAGE (gtk_bin_get_child (GTK_BIN (self))), surface);

return FALSE;
}

Expand All @@ -396,19 +395,15 @@ drive_button_update (gpointer user_data)
{
is_mounted = TRUE;
tip = g_strdup_printf ("%s\n%s", display_name, _("(mounted)"));
icon = g_mount_get_icon (mount);
g_object_unref (mount);
}
else
{
is_mounted = FALSE;
tip = g_strdup_printf ("%s\n%s", display_name, _("(not mounted)"));
}
if (mount)
icon = g_mount_get_icon (mount);
else
icon = g_volume_get_icon (self->volume);

if (mount)
g_object_unref (mount);
}
} else
{
is_mounted = TRUE;
Expand All @@ -423,41 +418,43 @@ drive_button_update (gpointer user_data)

screen = gtk_widget_get_screen (GTK_WIDGET (self));
icon_theme = gtk_icon_theme_get_for_screen (screen);
icon_info = gtk_icon_theme_lookup_by_gicon (icon_theme, icon,
MIN (width, height),
GTK_ICON_LOOKUP_USE_BUILTIN);
icon_info = gtk_icon_theme_lookup_by_gicon_for_scale (icon_theme, icon,
MIN (width, height), scale,
GTK_ICON_LOOKUP_USE_BUILTIN);
if (icon_info)
{
pixbuf = gtk_icon_info_load_icon (icon_info, NULL);
surface = gtk_icon_info_load_surface (icon_info, NULL, NULL);
g_object_unref (icon_info);
}

g_object_unref (icon);

if (!pixbuf)
if (!surface)
return FALSE;

// make a copy of pixbuf becasue icon image can be shared by system
tmp_pixbuf = gdk_pixbuf_copy (pixbuf);
g_object_unref (pixbuf);
g_assert (tmp_pixbuf != NULL);
// create a new surface because icon image can be shared by system
tmp_surface = cairo_surface_create_similar (surface,
cairo_surface_get_content (surface),
cairo_image_surface_get_width (surface) / scale,
cairo_image_surface_get_height (surface) / scale);

// if mounted, change icon
if (is_mounted)
{
int icon_width, icon_height, rowstride, n_channels, x, y;
guchar *pixels, *p;
gboolean has_alpha;

has_alpha = cairo_surface_get_content (tmp_surface) != CAIRO_CONTENT_COLOR;
n_channels = 3;
if (has_alpha)
n_channels++;

n_channels = gdk_pixbuf_get_n_channels (tmp_pixbuf);
g_assert (gdk_pixbuf_get_colorspace (tmp_pixbuf) == GDK_COLORSPACE_RGB);
g_assert (gdk_pixbuf_get_bits_per_sample (tmp_pixbuf) == 8);
g_assert (gdk_pixbuf_get_has_alpha (tmp_pixbuf));
g_assert (n_channels == 4);
icon_width = gdk_pixbuf_get_width (tmp_pixbuf);
icon_height = gdk_pixbuf_get_height (tmp_pixbuf);
icon_width = cairo_image_surface_get_width (tmp_surface);
icon_height = cairo_image_surface_get_height (tmp_surface);

rowstride = gdk_pixbuf_get_rowstride (tmp_pixbuf);
pixels = gdk_pixbuf_get_pixels (tmp_pixbuf);
rowstride = cairo_image_surface_get_stride (tmp_surface);
pixels = cairo_image_surface_get_data (tmp_surface);

GdkRGBA color;
gchar *color_string = g_settings_get_string (settings, "drivemount-checkmark-color");
Expand All @@ -481,18 +478,20 @@ drive_button_update (gpointer user_data)
p[0] = red;
p[1] = green;
p[2] = blue;
p[3] = 255;
if (has_alpha)
p[3] = 255;
}
}

scaled = gdk_pixbuf_scale_simple (tmp_pixbuf, width, height, GDK_INTERP_BILINEAR);
if (scaled) {
g_object_unref (tmp_pixbuf);
tmp_pixbuf = scaled;
}
cr = cairo_create (tmp_surface);
cairo_set_operator (cr, CAIRO_OPERATOR_OVERLAY);
cairo_set_source_surface (cr, surface, 0, 0);
cairo_paint (cr);

gtk_image_set_from_surface (GTK_IMAGE (gtk_bin_get_child (GTK_BIN (self))), tmp_surface);

gtk_image_set_from_pixbuf (GTK_IMAGE (gtk_bin_get_child (GTK_BIN (self))), tmp_pixbuf);
g_object_unref (tmp_pixbuf);
cairo_surface_destroy (surface);
cairo_surface_destroy (tmp_surface);

gtk_widget_get_preferred_size (GTK_WIDGET (self), NULL, &button_req);

Expand Down

0 comments on commit 311ae4e

Please sign in to comment.