$(__BASE_AND_GUI_TOOLKIT_SRC_OBJECTS_5) \
$(__CORE_SRC_OBJECTS_3)
CORELIB_ODEP = $(___pch_wxprec_corelib_wx_wxprec_h_gch___depname)
+ADVDLL_CFLAGS = $(__advdll_PCH_INC) -D__WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p) \
+ $(__INC_TIFF_p) $(__INC_JPEG_p) $(__INC_PNG_p) $(__INC_ZLIB_p) \
+ $(__INC_ODBC_p) $(__INC_REGEX_p) $(__INC_EXPAT_p) -DWXUSINGDLL \
+ -DWXMAKINGDLL_ADV $(PIC_FLAG) $(CPPFLAGS) $(CFLAGS)
ADVDLL_CXXFLAGS = $(__advdll_PCH_INC) -D__WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p) \
$(__INC_TIFF_p) $(__INC_JPEG_p) $(__INC_PNG_p) $(__INC_ZLIB_p) \
$(__INC_ODBC_p) $(__INC_REGEX_p) $(__INC_EXPAT_p) -DWXUSINGDLL \
$(__ADVANCED_PLATFORM_SRC_OBJECTS_2) \
$(__PLUGIN_ADV_SRC_OBJECTS_2)
ADVDLL_ODEP = $(___pch_wxprec_advdll_wx_wxprec_h_gch___depname)
+ADVLIB_CFLAGS = $(__advlib_PCH_INC) -D__WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p) \
+ $(__INC_TIFF_p) $(__INC_JPEG_p) $(__INC_PNG_p) $(__INC_ZLIB_p) \
+ $(__INC_ODBC_p) $(__INC_REGEX_p) $(__INC_EXPAT_p) $(CPPFLAGS) $(CFLAGS)
ADVLIB_CXXFLAGS = $(__advlib_PCH_INC) -D__WX$(TOOLKIT)__ $(__WXUNIV_DEFINE_p) \
$(__INC_TIFF_p) $(__INC_JPEG_p) $(__INC_PNG_p) $(__INC_ZLIB_p) \
$(__INC_ODBC_p) $(__INC_REGEX_p) $(__INC_EXPAT_p) $(CPPFLAGS) $(CXXFLAGS)
monodll_taskbarcmn.o \
monodll_joystick.o \
monodll_sound.o \
- monodll_taskbarx11.o
+ monodll_taskbarx11.o \
+ monodll_taskbar.o \
+ monodll_eggtrayicon.o
@COND_TOOLKIT_GTK@__ADVANCED_PLATFORM_SRC_OBJECTS = $(COND_TOOLKIT_GTK___ADVANCED_PLATFORM_SRC_OBJECTS)
@COND_TOOLKIT_MAC@__ADVANCED_PLATFORM_SRC_OBJECTS = \
@COND_TOOLKIT_MAC@ monodll_joystick.o monodll_sound.o
monolib_taskbarcmn.o \
monolib_joystick.o \
monolib_sound.o \
- monolib_taskbarx11.o
+ monolib_taskbarx11.o \
+ monolib_taskbar.o \
+ monolib_eggtrayicon.o
@COND_TOOLKIT_GTK@__ADVANCED_PLATFORM_SRC_OBJECTS_1 = $(COND_TOOLKIT_GTK___ADVANCED_PLATFORM_SRC_OBJECTS_1)
@COND_TOOLKIT_MAC@__ADVANCED_PLATFORM_SRC_OBJECTS_1 = \
@COND_TOOLKIT_MAC@ monolib_joystick.o monolib_sound.o
$(DLLPREFIX)$(WXDLLNAMEPREFIXGUI)$(WXUNICODEFLAG)$(WXDEBUGFLAG)_adv$(WXCOMPILER)$(VENDORTAG)$(WXDLLVERSIONTAG)$(dll___targetsuf2) \
$(LIBPREFIX)wx_$(PORTNAME)$(WXUNIVNAME)$(WXUNICODEFLAG)$(WXDEBUGFLAG)_adv-2.5$(HOST_SUFFIX).$(DLLIMP_SUFFIX)
@COND_USE_SOSYMLINKS_1@__advdll___so_symlinks_inst_cmd = $(COND_USE_SOSYMLINKS_1___advdll___so_symlinks_inst_cmd)
-@COND_TOOLKIT_GTK@__ADVANCED_PLATFORM_SRC_OBJECTS_2 = \
-@COND_TOOLKIT_GTK@ advdll_taskbarcmn.o advdll_joystick.o advdll_sound.o \
-@COND_TOOLKIT_GTK@ advdll_taskbarx11.o
+COND_TOOLKIT_GTK___ADVANCED_PLATFORM_SRC_OBJECTS_2 = \
+ advdll_taskbarcmn.o \
+ advdll_joystick.o \
+ advdll_sound.o \
+ advdll_taskbarx11.o \
+ advdll_taskbar.o \
+ advdll_eggtrayicon.o
+@COND_TOOLKIT_GTK@__ADVANCED_PLATFORM_SRC_OBJECTS_2 = $(COND_TOOLKIT_GTK___ADVANCED_PLATFORM_SRC_OBJECTS_2)
@COND_TOOLKIT_MAC@__ADVANCED_PLATFORM_SRC_OBJECTS_2 = \
@COND_TOOLKIT_MAC@ advdll_joystick.o advdll_sound.o
@COND_TOOLKIT_MOTIF@__ADVANCED_PLATFORM_SRC_OBJECTS_2 = \
@COND_GCC_PCH_1@__advlib_PCH_INC = -I.pch/wxprec_advlib
@COND_GCC_PCH_1@___pch_wxprec_advlib_wx_wxprec_h_gch___depname \
@COND_GCC_PCH_1@ = .pch/wxprec_advlib/wx/wxprec.h.gch
-@COND_TOOLKIT_GTK@__ADVANCED_PLATFORM_SRC_OBJECTS_3 = \
-@COND_TOOLKIT_GTK@ advlib_taskbarcmn.o advlib_joystick.o advlib_sound.o \
-@COND_TOOLKIT_GTK@ advlib_taskbarx11.o
+COND_TOOLKIT_GTK___ADVANCED_PLATFORM_SRC_OBJECTS_3 = \
+ advlib_taskbarcmn.o \
+ advlib_joystick.o \
+ advlib_sound.o \
+ advlib_taskbarx11.o \
+ advlib_taskbar.o \
+ advlib_eggtrayicon.o
+@COND_TOOLKIT_GTK@__ADVANCED_PLATFORM_SRC_OBJECTS_3 = $(COND_TOOLKIT_GTK___ADVANCED_PLATFORM_SRC_OBJECTS_3)
@COND_TOOLKIT_MAC@__ADVANCED_PLATFORM_SRC_OBJECTS_3 = \
@COND_TOOLKIT_MAC@ advlib_joystick.o advlib_sound.o
@COND_TOOLKIT_MOTIF@__ADVANCED_PLATFORM_SRC_OBJECTS_3 = \
monodll_wizard.o: $(srcdir)/src/generic/wizard.cpp $(MONODLL_ODEP)
$(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $<
+monodll_eggtrayicon.o: $(srcdir)/src/gtk/eggtrayicon.c $(MONODLL_ODEP)
+ $(CCC) -c -o $@ $(MONODLL_CFLAGS) $<
+
monodll_helpbest.o: $(srcdir)/src/msw/helpbest.cpp $(MONODLL_ODEP)
$(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $<
@COND_TOOLKIT_WINCE_USE_GUI_1@monodll_taskbar.o: $(srcdir)/src/msw/taskbar.cpp $(MONODLL_ODEP)
@COND_TOOLKIT_WINCE_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $<
+@COND_TOOLKIT_GTK_USE_GUI_1@monodll_taskbar.o: $(srcdir)/src/gtk/taskbar.cpp $(MONODLL_ODEP)
+@COND_TOOLKIT_GTK_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $<
+
@COND_TOOLKIT_MSW_USE_GUI_1@monodll_joystick.o: $(srcdir)/src/msw/joystick.cpp $(MONODLL_ODEP)
@COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $<
monolib_wizard.o: $(srcdir)/src/generic/wizard.cpp $(MONOLIB_ODEP)
$(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $<
+monolib_eggtrayicon.o: $(srcdir)/src/gtk/eggtrayicon.c $(MONOLIB_ODEP)
+ $(CCC) -c -o $@ $(MONOLIB_CFLAGS) $<
+
monolib_helpbest.o: $(srcdir)/src/msw/helpbest.cpp $(MONOLIB_ODEP)
$(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $<
@COND_TOOLKIT_WINCE_USE_GUI_1@monolib_taskbar.o: $(srcdir)/src/msw/taskbar.cpp $(MONOLIB_ODEP)
@COND_TOOLKIT_WINCE_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $<
+@COND_TOOLKIT_GTK_USE_GUI_1@monolib_taskbar.o: $(srcdir)/src/gtk/taskbar.cpp $(MONOLIB_ODEP)
+@COND_TOOLKIT_GTK_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $<
+
@COND_TOOLKIT_MSW_USE_GUI_1@monolib_joystick.o: $(srcdir)/src/msw/joystick.cpp $(MONOLIB_ODEP)
@COND_TOOLKIT_MSW_USE_GUI_1@ $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $<
advdll_wizard.o: $(srcdir)/src/generic/wizard.cpp $(ADVDLL_ODEP)
$(CXXC) -c -o $@ $(ADVDLL_CXXFLAGS) $<
+advdll_eggtrayicon.o: $(srcdir)/src/gtk/eggtrayicon.c $(ADVDLL_ODEP)
+ $(CCC) -c -o $@ $(ADVDLL_CFLAGS) $<
+
advdll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(ADVDLL_ODEP)
$(CXXC) -c -o $@ $(ADVDLL_CXXFLAGS) $<
@COND_TOOLKIT_WINCE@advdll_taskbar.o: $(srcdir)/src/msw/taskbar.cpp $(ADVDLL_ODEP)
@COND_TOOLKIT_WINCE@ $(CXXC) -c -o $@ $(ADVDLL_CXXFLAGS) $<
+@COND_TOOLKIT_GTK@advdll_taskbar.o: $(srcdir)/src/gtk/taskbar.cpp $(ADVDLL_ODEP)
+@COND_TOOLKIT_GTK@ $(CXXC) -c -o $@ $(ADVDLL_CXXFLAGS) $<
+
@COND_TOOLKIT_MSW@advdll_joystick.o: $(srcdir)/src/msw/joystick.cpp $(ADVDLL_ODEP)
@COND_TOOLKIT_MSW@ $(CXXC) -c -o $@ $(ADVDLL_CXXFLAGS) $<
advlib_wizard.o: $(srcdir)/src/generic/wizard.cpp $(ADVLIB_ODEP)
$(CXXC) -c -o $@ $(ADVLIB_CXXFLAGS) $<
+advlib_eggtrayicon.o: $(srcdir)/src/gtk/eggtrayicon.c $(ADVLIB_ODEP)
+ $(CCC) -c -o $@ $(ADVLIB_CFLAGS) $<
+
advlib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(ADVLIB_ODEP)
$(CXXC) -c -o $@ $(ADVLIB_CXXFLAGS) $<
@COND_TOOLKIT_WINCE@advlib_taskbar.o: $(srcdir)/src/msw/taskbar.cpp $(ADVLIB_ODEP)
@COND_TOOLKIT_WINCE@ $(CXXC) -c -o $@ $(ADVLIB_CXXFLAGS) $<
+@COND_TOOLKIT_GTK@advlib_taskbar.o: $(srcdir)/src/gtk/taskbar.cpp $(ADVLIB_ODEP)
+@COND_TOOLKIT_GTK@ $(CXXC) -c -o $@ $(ADVLIB_CXXFLAGS) $<
+
@COND_TOOLKIT_MSW@advlib_joystick.o: $(srcdir)/src/msw/joystick.cpp $(ADVLIB_ODEP)
@COND_TOOLKIT_MSW@ $(CXXC) -c -o $@ $(ADVLIB_CXXFLAGS) $<
wx/unix/taskbarx11.h
</set>
+<set var="ADVANCED_GTK_SRC" hints="files">
+ src/gtk/taskbar.cpp
+ src/gtk/eggtrayicon.c
+</set>
+
<!-- ====================================================================== -->
<!-- wxHTML -->
<if cond="TOOLKIT=='WINCE'">$(ADVANCED_MSW_SRC)</if>
<if cond="TOOLKIT=='MAC'">$(ADVANCED_MAC_SRC)</if>
<if cond="TOOLKIT=='MOTIF'">$(ADVANCED_UNIX_SRC)</if>
- <if cond="TOOLKIT=='GTK'">$(ADVANCED_UNIX_SRC)</if>
+ <if cond="TOOLKIT=='GTK'">$(ADVANCED_UNIX_SRC) $(ADVANCED_GTK_SRC)</if>
<if cond="TOOLKIT=='X11'">$(ADVANCED_UNIX_SRC)</if>
<if cond="TOOLKIT=='PM'">$(ADVANCED_OS2_SRC)</if>
</set>
OTHER CHANGES
=============
+2.5.3
+-----
+
+Unix:
+
+- wxTaskBarIcon now supports freedesktop.org System Tray protocol
+
+
2.5.2
-----
- <div> handling fix (Xavier Nodet)
Unix:
+
- fixed priorities of mailcap entries (David Hart)
- added "wx-config --libs=std,<extra>" syntax (i.e. support for "std")
wxODBC:
+
- Full Unicode support is now available
- BLOB support is working
\section{\class{wxTaskBarIcon}}\label{wxtaskbaricon}
-This class represents a taskbar icon, appearing in the `system tray' and responding to
-mouse clicks. An icon has an optional tooltip. This class is only supported for Windows 95/NT and for
-X Window System ports (wxGTK, wxMotif, wxX11), assuming the window manager supports KDE and GNOME 1.2
-systray methods.
+This class represents a taskbar icon, appearing in the `system tray' and
+responding to mouse clicks. An icon has an optional tooltip. This class is only
+supported under Windows 95/NT and in X Window System ports (wxGTK, wxMotif,
+wxX11).
+
+\wxheading{X Window System Note}
+
+Under X Window System, the window manager must support either
+the \urlref{System Tray Protocol by freedesktop.org}{http://freedesktop.org/Standards/systemtray-spec}
+(WMs used by modern desktop environments such as GNOME >= 2, KDE
+>= 3 and XFCE >= 4 all do) or the older methods used in GNOME 1.2 and
+KDE 1 and 2. If it doesn't, the icon will appear as a toplevel window on
+user's desktop.
+
+Because not all window managers have system tray, there's no guarantee that
+wxTaskBarIcon will work correctly under X Window System and so the applications
+should use it only as an optional component of their user interface. The user
+should be required to explicitly enable the taskbar icon on Unix, it shouldn't
+be on by default.
+
\wxheading{Derived from}
--- /dev/null
+/////////////////////////////////////////////////////////////////////////
+// File: wx/gtk/taskbarpriv.h
+// Purpose: wxTaskBarIcon (src/unix/taskbarx11.cpp) helper for GTK2
+// Author: Vaclav Slavik
+// Modified by:
+// Created: 2004/05/29
+// RCS-ID: $Id$
+// Copyright: (c) Vaclav Slavik, 2004
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_TASKBARPRIV_H_
+#define _WX_TASKBARPRIV_H_
+
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
+#pragma interface "taskbarpriv.h"
+#endif
+
+#include "wx/toplevel.h"
+#include "wx/bitmap.h"
+
+class WXDLLIMPEXP_ADV wxTaskBarIconAreaBase : public wxTopLevelWindow
+{
+public:
+ wxTaskBarIconAreaBase();
+
+ // Returns true if SYSTRAY protocol is supported by the desktop
+ bool IsProtocolSupported();
+};
+
+#endif // _WX_TASKBARPRIV_H_
--- /dev/null
+/////////////////////////////////////////////////////////////////////////
+// File: wx/gtk/taskbarpriv.h
+// Purpose: wxTaskBarIcon (src/unix/taskbarx11.cpp) helper for GTK2
+// Author: Vaclav Slavik
+// Modified by:
+// Created: 2004/05/29
+// RCS-ID: $Id$
+// Copyright: (c) Vaclav Slavik, 2004
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_TASKBARPRIV_H_
+#define _WX_TASKBARPRIV_H_
+
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
+#pragma interface "taskbarpriv.h"
+#endif
+
+#include "wx/toplevel.h"
+#include "wx/bitmap.h"
+
+class WXDLLIMPEXP_ADV wxTaskBarIconAreaBase : public wxTopLevelWindow
+{
+public:
+ wxTaskBarIconAreaBase();
+
+ // Returns true if SYSTRAY protocol is supported by the desktop
+ bool IsProtocolSupported();
+};
+
+#endif // _WX_TASKBARPRIV_H_
--- /dev/null
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* eggtrayicon.c
+ * Copyright (C) 2002 Anders Carlsson <andersca@gnu.org>
+ *
+ * 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 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.
+ */
+
+#include <string.h>
+#include <gdk/gdkx.h>
+#include "eggtrayicon.h"
+
+#define SYSTEM_TRAY_REQUEST_DOCK 0
+#define SYSTEM_TRAY_BEGIN_MESSAGE 1
+#define SYSTEM_TRAY_CANCEL_MESSAGE 2
+
+static GtkPlugClass *parent_class = NULL;
+
+static void egg_tray_icon_init (EggTrayIcon *icon);
+static void egg_tray_icon_class_init (EggTrayIconClass *klass);
+
+static void egg_tray_icon_unrealize (GtkWidget *widget);
+
+static void egg_tray_icon_update_manager_window (EggTrayIcon *icon);
+
+GType
+egg_tray_icon_get_type (void)
+{
+ static GType our_type = 0;
+
+ if (our_type == 0)
+ {
+ static const GTypeInfo our_info =
+ {
+ sizeof (EggTrayIconClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) egg_tray_icon_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (EggTrayIcon),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) egg_tray_icon_init
+ };
+
+ our_type = g_type_register_static (GTK_TYPE_PLUG, "EggTrayIcon", &our_info, 0);
+ }
+
+ return our_type;
+}
+
+static void
+egg_tray_icon_init (EggTrayIcon *icon)
+{
+ icon->stamp = 1;
+
+ gtk_widget_add_events (GTK_WIDGET (icon), GDK_PROPERTY_CHANGE_MASK);
+}
+
+static void
+egg_tray_icon_class_init (EggTrayIconClass *klass)
+{
+ GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ widget_class->unrealize = egg_tray_icon_unrealize;
+}
+
+static GdkFilterReturn
+egg_tray_icon_manager_filter (GdkXEvent *xevent, GdkEvent *event, gpointer user_data)
+{
+ EggTrayIcon *icon = user_data;
+ XEvent *xev = (XEvent *)xevent;
+
+ if (xev->xany.type == ClientMessage &&
+ xev->xclient.message_type == icon->manager_atom &&
+ xev->xclient.data.l[1] == icon->selection_atom)
+ {
+ egg_tray_icon_update_manager_window (icon);
+ }
+ else if (xev->xany.window == icon->manager_window)
+ {
+ if (xev->xany.type == DestroyNotify)
+ {
+ egg_tray_icon_update_manager_window (icon);
+ }
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+static void
+egg_tray_icon_unrealize (GtkWidget *widget)
+{
+ EggTrayIcon *icon = EGG_TRAY_ICON (widget);
+ GdkWindow *root_window;
+
+ if (icon->manager_window != None)
+ {
+ GdkWindow *gdkwin;
+
+ gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (widget),
+ icon->manager_window);
+
+ gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon);
+ }
+
+ root_window = gdk_screen_get_root_window (gtk_widget_get_screen (widget));
+
+ gdk_window_remove_filter (root_window, egg_tray_icon_manager_filter, icon);
+
+ if (GTK_WIDGET_CLASS (parent_class)->unrealize)
+ (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
+}
+
+static void
+egg_tray_icon_send_manager_message (EggTrayIcon *icon,
+ long message,
+ Window window,
+ long data1,
+ long data2,
+ long data3)
+{
+ XClientMessageEvent ev;
+ Display *display;
+
+ ev.type = ClientMessage;
+ ev.window = window;
+ ev.message_type = icon->system_tray_opcode_atom;
+ ev.format = 32;
+ ev.data.l[0] = gdk_x11_get_server_time (GTK_WIDGET (icon)->window);
+ ev.data.l[1] = message;
+ ev.data.l[2] = data1;
+ ev.data.l[3] = data2;
+ ev.data.l[4] = data3;
+
+ display = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));
+
+ gdk_error_trap_push ();
+ XSendEvent (display,
+ icon->manager_window, False, NoEventMask, (XEvent *)&ev);
+ XSync (display, False);
+ gdk_error_trap_pop ();
+}
+
+static void
+egg_tray_icon_send_dock_request (EggTrayIcon *icon)
+{
+ egg_tray_icon_send_manager_message (icon,
+ SYSTEM_TRAY_REQUEST_DOCK,
+ icon->manager_window,
+ gtk_plug_get_id (GTK_PLUG (icon)),
+ 0, 0);
+}
+
+static void
+egg_tray_icon_update_manager_window (EggTrayIcon *icon)
+{
+ Display *xdisplay;
+
+ xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));
+
+ if (icon->manager_window != None)
+ {
+ GdkWindow *gdkwin;
+
+ gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)),
+ icon->manager_window);
+
+ gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon);
+ }
+
+ XGrabServer (xdisplay);
+
+ icon->manager_window = XGetSelectionOwner (xdisplay,
+ icon->selection_atom);
+
+ if (icon->manager_window != None)
+ XSelectInput (xdisplay,
+ icon->manager_window, StructureNotifyMask);
+
+ XUngrabServer (xdisplay);
+ XFlush (xdisplay);
+
+ if (icon->manager_window != None)
+ {
+ GdkWindow *gdkwin;
+
+ gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)),
+ icon->manager_window);
+
+ gdk_window_add_filter (gdkwin, egg_tray_icon_manager_filter, icon);
+
+ /* Send a request that we'd like to dock */
+ egg_tray_icon_send_dock_request (icon);
+ }
+}
+
+EggTrayIcon *
+egg_tray_icon_new_for_xscreen (Screen *xscreen, const char *name)
+{
+ EggTrayIcon *icon;
+ char buffer[256];
+ GdkWindow *root_window;
+ GdkDisplay *display;
+ GdkScreen *screen;
+
+ g_return_val_if_fail (xscreen != NULL, NULL);
+
+ icon = g_object_new (EGG_TYPE_TRAY_ICON, NULL);
+ gtk_window_set_title (GTK_WINDOW (icon), name);
+
+ display = gdk_x11_lookup_xdisplay (DisplayOfScreen (xscreen));
+ screen = gdk_display_get_screen (display, XScreenNumberOfScreen (xscreen));
+
+ gtk_plug_construct_for_display (GTK_PLUG (icon),
+ display, 0);
+
+ gtk_window_set_screen (GTK_WINDOW (icon), screen);
+
+ gtk_widget_realize (GTK_WIDGET (icon));
+
+ /* Now see if there's a manager window around */
+ g_snprintf (buffer, sizeof (buffer),
+ "_NET_SYSTEM_TRAY_S%d",
+ XScreenNumberOfScreen (xscreen));
+
+ icon->selection_atom = XInternAtom (DisplayOfScreen (xscreen),
+ buffer, False);
+
+ icon->manager_atom = XInternAtom (DisplayOfScreen (xscreen),
+ "MANAGER", False);
+
+ icon->system_tray_opcode_atom = XInternAtom (DisplayOfScreen (xscreen),
+ "_NET_SYSTEM_TRAY_OPCODE", False);
+
+ egg_tray_icon_update_manager_window (icon);
+
+ root_window = gdk_screen_get_root_window (gtk_widget_get_screen (GTK_WIDGET (icon)));
+
+ /* Add a root window filter so that we get changes on MANAGER */
+ gdk_window_add_filter (root_window,
+ egg_tray_icon_manager_filter, icon);
+
+ return icon;
+}
+
+EggTrayIcon *
+egg_tray_icon_new_for_screen (GdkScreen *screen, const char *name)
+{
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+ return egg_tray_icon_new_for_xscreen (GDK_SCREEN_XSCREEN (screen), name);
+}
+
+EggTrayIcon*
+egg_tray_icon_new (const gchar *name)
+{
+ return egg_tray_icon_new_for_xscreen (DefaultScreenOfDisplay (gdk_display), name);
+}
+
+guint
+egg_tray_icon_send_message (EggTrayIcon *icon,
+ gint timeout,
+ const gchar *message,
+ gint len)
+{
+ guint stamp;
+
+ g_return_val_if_fail (EGG_IS_TRAY_ICON (icon), 0);
+ g_return_val_if_fail (timeout >= 0, 0);
+ g_return_val_if_fail (message != NULL, 0);
+
+ if (icon->manager_window == None)
+ return 0;
+
+ if (len < 0)
+ len = strlen (message);
+
+ stamp = icon->stamp++;
+
+ /* Get ready to send the message */
+ egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_BEGIN_MESSAGE,
+ (Window)gtk_plug_get_id (GTK_PLUG (icon)),
+ timeout, len, stamp);
+
+ /* Now to send the actual message */
+ gdk_error_trap_push ();
+ while (len > 0)
+ {
+ XClientMessageEvent ev;
+ Display *xdisplay;
+
+ xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));
+
+ ev.type = ClientMessage;
+ ev.window = (Window)gtk_plug_get_id (GTK_PLUG (icon));
+ ev.format = 8;
+ ev.message_type = XInternAtom (xdisplay,
+ "_NET_SYSTEM_TRAY_MESSAGE_DATA", False);
+ if (len > 20)
+ {
+ memcpy (&ev.data, message, 20);
+ len -= 20;
+ message += 20;
+ }
+ else
+ {
+ memcpy (&ev.data, message, len);
+ len = 0;
+ }
+
+ XSendEvent (xdisplay,
+ icon->manager_window, False, StructureNotifyMask, (XEvent *)&ev);
+ XSync (xdisplay, False);
+ }
+ gdk_error_trap_pop ();
+
+ return stamp;
+}
+
+void
+egg_tray_icon_cancel_message (EggTrayIcon *icon,
+ guint id)
+{
+ g_return_if_fail (EGG_IS_TRAY_ICON (icon));
+ g_return_if_fail (id > 0);
+
+ egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_CANCEL_MESSAGE,
+ (Window)gtk_plug_get_id (GTK_PLUG (icon)),
+ id, 0, 0);
+}
--- /dev/null
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* eggtrayicon.h
+ * Copyright (C) 2002 Anders Carlsson <andersca@gnu.org>
+ *
+ * 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 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 __EGG_TRAY_ICON_H__
+#define __EGG_TRAY_ICON_H__
+
+#include <gtk/gtkplug.h>
+#include <gdk/gdkx.h>
+
+G_BEGIN_DECLS
+
+#define EGG_TYPE_TRAY_ICON (egg_tray_icon_get_type ())
+#define EGG_TRAY_ICON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_TRAY_ICON, EggTrayIcon))
+#define EGG_TRAY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_TRAY_ICON, EggTrayIconClass))
+#define EGG_IS_TRAY_ICON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_TRAY_ICON))
+#define EGG_IS_TRAY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_TRAY_ICON))
+#define EGG_TRAY_ICON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_TRAY_ICON, EggTrayIconClass))
+
+typedef struct _EggTrayIcon EggTrayIcon;
+typedef struct _EggTrayIconClass EggTrayIconClass;
+
+struct _EggTrayIcon
+{
+ GtkPlug parent_instance;
+
+ guint stamp;
+
+ Atom selection_atom;
+ Atom manager_atom;
+ Atom system_tray_opcode_atom;
+ Window manager_window;
+};
+
+struct _EggTrayIconClass
+{
+ GtkPlugClass parent_class;
+};
+
+GType egg_tray_icon_get_type (void);
+
+EggTrayIcon *egg_tray_icon_new_for_screen (GdkScreen *screen,
+ const gchar *name);
+
+EggTrayIcon *egg_tray_icon_new (const gchar *name);
+
+guint egg_tray_icon_send_message (EggTrayIcon *icon,
+ gint timeout,
+ const char *message,
+ gint len);
+void egg_tray_icon_cancel_message (EggTrayIcon *icon,
+ guint id);
+
+
+
+G_END_DECLS
+
+#endif /* __EGG_TRAY_ICON_H__ */
--- /dev/null
+/////////////////////////////////////////////////////////////////////////
+// File: taskbar.cpp
+// Purpose: wxTaskBarIcon (src/unix/taskbarx11.cpp) helper for GTK2
+// Author: Vaclav Slavik
+// Modified by:
+// Created: 2004/05/29
+// RCS-ID: $Id$
+// Copyright: (c) Vaclav Slavik, 2004
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////
+
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
+#pragma implementation "taskbarpriv.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#include "wx/log.h"
+#include "wx/frame.h"
+
+#ifdef __WXGTK20__
+
+#include "wx/gtk/taskbarpriv.h"
+#include "eggtrayicon.h"
+
+wxTaskBarIconAreaBase::wxTaskBarIconAreaBase()
+{
+ if (IsProtocolSupported())
+ {
+ m_widget = GTK_WIDGET(egg_tray_icon_new("systray icon"));
+ gtk_window_set_resizable(GTK_WINDOW(m_widget), false);
+
+ wxLogTrace(_T("systray"), _T("using freedesktop.org systray spec"));
+ }
+
+ wxTopLevelWindow::Create(
+ NULL, wxID_ANY, _T("systray icon"),
+ wxDefaultPosition, wxDefaultSize,
+ wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR | wxSIMPLE_BORDER |
+ wxFRAME_SHAPED,
+ wxEmptyString /*eggtray doesn't like setting wmclass*/);
+}
+
+bool wxTaskBarIconAreaBase::IsProtocolSupported()
+{
+ static int s_supported = -1;
+ if (s_supported == -1)
+ {
+ Display *display = GDK_DISPLAY();
+ Screen *screen = DefaultScreenOfDisplay(display);
+
+ wxString name;
+ name.Printf(_T("_NET_SYSTEM_TRAY_S%d"), XScreenNumberOfScreen(screen));
+ Atom atom = XInternAtom(display, name.ToAscii(), False);
+
+ Window manager = XGetSelectionOwner(display, atom);
+
+ s_supported = (manager != None);
+ }
+
+ return (bool)s_supported;
+}
+
+#endif // __WXGTK20__
--- /dev/null
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* eggtrayicon.c
+ * Copyright (C) 2002 Anders Carlsson <andersca@gnu.org>
+ *
+ * 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 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.
+ */
+
+#include <string.h>
+#include <gdk/gdkx.h>
+#include "eggtrayicon.h"
+
+#define SYSTEM_TRAY_REQUEST_DOCK 0
+#define SYSTEM_TRAY_BEGIN_MESSAGE 1
+#define SYSTEM_TRAY_CANCEL_MESSAGE 2
+
+static GtkPlugClass *parent_class = NULL;
+
+static void egg_tray_icon_init (EggTrayIcon *icon);
+static void egg_tray_icon_class_init (EggTrayIconClass *klass);
+
+static void egg_tray_icon_unrealize (GtkWidget *widget);
+
+static void egg_tray_icon_update_manager_window (EggTrayIcon *icon);
+
+GType
+egg_tray_icon_get_type (void)
+{
+ static GType our_type = 0;
+
+ if (our_type == 0)
+ {
+ static const GTypeInfo our_info =
+ {
+ sizeof (EggTrayIconClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) egg_tray_icon_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (EggTrayIcon),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) egg_tray_icon_init
+ };
+
+ our_type = g_type_register_static (GTK_TYPE_PLUG, "EggTrayIcon", &our_info, 0);
+ }
+
+ return our_type;
+}
+
+static void
+egg_tray_icon_init (EggTrayIcon *icon)
+{
+ icon->stamp = 1;
+
+ gtk_widget_add_events (GTK_WIDGET (icon), GDK_PROPERTY_CHANGE_MASK);
+}
+
+static void
+egg_tray_icon_class_init (EggTrayIconClass *klass)
+{
+ GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ widget_class->unrealize = egg_tray_icon_unrealize;
+}
+
+static GdkFilterReturn
+egg_tray_icon_manager_filter (GdkXEvent *xevent, GdkEvent *event, gpointer user_data)
+{
+ EggTrayIcon *icon = user_data;
+ XEvent *xev = (XEvent *)xevent;
+
+ if (xev->xany.type == ClientMessage &&
+ xev->xclient.message_type == icon->manager_atom &&
+ xev->xclient.data.l[1] == icon->selection_atom)
+ {
+ egg_tray_icon_update_manager_window (icon);
+ }
+ else if (xev->xany.window == icon->manager_window)
+ {
+ if (xev->xany.type == DestroyNotify)
+ {
+ egg_tray_icon_update_manager_window (icon);
+ }
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+static void
+egg_tray_icon_unrealize (GtkWidget *widget)
+{
+ EggTrayIcon *icon = EGG_TRAY_ICON (widget);
+ GdkWindow *root_window;
+
+ if (icon->manager_window != None)
+ {
+ GdkWindow *gdkwin;
+
+ gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (widget),
+ icon->manager_window);
+
+ gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon);
+ }
+
+ root_window = gdk_screen_get_root_window (gtk_widget_get_screen (widget));
+
+ gdk_window_remove_filter (root_window, egg_tray_icon_manager_filter, icon);
+
+ if (GTK_WIDGET_CLASS (parent_class)->unrealize)
+ (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
+}
+
+static void
+egg_tray_icon_send_manager_message (EggTrayIcon *icon,
+ long message,
+ Window window,
+ long data1,
+ long data2,
+ long data3)
+{
+ XClientMessageEvent ev;
+ Display *display;
+
+ ev.type = ClientMessage;
+ ev.window = window;
+ ev.message_type = icon->system_tray_opcode_atom;
+ ev.format = 32;
+ ev.data.l[0] = gdk_x11_get_server_time (GTK_WIDGET (icon)->window);
+ ev.data.l[1] = message;
+ ev.data.l[2] = data1;
+ ev.data.l[3] = data2;
+ ev.data.l[4] = data3;
+
+ display = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));
+
+ gdk_error_trap_push ();
+ XSendEvent (display,
+ icon->manager_window, False, NoEventMask, (XEvent *)&ev);
+ XSync (display, False);
+ gdk_error_trap_pop ();
+}
+
+static void
+egg_tray_icon_send_dock_request (EggTrayIcon *icon)
+{
+ egg_tray_icon_send_manager_message (icon,
+ SYSTEM_TRAY_REQUEST_DOCK,
+ icon->manager_window,
+ gtk_plug_get_id (GTK_PLUG (icon)),
+ 0, 0);
+}
+
+static void
+egg_tray_icon_update_manager_window (EggTrayIcon *icon)
+{
+ Display *xdisplay;
+
+ xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));
+
+ if (icon->manager_window != None)
+ {
+ GdkWindow *gdkwin;
+
+ gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)),
+ icon->manager_window);
+
+ gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon);
+ }
+
+ XGrabServer (xdisplay);
+
+ icon->manager_window = XGetSelectionOwner (xdisplay,
+ icon->selection_atom);
+
+ if (icon->manager_window != None)
+ XSelectInput (xdisplay,
+ icon->manager_window, StructureNotifyMask);
+
+ XUngrabServer (xdisplay);
+ XFlush (xdisplay);
+
+ if (icon->manager_window != None)
+ {
+ GdkWindow *gdkwin;
+
+ gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)),
+ icon->manager_window);
+
+ gdk_window_add_filter (gdkwin, egg_tray_icon_manager_filter, icon);
+
+ /* Send a request that we'd like to dock */
+ egg_tray_icon_send_dock_request (icon);
+ }
+}
+
+EggTrayIcon *
+egg_tray_icon_new_for_xscreen (Screen *xscreen, const char *name)
+{
+ EggTrayIcon *icon;
+ char buffer[256];
+ GdkWindow *root_window;
+ GdkDisplay *display;
+ GdkScreen *screen;
+
+ g_return_val_if_fail (xscreen != NULL, NULL);
+
+ icon = g_object_new (EGG_TYPE_TRAY_ICON, NULL);
+ gtk_window_set_title (GTK_WINDOW (icon), name);
+
+ display = gdk_x11_lookup_xdisplay (DisplayOfScreen (xscreen));
+ screen = gdk_display_get_screen (display, XScreenNumberOfScreen (xscreen));
+
+ gtk_plug_construct_for_display (GTK_PLUG (icon),
+ display, 0);
+
+ gtk_window_set_screen (GTK_WINDOW (icon), screen);
+
+ gtk_widget_realize (GTK_WIDGET (icon));
+
+ /* Now see if there's a manager window around */
+ g_snprintf (buffer, sizeof (buffer),
+ "_NET_SYSTEM_TRAY_S%d",
+ XScreenNumberOfScreen (xscreen));
+
+ icon->selection_atom = XInternAtom (DisplayOfScreen (xscreen),
+ buffer, False);
+
+ icon->manager_atom = XInternAtom (DisplayOfScreen (xscreen),
+ "MANAGER", False);
+
+ icon->system_tray_opcode_atom = XInternAtom (DisplayOfScreen (xscreen),
+ "_NET_SYSTEM_TRAY_OPCODE", False);
+
+ egg_tray_icon_update_manager_window (icon);
+
+ root_window = gdk_screen_get_root_window (gtk_widget_get_screen (GTK_WIDGET (icon)));
+
+ /* Add a root window filter so that we get changes on MANAGER */
+ gdk_window_add_filter (root_window,
+ egg_tray_icon_manager_filter, icon);
+
+ return icon;
+}
+
+EggTrayIcon *
+egg_tray_icon_new_for_screen (GdkScreen *screen, const char *name)
+{
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+ return egg_tray_icon_new_for_xscreen (GDK_SCREEN_XSCREEN (screen), name);
+}
+
+EggTrayIcon*
+egg_tray_icon_new (const gchar *name)
+{
+ return egg_tray_icon_new_for_xscreen (DefaultScreenOfDisplay (gdk_display), name);
+}
+
+guint
+egg_tray_icon_send_message (EggTrayIcon *icon,
+ gint timeout,
+ const gchar *message,
+ gint len)
+{
+ guint stamp;
+
+ g_return_val_if_fail (EGG_IS_TRAY_ICON (icon), 0);
+ g_return_val_if_fail (timeout >= 0, 0);
+ g_return_val_if_fail (message != NULL, 0);
+
+ if (icon->manager_window == None)
+ return 0;
+
+ if (len < 0)
+ len = strlen (message);
+
+ stamp = icon->stamp++;
+
+ /* Get ready to send the message */
+ egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_BEGIN_MESSAGE,
+ (Window)gtk_plug_get_id (GTK_PLUG (icon)),
+ timeout, len, stamp);
+
+ /* Now to send the actual message */
+ gdk_error_trap_push ();
+ while (len > 0)
+ {
+ XClientMessageEvent ev;
+ Display *xdisplay;
+
+ xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));
+
+ ev.type = ClientMessage;
+ ev.window = (Window)gtk_plug_get_id (GTK_PLUG (icon));
+ ev.format = 8;
+ ev.message_type = XInternAtom (xdisplay,
+ "_NET_SYSTEM_TRAY_MESSAGE_DATA", False);
+ if (len > 20)
+ {
+ memcpy (&ev.data, message, 20);
+ len -= 20;
+ message += 20;
+ }
+ else
+ {
+ memcpy (&ev.data, message, len);
+ len = 0;
+ }
+
+ XSendEvent (xdisplay,
+ icon->manager_window, False, StructureNotifyMask, (XEvent *)&ev);
+ XSync (xdisplay, False);
+ }
+ gdk_error_trap_pop ();
+
+ return stamp;
+}
+
+void
+egg_tray_icon_cancel_message (EggTrayIcon *icon,
+ guint id)
+{
+ g_return_if_fail (EGG_IS_TRAY_ICON (icon));
+ g_return_if_fail (id > 0);
+
+ egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_CANCEL_MESSAGE,
+ (Window)gtk_plug_get_id (GTK_PLUG (icon)),
+ id, 0, 0);
+}
--- /dev/null
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* eggtrayicon.h
+ * Copyright (C) 2002 Anders Carlsson <andersca@gnu.org>
+ *
+ * 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 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 __EGG_TRAY_ICON_H__
+#define __EGG_TRAY_ICON_H__
+
+#include <gtk/gtkplug.h>
+#include <gdk/gdkx.h>
+
+G_BEGIN_DECLS
+
+#define EGG_TYPE_TRAY_ICON (egg_tray_icon_get_type ())
+#define EGG_TRAY_ICON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_TRAY_ICON, EggTrayIcon))
+#define EGG_TRAY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_TRAY_ICON, EggTrayIconClass))
+#define EGG_IS_TRAY_ICON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_TRAY_ICON))
+#define EGG_IS_TRAY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_TRAY_ICON))
+#define EGG_TRAY_ICON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_TRAY_ICON, EggTrayIconClass))
+
+typedef struct _EggTrayIcon EggTrayIcon;
+typedef struct _EggTrayIconClass EggTrayIconClass;
+
+struct _EggTrayIcon
+{
+ GtkPlug parent_instance;
+
+ guint stamp;
+
+ Atom selection_atom;
+ Atom manager_atom;
+ Atom system_tray_opcode_atom;
+ Window manager_window;
+};
+
+struct _EggTrayIconClass
+{
+ GtkPlugClass parent_class;
+};
+
+GType egg_tray_icon_get_type (void);
+
+EggTrayIcon *egg_tray_icon_new_for_screen (GdkScreen *screen,
+ const gchar *name);
+
+EggTrayIcon *egg_tray_icon_new (const gchar *name);
+
+guint egg_tray_icon_send_message (EggTrayIcon *icon,
+ gint timeout,
+ const char *message,
+ gint len);
+void egg_tray_icon_cancel_message (EggTrayIcon *icon,
+ guint id);
+
+
+
+G_END_DECLS
+
+#endif /* __EGG_TRAY_ICON_H__ */
--- /dev/null
+/////////////////////////////////////////////////////////////////////////
+// File: taskbar.cpp
+// Purpose: wxTaskBarIcon (src/unix/taskbarx11.cpp) helper for GTK2
+// Author: Vaclav Slavik
+// Modified by:
+// Created: 2004/05/29
+// RCS-ID: $Id$
+// Copyright: (c) Vaclav Slavik, 2004
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////
+
+#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
+#pragma implementation "taskbarpriv.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#include "wx/log.h"
+#include "wx/frame.h"
+
+#ifdef __WXGTK20__
+
+#include "wx/gtk/taskbarpriv.h"
+#include "eggtrayicon.h"
+
+wxTaskBarIconAreaBase::wxTaskBarIconAreaBase()
+{
+ if (IsProtocolSupported())
+ {
+ m_widget = GTK_WIDGET(egg_tray_icon_new("systray icon"));
+ gtk_window_set_resizable(GTK_WINDOW(m_widget), false);
+
+ wxLogTrace(_T("systray"), _T("using freedesktop.org systray spec"));
+ }
+
+ wxTopLevelWindow::Create(
+ NULL, wxID_ANY, _T("systray icon"),
+ wxDefaultPosition, wxDefaultSize,
+ wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR | wxSIMPLE_BORDER |
+ wxFRAME_SHAPED,
+ wxEmptyString /*eggtray doesn't like setting wmclass*/);
+}
+
+bool wxTaskBarIconAreaBase::IsProtocolSupported()
+{
+ static int s_supported = -1;
+ if (s_supported == -1)
+ {
+ Display *display = GDK_DISPLAY();
+ Screen *screen = DefaultScreenOfDisplay(display);
+
+ wxString name;
+ name.Printf(_T("_NET_SYSTEM_TRAY_S%d"), XScreenNumberOfScreen(screen));
+ Atom atom = XInternAtom(display, name.ToAscii(), False);
+
+ Window manager = XGetSelectionOwner(display, atom);
+
+ s_supported = (manager != None);
+ }
+
+ return (bool)s_supported;
+}
+
+#endif // __WXGTK20__
#endif
// NB: This implementation does *not* work with every X11 window manager.
-// Currently only GNOME 1.2 and KDE 1,2,3 methods are implemented.
-//
-// FIXME: implement:
-// - GNOME 2 support (see www.freedesktop.org for specification;
-// KDE 3 uses this method as well, even though legacy KDE
-// method we implement works as well)
-// - IceWM support (?)
+// Currently only GNOME 1.2 and KDE 1,2,3 methods are implemented here.
+// Freedesktop.org's System Tray specification is implemented in
+// src/gtk/taskbar.cpp and used from here under wxGTK.
//
// Thanks to Ian Campbell, author of XMMS Status Docklet, for publishing
// KDE and GNOME 1.2 methods.
#include "wx/statbmp.h"
#include "wx/sizer.h"
#include "wx/dcclient.h"
+#include "wx/log.h"
#ifdef __VMS
#pragma message disable nosimpint
#pragma message enable nosimpint
#endif
+// ----------------------------------------------------------------------------
+// base class that implements toolkit-specific method:
+// ----------------------------------------------------------------------------
+
+#ifdef __WXGTK20__
+ #include "wx/gtk/taskbarpriv.h"
+#else
+ class WXDLLIMPEXP_ADV wxTaskBarIconAreaBase : public wxFrame
+ {
+ public:
+ wxTaskBarIconAreaBase()
+ : wxFrame(NULL, wxID_ANY, _T("systray icon"),
+ wxDefaultPosition, wxDefaultSize,
+ wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR |
+ wxSIMPLE_BORDER | wxFRAME_SHAPED) {}
+
+ bool IsProtocolSupported() const { return false; }
+ };
+#endif
+
+
// ----------------------------------------------------------------------------
// toolkit dependent methods to set properties on helper window:
// ----------------------------------------------------------------------------
// wxTaskBarIconArea is the real window that shows the icon:
// ----------------------------------------------------------------------------
-class WXDLLIMPEXP_ADV wxTaskBarIconArea : public wxFrame
+class WXDLLIMPEXP_ADV wxTaskBarIconArea : public wxTaskBarIconAreaBase
{
public:
- wxTaskBarIconArea(wxTaskBarIcon *icon, const wxBitmap &bmp)
- : wxFrame(NULL, -1, wxT("taskbar icon"),
- wxDefaultPosition, wxDefaultSize,
- wxDEFAULT_FRAME_STYLE | wxFRAME_NO_TASKBAR |
- wxSIMPLE_BORDER | wxFRAME_SHAPED),
- m_icon(icon), m_bmp(bmp)
- {
- SetWMProperties();
- SetSize(wxSize(bmp.GetWidth(), bmp.GetHeight()));
- }
-
+ wxTaskBarIconArea(wxTaskBarIcon *icon, const wxBitmap &bmp);
+ void SetTrayIcon(const wxBitmap& bmp);
bool IsOk() { return true; }
protected:
- void SetWMProperties();
+ void SetLegacyWMProperties();
+ void OnSizeChange(wxSizeEvent& event);
void OnPaint(wxPaintEvent& evt);
- void OnWindowCreate(wxWindowCreateEvent& event);
void OnMouseEvent(wxMouseEvent& event);
void OnMenuEvent(wxCommandEvent& event);
wxTaskBarIcon *m_icon;
- wxBitmap m_bmp;
+ wxPoint m_pos;
+ wxBitmap m_bmp;
DECLARE_EVENT_TABLE()
};
-BEGIN_EVENT_TABLE(wxTaskBarIconArea, wxFrame)
+BEGIN_EVENT_TABLE(wxTaskBarIconArea, wxTaskBarIconAreaBase)
+ EVT_SIZE(wxTaskBarIconArea::OnSizeChange)
EVT_MOUSE_EVENTS(wxTaskBarIconArea::OnMouseEvent)
EVT_MENU(-1, wxTaskBarIconArea::OnMenuEvent)
EVT_PAINT(wxTaskBarIconArea::OnPaint)
-#ifdef __WXGTK__
- EVT_WINDOW_CREATE(wxTaskBarIconArea::OnWindowCreate)
-#endif
END_EVENT_TABLE()
+
+wxTaskBarIconArea::wxTaskBarIconArea(wxTaskBarIcon *icon, const wxBitmap &bmp)
+ : wxTaskBarIconAreaBase(), m_icon(icon), m_pos(0,0)
+{
+ if (!IsProtocolSupported())
+ {
+ wxLogTrace(_T("systray"),
+ _T("using legacy KDE1,2 and GNOME 1.2 methods"));
+ SetLegacyWMProperties();
+ }
+
+ // Set initial size to bitmap size (tray manager may and often will
+ // change it):
+ SetSize(wxSize(bmp.GetWidth(), bmp.GetHeight()));
+
+ SetTrayIcon(bmp);
+}
+
+void wxTaskBarIconArea::SetTrayIcon(const wxBitmap& bmp)
+{
+ m_bmp = bmp;
+
+ // determine suitable bitmap size:
+ wxSize winsize(GetSize());
+ wxSize bmpsize(m_bmp.GetWidth(), m_bmp.GetHeight());
+ wxSize iconsize(wxMin(winsize.x, bmpsize.x), wxMin(winsize.y, bmpsize.y));
+
+ // rescale the bitmap to fit into the tray icon window:
+ if (bmpsize != iconsize)
+ {
+ wxImage img = m_bmp.ConvertToImage();
+ img.Rescale(iconsize.x, iconsize.y);
+ m_bmp = wxBitmap(img);
+ }
-void wxTaskBarIconArea::SetWMProperties()
+ wxRegion region(m_bmp);
+
+ // if the bitmap is smaller than the window, offset it:
+ if (winsize != iconsize)
+ {
+ m_pos.x = (winsize.x - iconsize.x) / 2;
+ m_pos.y = (winsize.y - iconsize.y) / 2;
+ region.Offset(m_pos.x, m_pos.y);
+ }
+
+ // set frame's shape to correct value and redraw:
+ SetShape(region);
+ Refresh();
+}
+
+void wxTaskBarIconArea::SetLegacyWMProperties()
{
#ifdef __WXGTK__
gtk_widget_realize(m_widget);
PropModeReplace, (unsigned char*)data, 1);
}
-void wxTaskBarIconArea::OnWindowCreate(wxWindowCreateEvent& WXUNUSED(event))
+void wxTaskBarIconArea::OnSizeChange(wxSizeEvent& event)
{
- SetShape(wxRegion(m_bmp));
+ wxLogTrace(_T("systray"), _T("icon size changed to %i x %i"),
+ GetSize().x, GetSize().y);
+ // rescale or reposition the icon as needed:
+ wxBitmap bmp(m_bmp);
+ SetTrayIcon(bmp);
}
void wxTaskBarIconArea::OnPaint(wxPaintEvent& WXUNUSED(event))
{
wxPaintDC dc(this);
- dc.DrawBitmap(m_bmp, 0, 0, true);
+ dc.DrawBitmap(m_bmp, m_pos.x, m_pos.y, true);
}
void wxTaskBarIconArea::OnMouseEvent(wxMouseEvent& event)
{
wxEventType type = 0;
wxEventType mtype = event.GetEventType();
-
+
if (mtype == wxEVT_LEFT_DOWN)
type = wxEVT_TASKBAR_LEFT_DOWN;
else if (mtype == wxEVT_LEFT_UP)
bool wxTaskBarIcon::SetIcon(const wxIcon& icon, const wxString& tooltip)
{
- if (m_iconWnd)
- RemoveIcon();
-
wxBitmap bmp;
bmp.CopyFromIcon(icon);
-
- m_iconWnd = new wxTaskBarIconArea(this, bmp);
-#if wxUSE_TOOLTIPS
- if (!tooltip.empty())
- m_iconWnd->SetToolTip(tooltip);
-#endif
- if (m_iconWnd->IsOk())
+ if (!m_iconWnd)
{
- m_iconWnd->Show();
- return true;
+ m_iconWnd = new wxTaskBarIconArea(this, bmp);
+ if (m_iconWnd->IsOk())
+ {
+ m_iconWnd->Show();
+ }
+ else
+ {
+ m_iconWnd->Destroy();
+ m_iconWnd = NULL;
+ return false;
+ }
}
else
{
- m_iconWnd->Destroy();
- m_iconWnd = NULL;
- return false;
- }
+ m_iconWnd->SetTrayIcon(bmp);
+ }
+
+#if wxUSE_TOOLTIPS
+ if (!tooltip.empty())
+ m_iconWnd->SetToolTip(tooltip);
+ else
+ m_iconWnd->SetToolTip(NULL);
+#endif
+ return true;
}
bool wxTaskBarIcon::RemoveIcon()