[gtk-mac-integration] Adjustments and fixes to 4620977



commit 578c1a08652972aa8002a5e6da1014a95c44c2d9
Author: John Ralls <jralls ceridwen us>
Date:   Tue Sep 25 17:07:28 2012 -0700

    Adjustments and fixes to 4620977
    
    - Remove Inkscape-only image-in-a-widget handler. It breaks more common
    cases
    - Fix up formatting to Gnome coding standards (yes, there's plenty of
    other code here that needs the same treatment).
    - Move nsimage_from_pixbuf() and nsimage_from_resource() to a new file
    gtkosx-image.c so that they can be used in both
    gtkosxapplication_quartz.c and cocoa_menu_item.c
    - Introduce a new configure option, --enable-menu-images, to turn on the
    feature (it's disabled by default to prevent surprises).
    - Only set the image on the cocoa_item if there is one

 configure.ac                   |    8 ++
 src/Makefile.am                |    6 +-
 src/cocoa_menu_item.c          |  144 +++++++++++++---------------------------
 src/gtkosx-image.c             |   97 +++++++++++++++++++++++++++
 src/gtkosx-image.h             |   35 ++++++++++
 src/gtkosxapplication_quartz.c |   69 +-------------------
 6 files changed, 192 insertions(+), 167 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 921f3e2..92341fc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -37,6 +37,14 @@ fi
 
 GTK_DOC_CHECK([1.11], [--flavour no-tmpl])
 
+AC_ARG_ENABLE([menu-images],
+    [AS_HELP_STRING([--enable-menu-images],
+     [Include menu item icons in Mac menus @<:@default=no@:>@])],
+    [],
+    [enable_menu_images=no])
+AS_IF([test "x$enable_menu_images" != xno],
+      [AC_DEFINE([USE_MENU_IMAGES], 1, [Add images to menu items])])
+
 AC_ARG_WITH([gtk],
 	[AS_HELP_STRING([--with-gtk],
 		[select gtk+-3.0 or gtk+-2.0. @<:@default=check@:>@])],
diff --git a/src/Makefile.am b/src/Makefile.am
index 8e273ba..ebde188 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -19,9 +19,11 @@ libgtkmacintegration_la_SOURCES =			\
 	cocoa_menu.c					\
 	cocoa_menu_item.h				\
 	cocoa_menu_item.c				\
-	gtkosxapplication_quartz.c				\
+	gtkosxapplication_quartz.c			\
 	gtkosxapplication.c				\
-	gtkosxapplicationprivate.h				\
+	gtkosxapplicationprivate.h			\
+	gtkosx-image.c					\
+	gtkosx-image.h					\
 	gtk-mac-dock.c					\
 	gtk-mac-bundle.c				\
 	gtk-mac-menu.c					\
diff --git a/src/cocoa_menu_item.c b/src/cocoa_menu_item.c
index 03bd856..f089569 100644
--- a/src/cocoa_menu_item.c
+++ b/src/cocoa_menu_item.c
@@ -20,9 +20,10 @@
  * Boston, MA 02111-1307, USA.
  */
 
+#include <config.h>
 #import <Cocoa/Cocoa.h>
 #include <gtk/gtk.h>
-#if GTK_CHECK_VERSION(2,90,7)
+#if GTK_MAJOR_VERSION == 3
 #include <gdk/gdkkeysyms-compat.h>
 #else
 #include <gdk/gdkkeysyms.h>
@@ -31,7 +32,7 @@
 #include "cocoa_menu_item.h"
 #include "cocoa_menu.h"
 #include "getlabel.h"
-#include "gtk-mac-image-utils.h"
+#include "gtkosx-image.h"
 #import "GNSMenuBar.h"
 
 //#define DEBUG(format, ...) g_printerr ("%s: " format, G_STRFUNC, ## __VA_ARGS__)
@@ -446,107 +447,55 @@ cocoa_menu_item_sync (GtkWidget* menu_item)
 
 }
 
-/*
- * nsimage_from_pixbuf:
- * @pixbuf: The GdkPixbuf* to convert
- *
- * Create an NSImage from a CGImageRef.
- * Lifted from http://www.cocoadev.com/index.pl?CGImageRef
- *
- * Returns: An auto-released NSImage*
- */
-static NSImage*
-nsimage_from_pixbuf(GdkPixbuf *pixbuf)
-{
-  CGImageRef image = NULL;
-  NSRect imageRect = NSMakeRect(0.0, 0.0, 0.0, 0.0);
-  CGContextRef imageContext = nil;
-  NSImage* newImage = nil;
-
-  g_return_val_if_fail (pixbuf !=  NULL, NULL);
-  image = gtkosx_create_cgimage_from_pixbuf (pixbuf);
-  // Get the image dimensions.
-  imageRect.size.height = CGImageGetHeight(image);
-  imageRect.size.width = CGImageGetWidth(image);
-
-  // Create a new image to receive the Quartz image data.
-  newImage = [[[NSImage alloc] initWithSize:imageRect.size] autorelease];
-  [newImage lockFocus];
-
-  // Get the Quartz context and draw.
-  imageContext = (CGContextRef)[[NSGraphicsContext currentContext]
-                                graphicsPort];
-  CGContextDrawImage(imageContext, *(CGRect*)&imageRect, image);
-  [newImage unlockFocus];
-  CGImageRelease (image);
-  return newImage;
-}
 
 /*
- * If the menu item does contain an image Widget, depending of what this widget is,
- * get a PixBuf with the following method:
- *   - menu_item is GtkImage of type GTK_IMAGE_PIXBUF: use gtk_image_get_pixbuf()
- *   - menu_item is GtkImage of type GTK_IMAGE_STOCK: use gtk_widget_render_icon()
- *   - menu_item is GtkWidget: use gtk_offscreen_window_get_pixbuf() on GtkOffscreenWindow
+ * If the menu item does contain an image Widget, depending of what
+ * this widget is, get a PixBuf with the following method: - menu_item
+ * is GtkImage of type GTK_IMAGE_PIXBUF: use gtk_image_get_pixbuf() -
+ * menu_item is GtkImage of type GTK_IMAGE_STOCK: use
+ * gtk_widget_render_icon() - menu_item is GtkWidget: use
+ * gtk_offscreen_window_get_pixbuf() on GtkOffscreenWindow
  */
+#ifdef USE_MENU_IMAGES
 static void
 cocoa_menu_item_add_item_image (_GNSMenuItem* cocoa_item, GtkWidget* menu_item)
 {
-  GtkWidget *menu_image = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM(menu_item));
-
-  if (menu_image) {
-    NSImage *image = nil;
-    if (GTK_IS_IMAGE (menu_image)) {
-      if (gtk_image_get_storage_type(GTK_IMAGE(menu_image)) == GTK_IMAGE_PIXBUF) {
-        DEBUG("Menu image is GTK_IMAGE_PIXBUF\n");
-        GdkPixbuf *pixbuf = gtk_image_get_pixbuf(GTK_IMAGE(menu_image));
-        image = nsimage_from_pixbuf(pixbuf);
-      }
-      else if (gtk_image_get_storage_type(GTK_IMAGE(menu_image)) == GTK_IMAGE_STOCK) {
-        DEBUG("Menu image is GTK_IMAGE_STOCK\n");
-        gchar *stock_id;
-        GtkIconSize size;
-        gtk_image_get_stock(GTK_IMAGE(menu_image), &stock_id, &size);
-        GdkPixbuf *pixbuf = gtk_widget_render_icon(menu_image, stock_id, size, "");
-        image = nsimage_from_pixbuf(pixbuf);
-        g_object_unref(pixbuf);
-      }
-    }
-    if (!image) {
-      DEBUG("Menu image is GTK_WIDGET\n");
-      // Take menu image widget out of menu item
-      g_object_ref(menu_image);
-      gtk_widget_unparent (menu_image);
-      GTK_IMAGE_MENU_ITEM(menu_item)->image = NULL;
-      g_object_notify(G_OBJECT(menu_item), "image");
-      // Put menu image widget in Offscreen Window, take a pixbuf
-      GtkWidget *offscreenWindow = gtk_offscreen_window_new();
-      gtk_container_add(GTK_CONTAINER(offscreenWindow), menu_image);
-      // Show with proper size
-      gtk_widget_show_all(offscreenWindow);
-      GtkRequisition req;
-      GtkAllocation alloc;
-      gtk_widget_size_request (menu_image, &req);
-      alloc.x = alloc.y = 0;
-      alloc.width = req.width;
-      alloc.height = req.height;
-      gtk_widget_size_allocate (menu_image, &alloc);
-      while (gtk_events_pending ())
-        gtk_main_iteration_do (FALSE);
-      // Take a pixbuf of the offscreen window, convert to image
-      GdkPixbuf *pixbuf = gtk_offscreen_window_get_pixbuf(GTK_OFFSCREEN_WINDOW(offscreenWindow));
-      image = nsimage_from_pixbuf(pixbuf);
-      g_object_unref(pixbuf);
-      // Take menu image widget out of offscreen window, back into menu item
-      gtk_container_remove(GTK_CONTAINER(offscreenWindow), menu_image);
-      gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menu_item), menu_image);
-      g_object_unref(menu_image);
+  GtkImageMenuItem *image_menu_item = GTK_MENU_ITEM (menu_item);
+  GtkWidget *menu_widget = gtk_image_menu_item_get_image (image_menu_item);
+  GdkPixbuf *pixbuf = NULL;
+  NSImage *image = nil;
+
+  if (menu_widget == NULL)
+    return;
+
+  if (GTK_IS_IMAGE (menu_widget))
+    {
+      GtkImage *menu_image = menu_widget;
+      switch (gtk_image_get_storage_type (menu_image))
+	{
+	case GTK_IMAGE_PIXBUF:
+	  pixbuf = gtk_image_get_pixbuf (menu_image);
+	  image = nsimage_from_pixbuf (pixbuf);
+	  break;
+	case GTK_IMAGE_STOCK:
+	  {
+	    DEBUG("Menu image is GTK_IMAGE_STOCK\n");
+	    gchar *stock_id;
+	    GtkIconSize size;
+	    gtk_image_get_stock(menu_image, &stock_id, &size);
+	    pixbuf = gtk_widget_render_icon (menu_image, stock_id, size, "");
+	    image = nsimage_from_pixbuf (pixbuf);
+	    g_object_unref (pixbuf);
+	    break;
+	  }
+	default:
+	  return;
+	}
     }
+  if (image)
     [cocoa_item setImage: image];
-  }
-
 }
