@@ -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