Skip to content

Commit 311ae4e

Browse files
vkarehraveit65
authored andcommitted
Convert applet icons from pixbuf to surfaces
This improves support for HiDPI by loading properly scaled surfaces for applets.
1 parent e83811d commit 311ae4e

File tree

6 files changed

+178
-135
lines changed

6 files changed

+178
-135
lines changed

battstat/battstat_applet.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ static GdkColor darkred[] = {
214214
their XPM format (as stored in pixmaps.h). This should only be done once
215215
since they are global variables.
216216
*/
217+
/* FIXME: We should be using named icons here... */
217218
static void
218219
initialise_global_pixmaps( void )
219220
{

cpufreq/src/cpufreq-applet.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ struct _CPUFreqApplet {
6262
GtkWidget *box;
6363
GtkWidget *labels_box;
6464
GtkWidget *container;
65-
GdkPixbuf *pixbufs[5];
65+
cairo_surface_t *surfaces[5];
6666

6767
gint max_label_width;
6868
gint max_perc_width;
@@ -245,9 +245,9 @@ cpufreq_applet_dispose (GObject *widget)
245245
}
246246

247247
for (i = 0; i <= 3; i++) {
248-
if (applet->pixbufs[i]) {
249-
g_object_unref (G_OBJECT (applet->pixbufs[i]));
250-
applet->pixbufs[i] = NULL;
248+
if (applet->surfaces[i]) {
249+
cairo_surface_destroy (applet->surfaces[i]);
250+
applet->surfaces[i] = NULL;
251251
}
252252
}
253253

@@ -646,6 +646,8 @@ static void
646646
cpufreq_applet_pixmap_set_image (CPUFreqApplet *applet, gint perc)
647647
{
648648
gint image;
649+
gint scale;
650+
gint size = 24; /* FIXME */
649651

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

666-
if (applet->pixbufs[image] == NULL) {
667-
applet->pixbufs[image] = gdk_pixbuf_new_from_file_at_size (cpufreq_icons[image],
668-
24, 24, NULL);
668+
scale = gtk_widget_get_scale_factor (GTK_WIDGET (applet->icon));
669+
670+
if (applet->surfaces[image] == NULL) {
671+
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_scale (cpufreq_icons[image],
672+
size * scale,
673+
size * scale,
674+
TRUE,
675+
NULL);
676+
applet->surfaces[image] = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale, NULL);
669677
}
670678

671-
gtk_image_set_from_pixbuf (GTK_IMAGE (applet->icon), applet->pixbufs[image]);
679+
gtk_image_set_from_surface (GTK_IMAGE (applet->icon), applet->surfaces[image]);
672680
}
673681

674682
static gboolean

drivemount/drive-button.c

Lines changed: 48 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -339,9 +339,10 @@ drive_button_update (gpointer user_data)
339339
GtkIconTheme *icon_theme;
340340
GtkIconInfo *icon_info;
341341
GIcon *icon;
342-
int width, height;
343-
GdkPixbuf *pixbuf = NULL, *scaled;
344-
GdkPixbuf *tmp_pixbuf = NULL;
342+
int width, height, scale;
343+
cairo_t *cr;
344+
cairo_surface_t *surface = NULL;
345+
cairo_surface_t *tmp_surface = NULL;
345346
GtkRequisition button_req, image_req;
346347
char *display_name, *tip;
347348

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

352353
/* base the icon size on the desired button size */
353354
drive_button_reset_popup (self);
355+
scale = gtk_widget_get_scale_factor (GTK_WIDGET (self));
354356
gtk_widget_get_preferred_size (GTK_WIDGET (self), NULL, &button_req);
355357
gtk_widget_get_preferred_size (gtk_bin_get_child (GTK_BIN (self)), NULL, &image_req);
356-
width = self->icon_size - (button_req.width - image_req.width);
357-
height = self->icon_size - (button_req.height - image_req.height);
358+
width = (self->icon_size - (button_req.width - image_req.width)) / scale;
359+
height = (self->icon_size - (button_req.height - image_req.height)) / scale;
358360

359361
/* if no volume or mount, display general image */
360362
if (!self->volume && !self->mount)
@@ -363,23 +365,20 @@ drive_button_update (gpointer user_data)
363365
screen = gtk_widget_get_screen (GTK_WIDGET (self));
364366
icon_theme = gtk_icon_theme_get_for_screen (screen); //m
365367
// note - other good icon would be emblem-unreadable
366-
icon_info = gtk_icon_theme_lookup_icon (icon_theme, "media-floppy",
367-
MIN (width, height),
368-
GTK_ICON_LOOKUP_USE_BUILTIN);
368+
icon_info = gtk_icon_theme_lookup_icon_for_scale (icon_theme, "media-floppy",
369+
MIN (width, height), scale,
370+
GTK_ICON_LOOKUP_USE_BUILTIN);
369371
if (icon_info) {
370-
pixbuf = gtk_icon_info_load_icon (icon_info, NULL);
372+
surface = gtk_icon_info_load_surface (icon_info, NULL, NULL);
371373
g_object_unref (icon_info);
372374
}
373375

374-
if (!pixbuf)
376+
if (!surface)
375377
return FALSE;
376-
scaled = gdk_pixbuf_scale_simple (pixbuf, width, height, GDK_INTERP_BILINEAR);
377-
if (scaled) {
378-
g_object_unref (pixbuf);
379-
pixbuf = scaled;
380-
}
378+
381379
if (gtk_bin_get_child (GTK_BIN (self)) != NULL)
382-
gtk_image_set_from_pixbuf (GTK_IMAGE (gtk_bin_get_child (GTK_BIN (self))), pixbuf);
380+
gtk_image_set_from_surface (GTK_IMAGE (gtk_bin_get_child (GTK_BIN (self))), surface);
381+
383382
return FALSE;
384383
}
385384

@@ -396,19 +395,15 @@ drive_button_update (gpointer user_data)
396395
{
397396
is_mounted = TRUE;
398397
tip = g_strdup_printf ("%s\n%s", display_name, _("(mounted)"));
398+
icon = g_mount_get_icon (mount);
399+
g_object_unref (mount);
399400
}
400401
else
401402
{
402403
is_mounted = FALSE;
403404
tip = g_strdup_printf ("%s\n%s", display_name, _("(not mounted)"));
404-
}
405-
if (mount)
406-
icon = g_mount_get_icon (mount);
407-
else
408405
icon = g_volume_get_icon (self->volume);
409-
410-
if (mount)
411-
g_object_unref (mount);
406+
}
412407
} else
413408
{
414409
is_mounted = TRUE;
@@ -423,41 +418,43 @@ drive_button_update (gpointer user_data)
423418

424419
screen = gtk_widget_get_screen (GTK_WIDGET (self));
425420
icon_theme = gtk_icon_theme_get_for_screen (screen);
426-
icon_info = gtk_icon_theme_lookup_by_gicon (icon_theme, icon,
427-
MIN (width, height),
428-
GTK_ICON_LOOKUP_USE_BUILTIN);
421+
icon_info = gtk_icon_theme_lookup_by_gicon_for_scale (icon_theme, icon,
422+
MIN (width, height), scale,
423+
GTK_ICON_LOOKUP_USE_BUILTIN);
429424
if (icon_info)
430425
{
431-
pixbuf = gtk_icon_info_load_icon (icon_info, NULL);
426+
surface = gtk_icon_info_load_surface (icon_info, NULL, NULL);
432427
g_object_unref (icon_info);
433428
}
434429

435430
g_object_unref (icon);
436431

437-
if (!pixbuf)
432+
if (!surface)
438433
return FALSE;
439434

440-
// make a copy of pixbuf becasue icon image can be shared by system
441-
tmp_pixbuf = gdk_pixbuf_copy (pixbuf);
442-
g_object_unref (pixbuf);
443-
g_assert (tmp_pixbuf != NULL);
435+
// create a new surface because icon image can be shared by system
436+
tmp_surface = cairo_surface_create_similar (surface,
437+
cairo_surface_get_content (surface),
438+
cairo_image_surface_get_width (surface) / scale,
439+
cairo_image_surface_get_height (surface) / scale);
444440

445441
// if mounted, change icon
446442
if (is_mounted)
447443
{
448444
int icon_width, icon_height, rowstride, n_channels, x, y;
449445
guchar *pixels, *p;
446+
gboolean has_alpha;
447+
448+
has_alpha = cairo_surface_get_content (tmp_surface) != CAIRO_CONTENT_COLOR;
449+
n_channels = 3;
450+
if (has_alpha)
451+
n_channels++;
450452

451-
n_channels = gdk_pixbuf_get_n_channels (tmp_pixbuf);
452-
g_assert (gdk_pixbuf_get_colorspace (tmp_pixbuf) == GDK_COLORSPACE_RGB);
453-
g_assert (gdk_pixbuf_get_bits_per_sample (tmp_pixbuf) == 8);
454-
g_assert (gdk_pixbuf_get_has_alpha (tmp_pixbuf));
455-
g_assert (n_channels == 4);
456-
icon_width = gdk_pixbuf_get_width (tmp_pixbuf);
457-
icon_height = gdk_pixbuf_get_height (tmp_pixbuf);
453+
icon_width = cairo_image_surface_get_width (tmp_surface);
454+
icon_height = cairo_image_surface_get_height (tmp_surface);
458455

459-
rowstride = gdk_pixbuf_get_rowstride (tmp_pixbuf);
460-
pixels = gdk_pixbuf_get_pixels (tmp_pixbuf);
456+
rowstride = cairo_image_surface_get_stride (tmp_surface);
457+
pixels = cairo_image_surface_get_data (tmp_surface);
461458

462459
GdkRGBA color;
463460
gchar *color_string = g_settings_get_string (settings, "drivemount-checkmark-color");
@@ -481,18 +478,20 @@ drive_button_update (gpointer user_data)
481478
p[0] = red;
482479
p[1] = green;
483480
p[2] = blue;
484-
p[3] = 255;
481+
if (has_alpha)
482+
p[3] = 255;
485483
}
486484
}
487485

488-
scaled = gdk_pixbuf_scale_simple (tmp_pixbuf, width, height, GDK_INTERP_BILINEAR);
489-
if (scaled) {
490-
g_object_unref (tmp_pixbuf);
491-
tmp_pixbuf = scaled;
492-
}
486+
cr = cairo_create (tmp_surface);
487+
cairo_set_operator (cr, CAIRO_OPERATOR_OVERLAY);
488+
cairo_set_source_surface (cr, surface, 0, 0);
489+
cairo_paint (cr);
490+
491+
gtk_image_set_from_surface (GTK_IMAGE (gtk_bin_get_child (GTK_BIN (self))), tmp_surface);
493492

494-
gtk_image_set_from_pixbuf (GTK_IMAGE (gtk_bin_get_child (GTK_BIN (self))), tmp_pixbuf);
495-
g_object_unref (tmp_pixbuf);
493+
cairo_surface_destroy (surface);
494+
cairo_surface_destroy (tmp_surface);
496495

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

0 commit comments

Comments
 (0)