-
+#endif
 /*
  * Public Functions
  */
@@ -570,7 +519,7 @@ cocoa_menu_item_add_item (NSMenu* cocoa_menu, GtkWidget* menu_item, int index)
     [[cocoa_item menu] removeItem: cocoa_item];
   }
 
-  if (GTK_IS_SEPARATOR_MENU_ITEM (menu_item)) {
+  if (GTK_IS_SEPARATOR_MENU_ITEM (GTK_MENU_ITEM (menu_item))) {
     cocoa_item = (_GNSMenuItem*)[_GNSMenuItem separatorItem];
     DEBUG ("\ta separator\n");
   } else {
@@ -589,9 +538,10 @@ cocoa_menu_item_add_item (NSMenu* cocoa_menu, GtkWidget* menu_item, int index)
     DEBUG ("\tan item\n");
   }
   cocoa_menu_item_connect (menu_item, (_GNSMenuItem*) cocoa_item, label);
-  if (GTK_IS_IMAGE_MENU_ITEM (menu_item)) {
+#ifdef USE_MENU_IMAGES
+  if (GTK_IS_IMAGE_MENU_ITEM (menu_item))
     cocoa_menu_item_add_item_image(cocoa_item, menu_item);
-  }
+#endif
   [ cocoa_item setEnabled:YES];
 
   /* connect GtkMenuItem and _GNSMenuItem so that we can notice changes
diff --git a/src/gtkosx-image.c b/src/gtkosx-image.c
new file mode 100644
index 0000000..668a6ed
--- /dev/null
+++ b/src/gtkosx-image.c
@@ -0,0 +1,97 @@
+/* GTK+ application-level integration for the Mac OS X/Cocoa 
+ *
+ * Copyright (C) 2007 Pioneer Research Center USA, Inc.
+ * Copyright (C) 2007 Imendio AB
+ * Copyright (C) 2009 Paul Davis
+ *
+ * This is a reimplementation in Cocoa of the sync-menu.c concept
+ * from Imendio, although without the "set quit menu" API since
+ * a Cocoa app needs to handle termination anyway.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1
+ * of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include "gtkosx-image.h"
+#include "gtk-mac-image-utils.h"
+
+/**
+ * nsimage_from_resource:
+ * @name: The filename
+ * @type: The extension (e.g., jpg) of the filename
+ * @subdir: The subdirectory of $Bundle/Contents/Resources in which to
+ * look for the file.
+ *
+ * Retrieve an image file from the bundle and return an NSImage* of it.
+ *
+ * Returns: An autoreleased NSImage
+ */
+NSImage*
+nsimage_from_resource(const gchar *name, const gchar* type, const gchar* subdir)
+{
+  NSString *ns_name, *ns_type, *ns_subdir, *path;
+  NSImage *image = NULL; 
+  g_return_val_if_fail(name != NULL, NULL);
+  g_return_val_if_fail(type != NULL, NULL);
+  g_return_val_if_fail(subdir != NULL, NULL);
+
+  ns_name = [NSString stringWithUTF8String: name];
+  ns_type = [NSString stringWithUTF8String: type];
+  ns_subdir = [NSString stringWithUTF8String: subdir];
+  path = [[NSApp mainBundle] pathForResource: ns_name
+		     ofType: ns_type inDirectory: ns_subdir];
+  if (path) 
+  image = [[[NSImage alloc] initWithContentsOfFile: path] autorelease];
+
+  return image;
+}
+
+/*
+ * nsimage_from_pixbuf:
+ * @pixbuf: The GdkPixbuf* to convert
+ *
+ * Create an NSImage from a CGImageRef.
+ * Lifted from http://www.cocoadev.com/index.pl?CGImageRef
+ *
+ * Returns: An auto-released NSImage*
+ */
+NSImage*
+nsimage_from_pixbuf(GdkPixbuf *pixbuf)
+{
+  CGImageRef image = NULL;
+  NSRect imageRect = NSMakeRect(0.0, 0.0, 0.0, 0.0);
+  CGContextRef imageContext = nil;
+  NSImage* newImage = nil;
+
+  g_return_val_if_fail (pixbuf !=  NULL, NULL);
+  image = gtkosx_create_cgimage_from_pixbuf (pixbuf);
+  // Get the image dimensions.
+  imageRect.size.height = CGImageGetHeight(image);
+  imageRect.size.width = CGImageGetWidth(image);
+
+  // Create a new image to receive the Quartz image data.
+  newImage = [[[NSImage alloc] initWithSize:imageRect.size] autorelease];
+  [newImage lockFocus];
+
+  // Get the Quartz context and draw.
+  imageContext = (CGContextRef)[[NSGraphicsContext currentContext]
+				graphicsPort];
+  CGContextDrawImage(imageContext, *(CGRect*)&imageRect, image);
+  [newImage unlockFocus];
+  CGImageRelease (image);
+  return newImage;
+}
diff --git a/src/gtkosx-image.h b/src/gtkosx-image.h
new file mode 100644
index 0000000..076d9d4
--- /dev/null
+++ b/src/gtkosx-image.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2007 Imendio AB
+ *
+ * This library is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GTKOSX_IMAGE_H__
+#define __GTKOSX_IMAGE_H__
+
+#import <Cocoa/Cocoa.h>
+
+G_BEGIN_DECLS
+
+NSImage* nsimage_from_resource(const gchar *name,
+			       const gchar* type,
+			       const gchar* subdir);
+
+NSImage* nsimage_from_pixbuf(GdkPixbuf *pixbuf);
+
+G_END_DECLS
+
+#endif /* __GTKOSX_IMAGE_H__ */
diff --git a/src/gtkosxapplication_quartz.c b/src/gtkosxapplication_quartz.c
index 7d1050e..ebfe5a8 100644
--- a/src/gtkosxapplication_quartz.c
+++ b/src/gtkosxapplication_quartz.c
@@ -36,7 +36,7 @@
 #include "cocoa_menu_item.h"
 #include "cocoa_menu.h"
 #include "getlabel.h"
-#include "gtk-mac-image-utils.h"
+#include "gtkosx-image.h"
 
 /* This is a private function in libgdk; we need to have is so that we
    can force new windows onto the Window menu */
@@ -845,73 +845,6 @@ gtkosx_application_set_dock_menu(GtkosxApplication *self,
   }
 }
 
