summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--gtk/Makefile.am1
-rw-r--r--gtk/gtkstatusicon-quartz.c148
-rwxr-xr-xgtk/gtkstatusicon.c104
4 files changed, 258 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index ec8234622e..59053d1fc2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2006-12-20 Mikael Hallendal <micke@imendio.com>
+
+ * gtk/Makefile.am: Added gtkstatusicon-quartz.c
+ * gtk/gtkstatusicon-quartz.c: Implements the quartz backend for the
+ status icon.
+ * gtk/gtkstatusicon.c: Hooked in the new quartz backend. Bug #387874.
+
2006-12-19 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkprintunixdialog.c: Add a tooltip explaining the
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index 4c07d1e461..36ad0292cb 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -697,6 +697,7 @@ gtk_extra_sources = \
paper_names.c \
paper_names_offsets.c \
gen-paper-names.c \
+ gtkstatusicon-quartz.c \
gtk.symbols \
gtkversion.h.in \
gtkmarshalers.list \
diff --git a/gtk/gtkstatusicon-quartz.c b/gtk/gtkstatusicon-quartz.c
new file mode 100644
index 0000000000..8f8bb024c8
--- /dev/null
+++ b/gtk/gtkstatusicon-quartz.c
@@ -0,0 +1,148 @@
+/* gtkstatusicon-quartz.c:
+ *
+ * Copyright (C) 2006 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library 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.
+ *
+ * GCC on Mac OS X handles inlined objective C in C-files.
+ *
+ * Authors:
+ * Mikael Hallendal <micke@imendio.com>
+ */
+
+#import <Cocoa/Cocoa.h>
+#include <quartz/gdkquartz.h>
+
+#define QUARTZ_POOL_ALLOC NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]
+#define QUARTZ_POOL_RELEASE [pool release]
+
+@interface GtkQuartzStatusIcon : NSObject
+{
+ GtkStatusIcon *status_icon;
+ NSStatusBar *ns_bar;
+ NSStatusItem *ns_item;
+ NSImage *current_image;
+ NSString *ns_tooltip;
+}
+- (id) initWithStatusIcon:(GtkStatusIcon *)status_icon;
+- (void) ensureItem;
+- (void) actionCb:(NSObject *)button;
+- (void) setImage:(GdkPixbuf *)pixbuf;
+- (void) setVisible:(gboolean)visible;
+- (void) setToolTip:(const gchar *)tooltip_text;
+- (float) getWidth;
+- (float) getHeight;
+@end
+
+@implementation GtkQuartzStatusIcon : NSObject
+- (id) initWithStatusIcon:(GtkStatusIcon *)icon
+{
+ [super init];
+ status_icon = icon;
+ ns_bar = [NSStatusBar systemStatusBar];
+
+ return self;
+}
+
+- (void) ensureItem
+{
+ if (ns_item != nil)
+ return;
+
+ ns_item = [ns_bar statusItemWithLength:NSVariableStatusItemLength];
+ [ns_item setAction:@selector(actionCb:)];
+ [ns_item setTarget:self];
+ [ns_item retain];
+}
+
+- (void) dealloc
+{
+ g_print ("Deallocating GtkQuartzStatusIcon\n");
+ [current_image release];
+ [ns_item release];
+ [ns_bar release];
+
+ [super dealloc];
+}
+
+- (void) actionCb:(NSObject *)button
+{
+ NSEvent *event = [NSApp currentEvent];
+ double time = [event timestamp];
+
+ g_signal_emit (status_icon,
+ status_icon_signals [POPUP_MENU_SIGNAL], 0,
+ 1,
+ time * 1000.0);
+}
+
+- (void) setImage:(GdkPixbuf *)pixbuf
+{
+ /* Support NULL */
+ [self ensureItem];
+
+ if (current_image != nil) {
+ [current_image release];
+ current_image = nil;
+ }
+
+ if (!pixbuf) {
+ [ns_item release];
+ ns_item = nil;
+ return;
+ }
+
+ current_image = gdk_quartz_pixbuf_to_ns_image_libgtk_only (pixbuf);
+ [current_image retain];
+
+ [ns_item setImage:current_image];
+}
+
+- (void) setVisible:(gboolean)visible
+{
+ if (visible) {
+ [self ensureItem];
+ if (ns_item != nil)
+ [ns_item setImage:current_image];
+ if (ns_tooltip != nil)
+ [ns_item setToolTip:ns_tooltip];
+ } else {
+ [ns_item release];
+ ns_item = nil;
+ }
+}
+
+- (void) setToolTip:(const gchar *)tooltip_text
+{
+ [ns_tooltip release];
+ ns_tooltip = [[NSString stringWithUTF8String:tooltip_text] retain];
+
+ [ns_item setToolTip:ns_tooltip];
+}
+
+- (float) getWidth
+{
+ return [ns_bar thickness];
+}
+
+- (float) getHeight
+{
+ return [ns_bar thickness];
+}
+@end
+
+
+
diff --git a/gtk/gtkstatusicon.c b/gtk/gtkstatusicon.c
index 7ed3cb754a..047fd48df1 100755
--- a/gtk/gtkstatusicon.c
+++ b/gtk/gtkstatusicon.c
@@ -3,6 +3,7 @@
* Copyright (C) 2003 Sun Microsystems, Inc.
* Copyright (C) 2005 Hans Breuer <hans@breuer.org>
* Copyright (C) 2005 Novell, Inc.
+ * Copyright (C) 2006 Imendio AB
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,6 +24,7 @@
* Mark McLoughlin <mark@skynet.ie>
* Hans Breuer <hans@breuer.org>
* Tor Lillqvist <tml@novell.com>
+ * Mikael Hallendal <micke@imendio.com>
*/
#include <config.h>
@@ -47,6 +49,11 @@
#define WM_GTK_TRAY_NOTIFICATION (WM_USER+1)
#endif
+#ifdef GDK_WINDOWING_QUARTZ
+#include "gtkicontheme.h"
+#include "gtklabel.h"
+#endif
+
#include "gtkalias.h"
#define BLINK_TIMEOUT 500
@@ -73,6 +80,12 @@ enum
LAST_SIGNAL
};
+static guint status_icon_signals [LAST_SIGNAL] = { 0 };
+
+#ifdef GDK_WINDOWING_QUARTZ
+#include "gtkstatusicon-quartz.c"
+#endif
+
struct _GtkStatusIconPrivate
{
#ifdef GDK_WINDOWING_X11
@@ -85,6 +98,11 @@ struct _GtkStatusIconPrivate
GtkWidget *dummy_widget;
NOTIFYICONDATAW nid;
#endif
+
+#ifdef GDK_WINDOWING_QUARTZ
+ GtkWidget *dummy_widget;
+ GtkQuartzStatusIcon *status_item;
+#endif
gint size;
@@ -130,8 +148,6 @@ static void gtk_status_icon_disable_blinking (GtkStatusIcon *status_icon);
static void gtk_status_icon_reset_image_data (GtkStatusIcon *status_icon);
-static guint status_icon_signals [LAST_SIGNAL] = { 0 };
-
G_DEFINE_TYPE (GtkStatusIcon, gtk_status_icon, G_TYPE_OBJECT)
static void
@@ -466,6 +482,20 @@ gtk_status_icon_init (GtkStatusIcon *status_icon)
priv->nid.hWnd = NULL;
}
#endif
+
+#ifdef GDK_WINDOWING_QUARTZ
+ priv->dummy_widget = gtk_label_new ("");
+
+ QUARTZ_POOL_ALLOC;
+
+ priv->status_item = [[GtkQuartzStatusIcon alloc] initWithStatusIcon:status_icon];
+
+ priv->image_height = [priv->status_item getHeight];
+ priv->image_width = [priv->status_item getWidth];
+
+ QUARTZ_POOL_RELEASE;
+
+#endif
}
static void
@@ -496,6 +526,12 @@ gtk_status_icon_finalize (GObject *object)
gtk_widget_destroy (priv->dummy_widget);
#endif
+
+#ifdef GDK_WINDOWING_QUARTZ
+ QUARTZ_POOL_ALLOC;
+ [priv->status_item release];
+ QUARTZ_POOL_RELEASE;
+#endif
G_OBJECT_CLASS (gtk_status_icon_parent_class)->finalize (object);
}
@@ -816,6 +852,11 @@ gtk_status_icon_update_image (GtkStatusIcon *status_icon)
if (!Shell_NotifyIconW (NIM_MODIFY, &priv->nid))
g_warning ("%s:%d:Shell_NotifyIcon(NIM_MODIFY) failed", __FILE__, __LINE__-1);
#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ QUARTZ_POOL_ALLOC;
+ [priv->status_item setImage:gtk_status_icon_blank_icon (status_icon)];
+ QUARTZ_POOL_RELEASE;
+#endif
return;
}
@@ -857,6 +898,12 @@ gtk_status_icon_update_image (GtkStatusIcon *status_icon)
if (!Shell_NotifyIconW (NIM_MODIFY, &priv->nid))
g_warning ("%s:%d:Shell_NotifyIcon(NIM_MODIFY) failed", __FILE__, __LINE__-1);
#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ QUARTZ_POOL_ALLOC;
+ [priv->status_item setImage:scaled];
+ QUARTZ_POOL_RELEASE;
+#endif
+
g_object_unref (scaled);
}
else
@@ -870,6 +917,9 @@ gtk_status_icon_update_image (GtkStatusIcon *status_icon)
if (!Shell_NotifyIconW (NIM_MODIFY, &priv->nid))
g_warning ("%s:%d:Shell_NotifyIcon(NIM_MODIFY) failed", __FILE__, __LINE__-1);
#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ [priv->status_item setImage:NULL];
+#endif
}
}
break;
@@ -897,6 +947,20 @@ gtk_status_icon_update_image (GtkStatusIcon *status_icon)
g_object_unref (pixbuf);
}
#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ {
+ GdkPixbuf *pixbuf;
+
+ pixbuf = gtk_widget_render_icon (priv->dummy_widget,
+ priv->image_data.stock_id,
+ GTK_ICON_SIZE_SMALL_TOOLBAR,
+ NULL);
+ QUARTZ_POOL_ALLOC;
+ [priv->status_item setImage:pixbuf];
+ QUARTZ_POOL_RELEASE;
+ g_object_unref (pixbuf);
+ }
+#endif
}
break;
@@ -924,6 +988,22 @@ gtk_status_icon_update_image (GtkStatusIcon *status_icon)
g_object_unref (pixbuf);
}
#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ {
+ GdkPixbuf *pixbuf;
+
+ pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
+ priv->image_data.icon_name,
+ priv->size,
+ 0, NULL);
+
+ QUARTZ_POOL_ALLOC;
+ [priv->status_item setImage:pixbuf];
+ QUARTZ_POOL_RELEASE;
+ g_object_unref (pixbuf);
+ }
+#endif
+
}
break;
@@ -937,6 +1017,13 @@ gtk_status_icon_update_image (GtkStatusIcon *status_icon)
if (!Shell_NotifyIconW (NIM_MODIFY, &priv->nid))
g_warning ("%s:%d:Shell_NotifyIcon(NIM_MODIFY) failed", __FILE__, __LINE__-1);
#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ {
+ QUARTZ_POOL_ALLOC;
+ [priv->status_item setImage:NULL];
+ QUARTZ_POOL_RELEASE;
+ }
+#endif
break;
default:
g_assert_not_reached ();
@@ -1398,6 +1485,11 @@ gtk_status_icon_set_tooltip (GtkStatusIcon *status_icon,
if (!Shell_NotifyIconW (NIM_MODIFY, &priv->nid))
g_warning ("%s:%d:Shell_NotifyIconW(NIM_MODIFY) failed", __FILE__, __LINE__-1);
#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ QUARTZ_POOL_ALLOC;
+ [priv->status_item setToolTip:tooltip_text];
+ QUARTZ_POOL_RELEASE;
+#endif
}
static gboolean
@@ -1483,6 +1575,11 @@ gtk_status_icon_set_visible (GtkStatusIcon *status_icon,
Shell_NotifyIconW (NIM_DELETE, &priv->nid);
}
#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ QUARTZ_POOL_ALLOC;
+ [priv->status_item setVisible:visible];
+ QUARTZ_POOL_RELEASE;
+#endif
g_object_notify (G_OBJECT (status_icon), "visible");
}
}
@@ -1596,6 +1693,9 @@ gtk_status_icon_is_embedded (GtkStatusIcon *status_icon)
#ifdef GDK_WINDOWING_WIN32
return TRUE;
#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ return TRUE;
+#endif
}
/**