Added gtkstatusicon-quartz.c Implements the quartz backend for the status

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.
This commit is contained in:
Mikael Hallendal 2006-12-20 13:24:05 +00:00 committed by Mikael Hallendal
parent ce503485cb
commit f18b0d4b7a
4 changed files with 258 additions and 2 deletions

View File

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

View File

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

148
gtk/gtkstatusicon-quartz.c Normal file
View File

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

View File

@ -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);
}
@ -815,6 +851,11 @@ gtk_status_icon_update_image (GtkStatusIcon *status_icon)
if (priv->nid.hWnd != NULL && priv->visible)
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
@ -869,6 +916,9 @@ gtk_status_icon_update_image (GtkStatusIcon *status_icon)
if (priv->nid.hWnd != NULL && priv->visible)
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
}
}
@ -896,6 +946,20 @@ gtk_status_icon_update_image (GtkStatusIcon *status_icon)
g_warning ("%s:%d:Shell_NotifyIcon(NIM_MODIFY) failed", __FILE__, __LINE__-1);
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;
@ -936,6 +1016,13 @@ gtk_status_icon_update_image (GtkStatusIcon *status_icon)
if (priv->nid.hWnd != NULL && priv->visible)
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:
@ -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
@ -1482,6 +1574,11 @@ gtk_status_icon_set_visible (GtkStatusIcon *status_icon,
else
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
}
/**