summaryrefslogtreecommitdiff
path: root/mate-panel
diff options
context:
space:
mode:
authorVictor Kareh <[email protected]>2018-05-01 00:24:38 -0400
committerraveit65 <[email protected]>2018-05-12 21:23:54 +0200
commit5c4eb86ea1bb117805cc8fccb4ba3d96a53f2813 (patch)
treebb18949947cbcc5e446ac1e666594be23cf34ba1 /mate-panel
parent6e0188bf03c24558cc1ecd1dd6244eda8137b48e (diff)
downloadmate-panel-5c4eb86ea1bb117805cc8fccb4ba3d96a53f2813.tar.bz2
mate-panel-5c4eb86ea1bb117805cc8fccb4ba3d96a53f2813.tar.xz
Convert launcher icons to cairo surfaces
This improves support for HiDPI by loading properly scaled surfaces for launcher and drawer icons. It also Fixes the Show Desktop wncklet to show a surface icon. Other wncklets have their icons determined by libwnck, so they remain as pixbufs. Fixes mate-desktop/mate-desktop#314
Diffstat (limited to 'mate-panel')
-rw-r--r--mate-panel/button-widget.c153
-rw-r--r--mate-panel/button-widget.h2
-rw-r--r--mate-panel/launcher.c34
-rw-r--r--mate-panel/panel-util.c15
-rw-r--r--mate-panel/panel-util.h2
-rw-r--r--mate-panel/xstuff.c17
-rw-r--r--mate-panel/xstuff.h2
7 files changed, 124 insertions, 101 deletions
diff --git a/mate-panel/button-widget.c b/mate-panel/button-widget.c
index 94d031f0..796e3179 100644
--- a/mate-panel/button-widget.c
+++ b/mate-panel/button-widget.c
@@ -5,7 +5,7 @@
#include <glib/gi18n.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gdk/gdk.h>
#include "button-widget.h"
#include "panel-widget.h"
@@ -22,8 +22,8 @@
struct _ButtonWidgetPrivate {
GtkIconTheme *icon_theme;
- GdkPixbuf *pixbuf;
- GdkPixbuf *pixbuf_hc;
+ cairo_surface_t *surface;
+ cairo_surface_t *surface_hc;
char *filename;
@@ -38,7 +38,7 @@ struct _ButtonWidgetPrivate {
};
static void button_widget_icon_theme_changed (ButtonWidget *button);
-static void button_widget_reload_pixbuf (ButtonWidget *button);
+static void button_widget_reload_surface (ButtonWidget *button);
enum {
PROP_0,
@@ -54,9 +54,9 @@ enum {
G_DEFINE_TYPE (ButtonWidget, button_widget, GTK_TYPE_BUTTON)
-/* colorshift a pixbuf */
+/* colorshift a surface */
static void
-do_colorshift (GdkPixbuf *dest, GdkPixbuf *src, int shift)
+do_colorshift (cairo_surface_t *dest, cairo_surface_t *src, int shift)
{
gint i, j;
gint width, height, has_alpha, srcrowstride, destrowstride;
@@ -67,13 +67,13 @@ do_colorshift (GdkPixbuf *dest, GdkPixbuf *src, int shift)
int val;
guchar r,g,b;
- has_alpha = gdk_pixbuf_get_has_alpha (src);
- width = gdk_pixbuf_get_width (src);
- height = gdk_pixbuf_get_height (src);
- srcrowstride = gdk_pixbuf_get_rowstride (src);
- destrowstride = gdk_pixbuf_get_rowstride (dest);
- target_pixels = gdk_pixbuf_get_pixels (dest);
- original_pixels = gdk_pixbuf_get_pixels (src);
+ has_alpha = cairo_surface_get_content (src) != CAIRO_CONTENT_COLOR;
+ width = cairo_image_surface_get_width (src);
+ height = cairo_image_surface_get_height (src);
+ srcrowstride = cairo_image_surface_get_stride (src);
+ destrowstride = cairo_image_surface_get_stride (dest);
+ original_pixels = cairo_image_surface_get_data (src);
+ target_pixels = cairo_image_surface_get_data (dest);
for (i = 0; i < height; i++) {
pixdest = target_pixels + i*destrowstride;
@@ -94,20 +94,25 @@ do_colorshift (GdkPixbuf *dest, GdkPixbuf *src, int shift)
}
}
-static GdkPixbuf *
-make_hc_pixbuf (GdkPixbuf *pb)
+static cairo_surface_t *
+make_hc_surface (cairo_surface_t *surface)
{
- GdkPixbuf *new;
-
- if (!pb)
+ cairo_t *cr;
+ cairo_surface_t *new;
+
+ if (!surface)
return NULL;
- new = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (pb),
- gdk_pixbuf_get_has_alpha (pb),
- gdk_pixbuf_get_bits_per_sample (pb),
- gdk_pixbuf_get_width (pb),
- gdk_pixbuf_get_height (pb));
- do_colorshift (new, pb, 30);
+ new = cairo_surface_create_similar (surface,
+ cairo_surface_get_content (surface),
+ cairo_image_surface_get_width (surface),
+ cairo_image_surface_get_height (surface));
+
+ do_colorshift (new, surface, 30);
+
+ cr = cairo_create (new);
+ cairo_set_operator (cr, CAIRO_OPERATOR_DEST_IN);
+ cairo_mask_surface (cr, surface, 0, 0);
return new;
}
@@ -128,7 +133,7 @@ button_widget_realize(GtkWidget *widget)
widget,
G_CONNECT_SWAPPED);
- button_widget_reload_pixbuf (BUTTON_WIDGET (widget));
+ button_widget_reload_surface (BUTTON_WIDGET (widget));
}
static void
@@ -142,49 +147,54 @@ button_widget_unrealize (GtkWidget *widget)
}
static void
-button_widget_unset_pixbufs (ButtonWidget *button)
+button_widget_unset_surfaces (ButtonWidget *button)
{
- if (button->priv->pixbuf)
- g_object_unref (button->priv->pixbuf);
- button->priv->pixbuf = NULL;
+ if (button->priv->surface)
+ cairo_surface_destroy (button->priv->surface);
+ button->priv->surface = NULL;
- if (button->priv->pixbuf_hc)
- g_object_unref (button->priv->pixbuf_hc);
- button->priv->pixbuf_hc = NULL;
+ if (button->priv->surface_hc)
+ cairo_surface_destroy (button->priv->surface_hc);
+ button->priv->surface_hc = NULL;
}
static void
-button_widget_reload_pixbuf (ButtonWidget *button)
+button_widget_reload_surface (ButtonWidget *button)
{
- button_widget_unset_pixbufs (button);
+ button_widget_unset_surfaces (button);
if (button->priv->size <= 1 || button->priv->icon_theme == NULL)
return;
if (button->priv->filename != NULL &&
button->priv->filename [0] != '\0') {
+ gint scale;
char *error = NULL;
- button->priv->pixbuf =
+ scale = gtk_widget_get_scale_factor (GTK_WIDGET (button));
+
+ button->priv->surface =
panel_load_icon (button->priv->icon_theme,
button->priv->filename,
- button->priv->size,
- button->priv->orientation & PANEL_VERTICAL_MASK ? button->priv->size : -1,
- button->priv->orientation & PANEL_HORIZONTAL_MASK ? button->priv->size : -1,
+ button->priv->size * scale,
+ button->priv->orientation & PANEL_VERTICAL_MASK ? button->priv->size * scale : -1,
+ button->priv->orientation & PANEL_HORIZONTAL_MASK ? button->priv->size * scale: -1,
&error);
if (error) {
//FIXME: this is not rendered at button->priv->size
GtkIconTheme *icon_theme = gtk_icon_theme_get_default();
- button->priv->pixbuf = gtk_icon_theme_load_icon (icon_theme,
+ button->priv->surface = gtk_icon_theme_load_surface (icon_theme,
"image-missing",
GTK_ICON_SIZE_BUTTON,
+ scale,
+ NULL,
GTK_ICON_LOOKUP_FORCE_SVG | GTK_ICON_LOOKUP_USE_BUILTIN,
NULL);
g_free (error);
}
}
- button->priv->pixbuf_hc = make_hc_pixbuf (button->priv->pixbuf);
+ button->priv->surface_hc = make_hc_surface (button->priv->surface);
gtk_widget_queue_resize (GTK_WIDGET (button));
}
@@ -193,7 +203,7 @@ static void
button_widget_icon_theme_changed (ButtonWidget *button)
{
if (button->priv->filename != NULL)
- button_widget_reload_pixbuf (button);
+ button_widget_reload_surface (button);
}
static void
@@ -201,7 +211,7 @@ button_widget_finalize (GObject *object)
{
ButtonWidget *button = (ButtonWidget *) object;
- button_widget_unset_pixbufs (button);
+ button_widget_unset_surfaces (button);
g_free (button->priv->filename);
button->priv->filename = NULL;
@@ -341,50 +351,47 @@ button_widget_draw (GtkWidget *widget,
GtkStateFlags state_flags;
int off;
int x, y, w, h;
- GdkPixbuf *pb = NULL;
-
+ int scale;
+
g_return_val_if_fail (BUTTON_IS_WIDGET (widget), FALSE);
button_widget = BUTTON_WIDGET (widget);
- if (!button_widget->priv->pixbuf_hc && !button_widget->priv->pixbuf)
+ if (!button_widget->priv->surface_hc && !button_widget->priv->surface)
return FALSE;
state_flags = gtk_widget_get_state_flags (widget);
width = gtk_widget_get_allocated_width (widget);
height = gtk_widget_get_allocated_height (widget);
+ scale = gtk_widget_get_scale_factor (widget);
/* offset for pressed buttons */
off = (button_widget->priv->activatable &&
(state_flags & GTK_STATE_FLAG_PRELIGHT) && (state_flags & GTK_STATE_FLAG_ACTIVE)) ?
BUTTON_WIDGET_DISPLACEMENT * height / 48.0 : 0;
- if (!button_widget->priv->activatable) {
- pb = gdk_pixbuf_copy (button_widget->priv->pixbuf);
- gdk_pixbuf_saturate_and_pixelate (button_widget->priv->pixbuf,
- pb,
- 0.8,
- TRUE);
- } else if (panel_global_config_get_highlight_when_over () &&
- (state_flags & GTK_STATE_FLAG_PRELIGHT || gtk_widget_has_focus (widget)))
- pb = g_object_ref (button_widget->priv->pixbuf_hc);
- else
- pb = g_object_ref (button_widget->priv->pixbuf);
+ w = cairo_image_surface_get_width (button_widget->priv->surface) / scale;
+ h = cairo_image_surface_get_height (button_widget->priv->surface) / scale;
+ x = off + (width - w) / 2;
+ y = off + (height - h) / 2;
- g_assert (pb != NULL);
+ cairo_save (cr);
- w = gdk_pixbuf_get_width (pb);
- h = gdk_pixbuf_get_height (pb);
- x = off + (width - w)/2;
- y = off + (height - h)/2;
+ if (!button_widget->priv->activatable) {
+ cairo_set_source_surface (cr, button_widget->priv->surface, x, y);
+ cairo_mask_surface (cr, button_widget->priv->surface, x, y);
+ cairo_set_operator (cr, CAIRO_OPERATOR_HSL_SATURATION);
+ cairo_set_source_rgba (cr, 0, 0, 0, 0.2);
+ } else if (panel_global_config_get_highlight_when_over () &&
+ (state_flags & GTK_STATE_FLAG_PRELIGHT || gtk_widget_has_focus (widget))) {
+ cairo_set_source_surface (cr, button_widget->priv->surface_hc, x, y);
+ } else {
+ cairo_set_source_surface (cr, button_widget->priv->surface, x, y);
+ }
- cairo_save (cr);
- gdk_cairo_set_source_pixbuf (cr, pb, x, y);
cairo_paint (cr);
cairo_restore (cr);
- g_object_unref (pb);
-
context = gtk_widget_get_style_context (widget);
if (button_widget->priv->arrow) {
@@ -494,7 +501,7 @@ button_widget_size_allocate (GtkWidget *widget,
if (button_widget->priv->size != size) {
button_widget->priv->size = size;
- button_widget_reload_pixbuf (button_widget);
+ button_widget_reload_surface (button_widget);
}
}
@@ -571,8 +578,8 @@ button_widget_init (ButtonWidget *button)
button->priv = BUTTON_WIDGET_GET_PRIVATE (button);
button->priv->icon_theme = NULL;
- button->priv->pixbuf = NULL;
- button->priv->pixbuf_hc = NULL;
+ button->priv->surface = NULL;
+ button->priv->surface_hc = NULL;
button->priv->filename = NULL;
@@ -724,7 +731,7 @@ button_widget_set_icon_name (ButtonWidget *button,
g_free (button->priv->filename);
button->priv->filename = g_strdup (icon_name);
- button_widget_reload_pixbuf (button);
+ button_widget_reload_surface (button);
g_object_notify (G_OBJECT (button), "icon-name");
}
@@ -850,13 +857,13 @@ button_widget_get_icon_theme (ButtonWidget *button)
return button->priv->icon_theme;
}
-GdkPixbuf *
-button_widget_get_pixbuf (ButtonWidget *button)
+cairo_surface_t *
+button_widget_get_surface (ButtonWidget *button)
{
g_return_val_if_fail (BUTTON_IS_WIDGET (button), NULL);
- if (!button->priv->pixbuf)
+ if (!button->priv->surface)
return NULL;
- return g_object_ref (button->priv->pixbuf);
+ return cairo_surface_reference (button->priv->surface);
}
diff --git a/mate-panel/button-widget.h b/mate-panel/button-widget.h
index e9b87e6d..372c33b9 100644
--- a/mate-panel/button-widget.h
+++ b/mate-panel/button-widget.h
@@ -51,7 +51,7 @@ void button_widget_set_ignore_leave (ButtonWidget *button,
gboolean ignore_leave);
gboolean button_widget_get_ignore_leave (ButtonWidget *button);
GtkIconTheme *button_widget_get_icon_theme (ButtonWidget *button);
-GdkPixbuf *button_widget_get_pixbuf (ButtonWidget *button);
+cairo_surface_t *button_widget_get_surface (ButtonWidget *button);
#ifdef __cplusplus
}
diff --git a/mate-panel/launcher.c b/mate-panel/launcher.c
index d8d65ad1..67746b06 100644
--- a/mate-panel/launcher.c
+++ b/mate-panel/launcher.c
@@ -184,15 +184,15 @@ drag_data_received_cb (GtkWidget *widget,
GList *file_list;
if (panel_global_config_get_enable_animations ()) {
- GdkPixbuf *pixbuf;
- pixbuf = button_widget_get_pixbuf (BUTTON_WIDGET (widget));
+ cairo_surface_t *surface;
+ surface = button_widget_get_surface (BUTTON_WIDGET (widget));
xstuff_zoom_animate (widget,
- pixbuf,
+ surface,
button_widget_get_orientation (BUTTON_WIDGET (widget)),
NULL);
- g_object_unref (pixbuf);
+ cairo_surface_destroy (surface);
}
-
+
file_list = NULL;
uris = g_uri_list_extract_uris ((const char *) gtk_selection_data_get_data (selection_data));
for (i = 0; uris[i]; i++)
@@ -402,13 +402,13 @@ clicked_cb (Launcher *launcher,
GtkWidget *widget)
{
if (panel_global_config_get_enable_animations ()) {
- GdkPixbuf *pixbuf;
- pixbuf = button_widget_get_pixbuf (BUTTON_WIDGET (widget));
+ cairo_surface_t *surface;
+ surface = button_widget_get_surface (BUTTON_WIDGET (widget));
xstuff_zoom_animate (widget,
- pixbuf,
+ surface,
button_widget_get_orientation (BUTTON_WIDGET (widget)),
NULL);
- g_object_unref (pixbuf);
+ cairo_surface_destroy (surface);
}
launcher_launch (launcher, NULL);
@@ -1157,7 +1157,7 @@ void
panel_launcher_set_dnd_enabled (Launcher *launcher,
gboolean dnd_enabled)
{
- GdkPixbuf *pixbuf;
+ cairo_surface_t *surface;
if (dnd_enabled) {
static GtkTargetEntry dnd_targets[] = {
@@ -1170,16 +1170,20 @@ panel_launcher_set_dnd_enabled (Launcher *launcher,
GDK_BUTTON1_MASK,
dnd_targets, 2,
GDK_ACTION_COPY | GDK_ACTION_MOVE);
- //FIXME: this doesn't work since the pixbuf isn't loaded yet
- pixbuf = button_widget_get_pixbuf (BUTTON_WIDGET (launcher->button));
- if (pixbuf) {
+ surface = button_widget_get_surface (BUTTON_WIDGET (launcher->button));
+ if (surface) {
+ GdkPixbuf *pixbuf;
+ pixbuf = gdk_pixbuf_get_from_surface (surface,
+ 0,
+ 0,
+ cairo_image_surface_get_width (surface),
+ cairo_image_surface_get_height (surface));
gtk_drag_source_set_icon_pixbuf (launcher->button,
pixbuf);
g_object_unref (pixbuf);
+ cairo_surface_destroy (surface);
}
gtk_widget_set_has_window (launcher->button, FALSE);
-
-
} else
gtk_drag_source_unset (launcher->button);
}
diff --git a/mate-panel/panel-util.c b/mate-panel/panel-util.c
index a958a761..f9832473 100644
--- a/mate-panel/panel-util.c
+++ b/mate-panel/panel-util.c
@@ -327,7 +327,7 @@ panel_find_icon (GtkIconTheme *icon_theme,
return retval;
}
-GdkPixbuf *
+cairo_surface_t *
panel_load_icon (GtkIconTheme *icon_theme,
const char *icon_name,
int size,
@@ -335,7 +335,8 @@ panel_load_icon (GtkIconTheme *icon_theme,
int desired_height,
char **error_msg)
{
- GdkPixbuf *retval;
+ GdkPixbuf *pixbuf;
+ cairo_surface_t *surface;
char *file;
GError *error;
@@ -351,19 +352,25 @@ panel_load_icon (GtkIconTheme *icon_theme,
}
error = NULL;
- retval = gdk_pixbuf_new_from_file_at_size (file,
+ pixbuf = gdk_pixbuf_new_from_file_at_scale (file,
desired_width,
desired_height,
+ TRUE,
&error);
if (error) {
if (error_msg)
*error_msg = g_strdup (error->message);
g_error_free (error);
+ surface = NULL;
+ }
+ else {
+ surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, 0, NULL);
}
g_free (file);
+ g_object_unref (pixbuf);
- return retval;
+ return surface;
}
static char* panel_lock_screen_action_get_command(const char* action)
diff --git a/mate-panel/panel-util.h b/mate-panel/panel-util.h
index 21352970..8d9fb2ef 100644
--- a/mate-panel/panel-util.h
+++ b/mate-panel/panel-util.h
@@ -31,7 +31,7 @@ GIcon * panel_gicon_from_icon_name (const char *icon_name);
char * panel_find_icon (GtkIconTheme *icon_theme,
const char *icon_name,
int size);
-GdkPixbuf * panel_load_icon (GtkIconTheme *icon_theme,
+cairo_surface_t *panel_load_icon (GtkIconTheme *icon_theme,
const char *icon_name,
int size,
int desired_width,
diff --git a/mate-panel/xstuff.c b/mate-panel/xstuff.c
index 7db48acf..21d58825 100644
--- a/mate-panel/xstuff.c
+++ b/mate-panel/xstuff.c
@@ -328,7 +328,7 @@ draw_zoom_animation (GdkScreen *gscreen,
void
xstuff_zoom_animate (GtkWidget *widget,
- GdkPixbuf *pixbuf,
+ cairo_surface_t *surface,
PanelOrientation orientation,
GdkRectangle *opt_rect)
{
@@ -353,12 +353,17 @@ xstuff_zoom_animate (GtkWidget *widget,
gscreen = gtk_widget_get_screen (widget);
- if (gdk_screen_is_composited (gscreen) && pixbuf)
+ if (gdk_screen_is_composited (gscreen) && surface) {
+ GdkPixbuf *pixbuf = gdk_pixbuf_get_from_surface (surface,
+ 0, 0,
+ cairo_image_surface_get_width (surface),
+ cairo_image_surface_get_height (surface));
draw_zoom_animation_composited (gscreen,
- rect.x, rect.y,
- rect.width, rect.height,
- pixbuf, orientation);
- else {
+ rect.x, rect.y,
+ rect.width, rect.height,
+ pixbuf, orientation);
+ g_object_unref (pixbuf);
+ } else {
display = gdk_screen_get_display (gscreen);
monitor = gdk_display_get_monitor_at_window (display,
gtk_widget_get_window (widget));
diff --git a/mate-panel/xstuff.h b/mate-panel/xstuff.h
index 507a1dd3..83af4645 100644
--- a/mate-panel/xstuff.h
+++ b/mate-panel/xstuff.h
@@ -5,7 +5,7 @@
#include <gtk/gtk.h>
void xstuff_zoom_animate (GtkWidget *widget,
- GdkPixbuf *pixbuf,
+ cairo_surface_t *surface,
PanelOrientation orientation,
GdkRectangle *opt_src_rect);