summaryrefslogtreecommitdiff
path: root/mate-panel/menu.c
diff options
context:
space:
mode:
authorDenis Gorodnichev <[email protected]>2014-11-09 17:30:11 +0300
committerStefano Karapetsas <[email protected]>2014-11-18 09:46:26 +0100
commita0d8947866db1486e0be0744cec62cfdcc2199d4 (patch)
tree2ed949b3e16801d99caeed2072f74e572d79632b /mate-panel/menu.c
parentfb43ad39ab10826519d23ed42101d983113527bf (diff)
downloadmate-panel-a0d8947866db1486e0be0744cec62cfdcc2199d4.tar.bz2
mate-panel-a0d8947866db1486e0be0744cec62cfdcc2199d4.tar.xz
use gtk icon(pixmap) cache insteadof custom one
Diffstat (limited to 'mate-panel/menu.c')
-rw-r--r--mate-panel/menu.c517
1 files changed, 14 insertions, 503 deletions
diff --git a/mate-panel/menu.c b/mate-panel/menu.c
index fa655668..368c416c 100644
--- a/mate-panel/menu.c
+++ b/mate-panel/menu.c
@@ -55,31 +55,6 @@
#include "panel-icon-names.h"
#include "panel-schemas.h"
-typedef struct {
- GtkWidget *pixmap;
- const char *stock_id;
- GIcon *gicon;
- char *image;
- char *fallback_image;
- GtkIconTheme *icon_theme;
- GtkIconSize icon_size;
-} IconToLoad;
-
-typedef struct {
- GtkWidget *image;
- const char *stock_id;
- GIcon *gicon;
- GdkPixbuf *pixbuf;
- GtkIconSize icon_size;
-} IconToAdd;
-
-static guint load_icons_id = 0;
-static GHashTable *loaded_icons = NULL;
-static GList *icons_to_load = NULL;
-static GList *icons_to_add = NULL;
-
-static GSList *image_menu_items = NULL;
-
static GtkWidget *populate_menu_from_directory (GtkWidget *menu,
MateMenuTreeDirectory *directory);
@@ -192,47 +167,10 @@ menuitem_to_screen (GtkWidget *menuitem)
return gtk_window_get_screen (GTK_WINDOW (panel_widget->toplevel));
}
-static void
-reload_image_menu_items (void)
-{
- GSList* l;
-
- for (l = image_menu_items; l; l = l->next) {
- GtkWidget *image = l->data;
- gboolean is_mapped;
-
- is_mapped = gtk_widget_get_mapped (image);
-
- if (is_mapped)
- gtk_widget_unmap (image);
-
- gtk_image_set_from_pixbuf (GTK_IMAGE (image), NULL);
-
- if (is_mapped)
- gtk_widget_map (image);
-
- }
-}
-
-static void
-icon_theme_changed (GtkIconTheme *icon_theme,
- gpointer data)
-{
- reload_image_menu_items ();
-}
-
GtkWidget *
panel_create_menu (void)
{
GtkWidget *retval;
- static gboolean registered_icon_theme_changer = FALSE;
-
- if (!registered_icon_theme_changer) {
- registered_icon_theme_changer = TRUE;
-
- g_signal_connect (gtk_icon_theme_get_default (), "changed",
- G_CALLBACK (icon_theme_changed), NULL);
- }
retval = gtk_menu_new ();
gtk_widget_set_name (retval, "mate-panel-main-menu");
@@ -262,336 +200,6 @@ create_empty_menu (void)
}
static void
-icon_to_load_free (IconToLoad *icon)
-{
- if (!icon)
- return;
-
- if (icon->pixmap)
- g_object_unref (icon->pixmap);
- icon->pixmap = NULL;
-
- if (icon->gicon)
- g_object_unref (icon->gicon);
- icon->gicon = NULL;
-
- g_free (icon->image); icon->image = NULL;
- g_free (icon->fallback_image); icon->fallback_image = NULL;
- g_free (icon);
-}
-
-static IconToLoad *
-icon_to_load_copy (IconToLoad *icon)
-{
- IconToLoad *retval;
-
- if (!icon)
- return NULL;
-
- retval = g_new0 (IconToLoad, 1);
-
- retval->pixmap = g_object_ref (icon->pixmap);
- if (icon->gicon)
- retval->gicon = g_object_ref (icon->gicon);
- else
- retval->gicon = NULL;
- retval->image = g_strdup (icon->image);
- retval->fallback_image = g_strdup (icon->fallback_image);
- retval->stock_id = icon->stock_id;
- retval->icon_size = icon->icon_size;
-
- return retval;
-}
-
-static void
-remove_pixmap_from_loaded (gpointer data, GObject *where_the_object_was)
-{
- char *key = data;
-
- if (loaded_icons != NULL)
- g_hash_table_remove (loaded_icons, key);
-
- g_free (key);
-}
-
-GdkPixbuf *
-panel_make_menu_icon (GtkIconTheme *icon_theme,
- const char *icon,
- const char *fallback,
- int size,
- gboolean *long_operation)
-{
- GdkPixbuf *pb;
- char *file, *key;
- gboolean loaded;
-
- g_return_val_if_fail (size > 0, NULL);
-
- file = NULL;
- if (icon != NULL)
- file = panel_find_icon (icon_theme, icon, size);
- if (file == NULL && fallback != NULL)
- file = panel_find_icon (icon_theme, fallback, size);
-
- if (file == NULL)
- return NULL;
-
- if (long_operation != NULL)
- *long_operation = TRUE;
-
- pb = NULL;
-
- loaded = FALSE;
-
- key = g_strdup_printf ("%d:%s", size, file);
-
- if (loaded_icons != NULL &&
- (pb = g_hash_table_lookup (loaded_icons, key)) != NULL) {
- if (pb != NULL)
- g_object_ref (G_OBJECT (pb));
- }
-
- if (pb == NULL) {
- pb = gdk_pixbuf_new_from_file (file, NULL);
- if (pb) {
- gint width, height;
-
- width = gdk_pixbuf_get_width (pb);
- height = gdk_pixbuf_get_height (pb);
-
- /* if we want 24 and we get 22, do nothing;
- * else scale */
- if (!(size - 2 <= width && width <= size &&
- size - 2 <= height && height <= size)) {
- GdkPixbuf *tmp;
-
- tmp = gdk_pixbuf_scale_simple (pb, size, size,
- GDK_INTERP_BILINEAR);
-
- g_object_unref (pb);
- pb = tmp;
- }
- }
-
- /* add icon to the hash table so we don't load it again */
- loaded = TRUE;
- }
-
- if (pb == NULL) {
- g_free (file);
- g_free (key);
- return NULL;
- }
-
- if (loaded &&
- (gdk_pixbuf_get_width (pb) != size &&
- gdk_pixbuf_get_height (pb) != size)) {
- GdkPixbuf *pb2;
- int dest_width;
- int dest_height;
- int width;
- int height;
-
- width = gdk_pixbuf_get_width (pb);
- height = gdk_pixbuf_get_height (pb);
-
- if (height > width) {
- dest_width = (size * width) / height;
- dest_height = size;
- } else {
- dest_width = size;
- dest_height = (size * height) / width;
- }
-
- pb2 = gdk_pixbuf_scale_simple (pb, dest_width, dest_height,
- GDK_INTERP_BILINEAR);
- g_object_unref (G_OBJECT (pb));
- pb = pb2;
- }
-
- if (loaded) {
- if (loaded_icons == NULL)
- loaded_icons = g_hash_table_new_full
- (g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) g_object_unref);
- g_hash_table_replace (loaded_icons,
- g_strdup (key),
- g_object_ref (G_OBJECT (pb)));
- g_object_weak_ref (G_OBJECT (pb),
- (GWeakNotify) remove_pixmap_from_loaded,
- g_strdup (key));
- } else {
- /* we didn't load from disk */
- if (long_operation != NULL)
- *long_operation = FALSE;
- }
-
- g_free (file);
- g_free (key);
-
- return pb;
-}
-
-static void
-menu_item_style_set (GtkImage *image,
- gpointer data)
-{
- GtkWidget *widget;
- GdkPixbuf *pixbuf;
- GtkIconSize icon_size = (GtkIconSize) GPOINTER_TO_INT (data);
- int icon_height;
- gboolean is_mapped;
-
- if (!gtk_icon_size_lookup (icon_size, NULL, &icon_height))
- return;
-
- pixbuf = gtk_image_get_pixbuf (image);
- if (!pixbuf)
- return;
-
- if (gdk_pixbuf_get_height (pixbuf) == icon_height)
- return;
-
- widget = GTK_WIDGET (image);
-
- is_mapped = gtk_widget_get_mapped (widget);
- if (is_mapped)
- gtk_widget_unmap (widget);
-
- gtk_image_set_from_pixbuf (image, NULL);
-
- if (is_mapped)
- gtk_widget_map (widget);
-}
-
-static void
-do_icons_to_add (void)
-{
- while (icons_to_add) {
- IconToAdd *icon_to_add = icons_to_add->data;
-
- icons_to_add = g_list_delete_link (icons_to_add, icons_to_add);
-
- if (icon_to_add->stock_id) {
- gtk_image_set_from_stock (
- GTK_IMAGE (icon_to_add->image),
- icon_to_add->stock_id,
- icon_to_add->icon_size);
- } else if (icon_to_add->gicon) {
- gtk_image_set_from_gicon (
- GTK_IMAGE (icon_to_add->image),
- icon_to_add->gicon,
- icon_to_add->icon_size);
- } else {
- g_assert (icon_to_add->pixbuf);
-
- gtk_image_set_from_pixbuf (
- GTK_IMAGE (icon_to_add->image),
- icon_to_add->pixbuf);
-
- g_signal_connect (icon_to_add->image, "style-set",
- G_CALLBACK (menu_item_style_set),
- GINT_TO_POINTER (icon_to_add->icon_size));
-
- g_object_unref (icon_to_add->pixbuf);
- }
-
- if (icon_to_add->gicon)
- g_object_unref (icon_to_add->gicon);
- g_object_unref (icon_to_add->image);
- g_free (icon_to_add);
- }
-}
-
-static gboolean
-load_icons_handler (gpointer data)
-{
- IconToLoad *icon;
- gboolean long_operation = FALSE;
-
-load_icons_handler_again:
-
- if (!icons_to_load) {
- load_icons_id = 0;
- do_icons_to_add ();
-
- return FALSE;
- }
-
- icon = icons_to_load->data;
- icons_to_load->data = NULL;
- /* pop */
- icons_to_load = g_list_delete_link (icons_to_load, icons_to_load);
-
- /* if not visible anymore, just ignore */
- if ( ! gtk_widget_get_visible (icon->pixmap)) {
- icon_to_load_free (icon);
- /* we didn't do anything long/hard, so just do this again,
- * this is fun, don't go back to main loop */
- goto load_icons_handler_again;
- }
-
- if (icon->stock_id || icon->gicon) {
- IconToAdd *icon_to_add;
-
- icon_to_add = g_new (IconToAdd, 1);
- icon_to_add->image = g_object_ref (icon->pixmap);
- icon_to_add->stock_id = icon->stock_id;
- icon_to_add->pixbuf = NULL;
- icon_to_add->icon_size = icon->icon_size;
- if (icon->gicon)
- icon_to_add->gicon = g_object_ref (icon->gicon);
- else
- icon_to_add->gicon = NULL;
-
- icons_to_add = g_list_prepend (icons_to_add, icon_to_add);
- } else {
- IconToAdd *icon_to_add;
- GdkPixbuf *pb;
- int icon_height = PANEL_DEFAULT_MENU_ICON_SIZE;
-
- gtk_icon_size_lookup (icon->icon_size, NULL, &icon_height);
-
- pb = panel_make_menu_icon (icon->icon_theme,
- icon->image,
- icon->fallback_image,
- icon_height,
- &long_operation);
- if (!pb) {
- icon_to_load_free (icon);
- if (long_operation)
- /* this may have been a long operation so jump back to
- * the main loop for a while */
- return TRUE;
- else
- /* we didn't do anything long/hard, so just do this again,
- * this is fun, don't go back to main loop */
- goto load_icons_handler_again;
- }
-
- icon_to_add = g_new (IconToAdd, 1);
- icon_to_add->image = g_object_ref (icon->pixmap);
- icon_to_add->stock_id = NULL;
- icon_to_add->gicon = NULL;
- icon_to_add->pixbuf = pb;
- icon_to_add->icon_size = icon->icon_size;
-
- icons_to_add = g_list_prepend (icons_to_add, icon_to_add);
- }
-
- icon_to_load_free (icon);
-
- if (!long_operation)
- /* we didn't do anything long/hard, so just do this again,
- * this is fun, don't go back to main loop */
- goto load_icons_handler_again;
-
- /* if still more we'll come back */
- return TRUE;
-}
-
-static void
add_app_to_panel (GtkWidget *item,
MateMenuTreeEntry *entry)
{
@@ -1128,38 +736,6 @@ drag_data_get_menu_cb (GtkWidget *widget,
g_free (uri_list);
}
-static void
-#if GTK_CHECK_VERSION (3, 0, 0)
-image_menuitem_set_size_request (GtkWidget *menuitem,
- GtkIconSize icon_size)
-#else
-image_menuitem_size_request (GtkWidget *menuitem,
- GtkRequisition *requisition,
- gpointer data)
-#endif
-{
-#if !GTK_CHECK_VERSION (3, 0, 0)
- GtkIconSize icon_size = (GtkIconSize) GPOINTER_TO_INT (data);
-#endif
- int icon_height;
- int req_height;
-
- if (!gtk_icon_size_lookup (icon_size, NULL, &icon_height))
- return;
-
- /* If we don't have a pixmap for this menuitem
- * at least make sure its the same height as
- * the rest.
- * This is a bit ugly, since we should keep this in sync with what's in
- * gtk_menu_item_size_request()
- */
- req_height = icon_height;
- req_height += (gtk_container_get_border_width (GTK_CONTAINER (menuitem)) +
- (gtk_widget_get_style (menuitem))->ythickness) * 2;
-
- gtk_widget_set_size_request (menuitem, -1, req_height);
-}
-
static char *
menu_escape_underscores_and_prepend (const char *text)
{
@@ -1222,21 +798,10 @@ setup_menuitem (GtkWidget *menuitem,
gtk_container_add (GTK_CONTAINER (menuitem), label);
if (image) {
- g_object_set_data_full (G_OBJECT (menuitem),
- "Panel:Image",
- g_object_ref (image),
- (GDestroyNotify) g_object_unref);
gtk_widget_show (image);
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
image);
- } else if (icon_size != GTK_ICON_SIZE_INVALID)
-#if GTK_CHECK_VERSION (3, 0, 0)
- image_menuitem_set_size_request (menuitem, icon_size);
-#else
- g_signal_connect (menuitem, "size_request",
- G_CALLBACK (image_menuitem_size_request),
- GINT_TO_POINTER (icon_size));
-#endif
+ }
gtk_widget_show (menuitem);
}
@@ -1850,45 +1415,6 @@ GtkWidget* create_main_menu(PanelWidget* panel)
return main_menu;
}
-static GList *
-find_in_load_list (GtkWidget *image)
-{
- GList *li;
- for (li = icons_to_load; li != NULL; li = li->next) {
- IconToLoad *icon = li->data;
- if (icon->pixmap == image)
- return li;
- }
- return NULL;
-}
-
-static void
-image_menu_shown (GtkWidget *image, gpointer data)
-{
- IconToLoad *new_icon;
- IconToLoad *icon;
-
- icon = (IconToLoad *) data;
-
- /* if we've already handled this */
- if (gtk_image_get_storage_type (GTK_IMAGE (image)) != GTK_IMAGE_EMPTY)
- return;
-
- if (find_in_load_list (image) == NULL) {
- new_icon = icon_to_load_copy (icon);
- new_icon->icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (image));
- icons_to_load = g_list_append (icons_to_load, new_icon);
- }
- if (load_icons_id == 0)
- load_icons_id = g_idle_add (load_icons_handler, NULL);
-}
-
-static void
-image_menu_destroy (GtkWidget *image, gpointer data)
-{
- image_menu_items = g_slist_remove (image_menu_items, image);
-}
-
static void
panel_load_menu_image_deferred (GtkWidget *image_menu_item,
GtkIconSize icon_size,
@@ -1897,47 +1423,32 @@ panel_load_menu_image_deferred (GtkWidget *image_menu_item,
const char *image_filename,
const char *fallback_image_filename)
{
- IconToLoad *icon;
GtkWidget *image;
int icon_height = PANEL_DEFAULT_MENU_ICON_SIZE;
- icon = g_new (IconToLoad, 1);
-
gtk_icon_size_lookup (icon_size, NULL, &icon_height);
image = gtk_image_new ();
- gtk_widget_set_size_request (image, icon_height, icon_height);
+ g_object_set (image, "icon-size", icon_size, NULL);
+ gtk_image_set_pixel_size (GTK_IMAGE(image), icon_height);
- /* this takes over the floating ref */
- icon->pixmap = g_object_ref_sink (G_OBJECT (image));
+ GIcon *icon = NULL;
- icon->stock_id = stock_id;
- if (gicon)
- icon->gicon = g_object_ref (gicon);
- else
- icon->gicon = NULL;
- icon->image = g_strdup (image_filename);
- icon->fallback_image = g_strdup (fallback_image_filename);
- icon->icon_size = icon_size;
+ if (gicon != NULL) {
+ icon = g_object_ref (gicon);
+ } else if (stock_id != NULL ) {
+ icon = g_themed_icon_new (stock_id);
+ } else if (image_filename != NULL) {
+ icon = panel_gicon_from_icon_name (image_filename);
+ }
- gtk_widget_show (image);
+ gtk_image_set_from_gicon (GTK_IMAGE(image), icon, icon_size);
+ g_object_unref (icon);
- g_object_set_data_full (G_OBJECT (image_menu_item),
- "Panel:Image",
- g_object_ref (image),
- (GDestroyNotify) g_object_unref);
+ gtk_widget_show (image);
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (image_menu_item),
image);
-
- g_signal_connect_data (image, "map",
- G_CALLBACK (image_menu_shown), icon,
- (GClosureNotify) icon_to_load_free, 0);
-
- g_signal_connect (image, "destroy",
- G_CALLBACK (image_menu_destroy), NULL);
-
- image_menu_items = g_slist_prepend (image_menu_items, image);
}
static gboolean