implemented freedesktop.org spec support for GTK version of wxTaskBarIcon

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@27544 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík 2004-05-31 22:17:09 +00:00
parent 63c5efa344
commit 33d4eef0b9
13 changed files with 1233 additions and 60 deletions

View File

@ -822,6 +822,10 @@ CORELIB_OBJECTS = \
$(__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 \
@ -840,6 +844,9 @@ ADVDLL_OBJECTS = \
$(__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)
@ -3021,7 +3028,9 @@ COND_TOOLKIT_GTK___ADVANCED_PLATFORM_SRC_OBJECTS = \
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
@ -3877,7 +3886,9 @@ COND_TOOLKIT_GTK___ADVANCED_PLATFORM_SRC_OBJECTS_1 = \
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
@ -5669,9 +5680,14 @@ COND_USE_SOSYMLINKS_1___advdll___so_symlinks_inst_cmd = rm -f \
$(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 = \
@ -5697,9 +5713,14 @@ COND_MONOLITHIC_0_SHARED_0_USE_GUI_1___advlib___depname = \
@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 = \
@ -8213,6 +8234,9 @@ monodll_tipdlg.o: $(srcdir)/src/generic/tipdlg.cpp $(MONODLL_ODEP)
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) $<
@ -10697,6 +10721,9 @@ monodll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONODLL_ODEP)
@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) $<
@ -11144,6 +11171,9 @@ monolib_tipdlg.o: $(srcdir)/src/generic/tipdlg.cpp $(MONOLIB_ODEP)
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) $<
@ -13628,6 +13658,9 @@ monolib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(MONOLIB_ODEP)
@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) $<
@ -19241,6 +19274,9 @@ advdll_tipdlg.o: $(srcdir)/src/generic/tipdlg.cpp $(ADVDLL_ODEP)
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) $<
@ -19286,6 +19322,9 @@ advdll_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(ADVDLL_ODEP)
@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) $<
@ -19343,6 +19382,9 @@ advlib_tipdlg.o: $(srcdir)/src/generic/tipdlg.cpp $(ADVLIB_ODEP)
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) $<
@ -19388,6 +19430,9 @@ advlib_sound_sdl.o: $(srcdir)/src/unix/sound_sdl.cpp $(ADVLIB_ODEP)
@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) $<

View File

@ -2196,6 +2196,11 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
wx/unix/taskbarx11.h
</set>
<set var="ADVANCED_GTK_SRC" hints="files">
src/gtk/taskbar.cpp
src/gtk/eggtrayicon.c
</set>
<!-- ====================================================================== -->
<!-- wxHTML -->
@ -2450,7 +2455,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
<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>

View File

@ -94,6 +94,14 @@ versions, please update your code to not use them.
OTHER CHANGES
=============
2.5.3
-----
Unix:
- wxTaskBarIcon now supports freedesktop.org System Tray protocol
2.5.2
-----
@ -162,10 +170,12 @@ wxHTML:
- <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

View File

@ -1,9 +1,25 @@
\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}

View File

@ -0,0 +1,31 @@
/////////////////////////////////////////////////////////////////////////
// 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_

View File

@ -0,0 +1,31 @@
/////////////////////////////////////////////////////////////////////////
// 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_

345
src/gtk/eggtrayicon.c Normal file
View File

@ -0,0 +1,345 @@
/* -*- 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);
}

74
src/gtk/eggtrayicon.h Normal file
View File

@ -0,0 +1,74 @@
/* -*- 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__ */

65
src/gtk/taskbar.cpp Normal file
View File

@ -0,0 +1,65 @@
/////////////////////////////////////////////////////////////////////////
// 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__

345
src/gtk1/eggtrayicon.c Normal file
View File

@ -0,0 +1,345 @@
/* -*- 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);
}

74
src/gtk1/eggtrayicon.h Normal file
View File

@ -0,0 +1,74 @@
/* -*- 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__ */

65
src/gtk1/taskbar.cpp Normal file
View File

@ -0,0 +1,65 @@
/////////////////////////////////////////////////////////////////////////
// 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__

View File

@ -14,13 +14,9 @@
#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.
@ -35,6 +31,7 @@
#include "wx/statbmp.h"
#include "wx/sizer.h"
#include "wx/dcclient.h"
#include "wx/log.h"
#ifdef __VMS
#pragma message disable nosimpint
@ -45,6 +42,27 @@
#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:
// ----------------------------------------------------------------------------
@ -68,46 +86,85 @@
// 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::SetWMProperties()
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);
}
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);
@ -134,22 +191,26 @@ void wxTaskBarIconArea::SetWMProperties()
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)
@ -204,29 +265,35 @@ bool wxTaskBarIcon::IsIconInstalled() const
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()