1 /////////////////////////////////////////////////////////////////////////
2 // File: src/gtk/taskbar.cpp
3 // Purpose: wxTaskBarIcon
4 // Author: Vaclav Slavik
5 // Modified by: Paul Cornett
8 // Copyright: (c) Vaclav Slavik, 2004
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
17 #include "wx/taskbar.h"
20 #include "wx/toplevel.h"
25 #include "eggtrayicon.h"
28 #if !GTK_CHECK_VERSION(2,10,0)
29 typedef struct _GtkStatusIcon GtkStatusIcon
;
32 class wxTaskBarIcon::Private
35 Private(wxTaskBarIcon
* taskBarIcon
);
38 void size_allocate(int width
, int height
);
40 // owning wxTaskBarIcon
41 wxTaskBarIcon
* m_taskBarIcon
;
42 // used when GTK+ >= 2.10
43 GtkStatusIcon
* m_statusIcon
;
44 // used when GTK+ < 2.10
45 GtkWidget
* m_eggTrayIcon
;
48 // for tooltip when GTK+ < 2.10
49 GtkTooltips
* m_tooltips
;
52 // width and height of available space, only used when GTK+ < 2.10
55 //-----------------------------------------------------------------------------
59 icon_size_allocate(GtkWidget
*, GtkAllocation
* alloc
, wxTaskBarIcon::Private
* priv
)
61 priv
->size_allocate(alloc
->width
, alloc
->height
);
65 icon_destroy(GtkWidget
*, wxTaskBarIcon::Private
* priv
)
67 // Icon window destroyed, probably because tray program has died.
68 // Recreate icon so it will appear if tray program is restarted.
69 priv
->m_eggTrayIcon
= NULL
;
74 icon_activate(void*, wxTaskBarIcon
* taskBarIcon
)
76 // activate occurs from single click with GTK+
77 wxTaskBarIconEvent
event(wxEVT_TASKBAR_LEFT_DOWN
, taskBarIcon
);
78 if (!taskBarIcon
->SafelyProcessEvent(event
))
80 // if single click not handled, send double click for compatibility
81 event
.SetEventType(wxEVT_TASKBAR_LEFT_DCLICK
);
82 taskBarIcon
->SafelyProcessEvent(event
);
87 icon_popup_menu(GtkWidget
*, wxTaskBarIcon
* taskBarIcon
)
89 wxTaskBarIconEvent
event(wxEVT_TASKBAR_CLICK
, taskBarIcon
);
90 taskBarIcon
->SafelyProcessEvent(event
);
95 icon_button_press_event(GtkWidget
*, GdkEventButton
* event
, wxTaskBarIcon
* taskBarIcon
)
97 if (event
->type
== GDK_BUTTON_PRESS
)
99 if (event
->button
== 1)
100 icon_activate(NULL
, taskBarIcon
);
101 else if (event
->button
== 3)
102 icon_popup_menu(NULL
, taskBarIcon
);
107 #if GTK_CHECK_VERSION(2,10,0)
109 status_icon_popup_menu(GtkStatusIcon
*, guint
, guint
, wxTaskBarIcon
* taskBarIcon
)
111 icon_popup_menu(NULL
, taskBarIcon
);
115 //-----------------------------------------------------------------------------
117 bool wxTaskBarIconBase::IsAvailable()
120 g_snprintf(name
, sizeof(name
), "_NET_SYSTEM_TRAY_S%d",
121 gdk_x11_get_default_screen());
122 Atom atom
= gdk_x11_get_xatom_by_name(name
);
124 Window manager
= XGetSelectionOwner(gdk_x11_get_default_xdisplay(), atom
);
126 return manager
!= None
;
128 //-----------------------------------------------------------------------------
130 wxTaskBarIcon::Private::Private(wxTaskBarIcon
* taskBarIcon
)
132 m_taskBarIcon
= taskBarIcon
;
134 m_eggTrayIcon
= NULL
;
140 wxTaskBarIcon::Private::~Private()
143 g_object_unref(m_statusIcon
);
144 else if (m_eggTrayIcon
)
146 g_signal_handlers_disconnect_by_func(m_eggTrayIcon
, (void*)icon_destroy
, this);
147 gtk_widget_destroy(m_eggTrayIcon
);
151 m_win
->PopEventHandler();
156 gtk_object_destroy(GTK_OBJECT(m_tooltips
));
157 g_object_unref(m_tooltips
);
161 void wxTaskBarIcon::Private::SetIcon()
163 #if GTK_CHECK_VERSION(2,10,0)
164 if (gtk_check_version(2,10,0) == NULL
)
167 gtk_status_icon_set_from_pixbuf(m_statusIcon
, m_bitmap
.GetPixbuf());
170 m_statusIcon
= gtk_status_icon_new_from_pixbuf(m_bitmap
.GetPixbuf());
171 g_signal_connect(m_statusIcon
, "activate",
172 G_CALLBACK(icon_activate
), m_taskBarIcon
);
173 g_signal_connect(m_statusIcon
, "popup_menu",
174 G_CALLBACK(status_icon_popup_menu
), m_taskBarIcon
);
183 GtkWidget
* image
= GTK_BIN(m_eggTrayIcon
)->child
;
184 gtk_image_set_from_pixbuf(GTK_IMAGE(image
), m_bitmap
.GetPixbuf());
188 m_eggTrayIcon
= GTK_WIDGET(egg_tray_icon_new("wxTaskBarIcon"));
189 gtk_widget_add_events(m_eggTrayIcon
, GDK_BUTTON_PRESS_MASK
);
190 g_signal_connect(m_eggTrayIcon
, "size_allocate",
191 G_CALLBACK(icon_size_allocate
), this);
192 g_signal_connect(m_eggTrayIcon
, "destroy",
193 G_CALLBACK(icon_destroy
), this);
194 g_signal_connect(m_eggTrayIcon
, "button_press_event",
195 G_CALLBACK(icon_button_press_event
), m_taskBarIcon
);
196 g_signal_connect(m_eggTrayIcon
, "popup_menu",
197 G_CALLBACK(icon_popup_menu
), m_taskBarIcon
);
198 GtkWidget
* image
= gtk_image_new_from_pixbuf(m_bitmap
.GetPixbuf());
199 gtk_container_add(GTK_CONTAINER(m_eggTrayIcon
), image
);
200 gtk_widget_show_all(m_eggTrayIcon
);
204 const char *tip_text
= NULL
;
205 if (!m_tipText
.empty())
206 tip_text
= m_tipText
.c_str();
208 #if GTK_CHECK_VERSION(2,10,0)
210 gtk_status_icon_set_tooltip(m_statusIcon
, tip_text
);
214 if (tip_text
&& m_tooltips
== NULL
)
216 m_tooltips
= gtk_tooltips_new();
217 g_object_ref(m_tooltips
);
218 gtk_object_sink(GTK_OBJECT(m_tooltips
));
221 gtk_tooltips_set_tip(m_tooltips
, m_eggTrayIcon
, tip_text
, "");
223 #endif // wxUSE_TOOLTIPS
226 void wxTaskBarIcon::Private::size_allocate(int width
, int height
)
229 EggTrayIcon
* icon
= EGG_TRAY_ICON(m_eggTrayIcon
);
230 if (egg_tray_icon_get_orientation(icon
) == GTK_ORIENTATION_VERTICAL
)
235 int w
= m_bitmap
.GetWidth();
236 int h
= m_bitmap
.GetHeight();
237 if (w
> size
|| h
> size
)
239 if (w
> size
) w
= size
;
240 if (h
> size
) h
= size
;
242 gdk_pixbuf_scale_simple(m_bitmap
.GetPixbuf(), w
, h
, GDK_INTERP_BILINEAR
);
243 GtkImage
* image
= GTK_IMAGE(GTK_BIN(m_eggTrayIcon
)->child
);
244 gtk_image_set_from_pixbuf(image
, pixbuf
);
245 g_object_unref(pixbuf
);
248 //-----------------------------------------------------------------------------
250 IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon
, wxEvtHandler
)
252 wxTaskBarIcon::wxTaskBarIcon()
254 m_priv
= new Private(this);
257 wxTaskBarIcon::~wxTaskBarIcon()
262 bool wxTaskBarIcon::SetIcon(const wxIcon
& icon
, const wxString
& tooltip
)
264 m_priv
->m_bitmap
= icon
;
265 m_priv
->m_tipText
= tooltip
;
270 bool wxTaskBarIcon::RemoveIcon()
273 m_priv
= new Private(this);
277 bool wxTaskBarIcon::IsIconInstalled() const
279 return m_priv
->m_statusIcon
|| m_priv
->m_eggTrayIcon
;
282 bool wxTaskBarIcon::PopupMenu(wxMenu
* menu
)
285 if (m_priv
->m_win
== NULL
)
287 m_priv
->m_win
= new wxTopLevelWindow(
288 NULL
, wxID_ANY
, wxString(), wxDefaultPosition
, wxDefaultSize
, 0);
289 m_priv
->m_win
->PushEventHandler(this);
291 wxPoint
point(-1, -1);
292 #ifdef __WXUNIVERSAL__
293 point
= wxGetMousePosition();
295 m_priv
->m_win
->PopupMenu(menu
, point
);
296 #endif // wxUSE_MENUS
300 #endif // wxUSE_TASKBARICON