-/*
- * nsimage_from_resource:
- * @name: The filename
- * @type: The extension (e.g., jpg) of the filename
- * @subdir: The subdirectory of $Bundle/Contents/Resources in which to
- * look for the file.
- *
- * Retrieve an image file from the bundle and return an NSImage* of it.
- *
- * Returns: An autoreleased NSImage
- */
-static NSImage*
-nsimage_from_resource(const gchar *name, const gchar* type, const gchar* subdir)
-{
-  NSString *ns_name, *ns_type, *ns_subdir, *path;
-  NSImage *image = NULL; 
-  g_return_val_if_fail(name != NULL, NULL);
-  g_return_val_if_fail(type != NULL, NULL);
-  g_return_val_if_fail(subdir != NULL, NULL);
-
-  ns_name = [NSString stringWithUTF8String: name];
-  ns_type = [NSString stringWithUTF8String: type];
-  ns_subdir = [NSString stringWithUTF8String: subdir];
-  path = [[NSApp mainBundle] pathForResource: ns_name
-		     ofType: ns_type inDirectory: ns_subdir];
-  if (path) 
-  image = [[[NSImage alloc] initWithContentsOfFile: path] autorelease];
-
-  return image;
-}
-
-/*
- * nsimage_from_pixbuf:
- * @pixbuf: The GdkPixbuf* to convert
- *
- * Create an NSImage from a CGImageRef.
- * Lifted from http://www.cocoadev.com/index.pl?CGImageRef
- *
- * Returns: An auto-released NSImage*
- */
-static NSImage*
-nsimage_from_pixbuf(GdkPixbuf *pixbuf)
-{
-  CGImageRef image = NULL;
-  NSRect imageRect = NSMakeRect(0.0, 0.0, 0.0, 0.0);
-  CGContextRef imageContext = nil;
-  NSImage* newImage = nil;
-
-  g_return_val_if_fail (pixbuf !=  NULL, NULL);
-  image = gtkosx_create_cgimage_from_pixbuf (pixbuf);
-  // Get the image dimensions.
-  imageRect.size.height = CGImageGetHeight(image);
-  imageRect.size.width = CGImageGetWidth(image);
-
-  // Create a new image to receive the Quartz image data.
-  newImage = [[[NSImage alloc] initWithSize:imageRect.size] autorelease];
-  [newImage lockFocus];
-
-  // Get the Quartz context and draw.
-  imageContext = (CGContextRef)[[NSGraphicsContext currentContext]
-				graphicsPort];
-  CGContextDrawImage(imageContext, *(CGRect*)&imageRect, image);
-  [newImage unlockFocus];
-  CGImageRelease (image);
-  return newImage;
-}
-
 /**
  * gtkosx_application_set_dock_icon_pixbuf:
  * @self: The GtkosxApplication



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]