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"
15 #if wxUSE_TASKBARICON && defined(__WXGTK210__)
17 #include "wx/taskbar.h"
20 #include "wx/toplevel.h"
25 #include "eggtrayicon.h"
28 class wxTaskBarIcon::Private
31 Private(wxTaskBarIcon
* taskBarIcon
);
34 void size_allocate(int width
, int height
);
36 // owning wxTaskBarIcon
37 wxTaskBarIcon
* m_taskBarIcon
;
38 // used when GTK+ >= 2.10
39 GtkStatusIcon
* m_statusIcon
;
40 // used when GTK+ < 2.10
41 GtkWidget
* m_eggTrayIcon
;
44 // for tooltip when GTK+ < 2.10
45 GtkTooltips
* m_tooltips
;
48 // width and height of available space, only used when GTK+ < 2.10
51 //-----------------------------------------------------------------------------
55 icon_size_allocate(GtkWidget
*, GtkAllocation
* alloc
, wxTaskBarIcon::Private
* priv
)
57 priv
->size_allocate(alloc
->width
, alloc
->height
);
61 icon_destroy(GtkWidget
*, wxTaskBarIcon::Private
* priv
)
63 // Icon window destroyed, probably because tray program has died.
64 // Recreate icon so it will appear if tray program is restarted.
65 priv
->m_eggTrayIcon
= NULL
;
70 icon_activate(void*, wxTaskBarIcon
* taskBarIcon
)
72 // activate occurs from single click with GTK+
73 wxTaskBarIconEvent
event(wxEVT_TASKBAR_LEFT_DOWN
, taskBarIcon
);
74 if (!taskBarIcon
->SafelyProcessEvent(event
))
76 // if single click not handled, send double click for compatibility
77 event
.SetEventType(wxEVT_TASKBAR_LEFT_DCLICK
);
78 taskBarIcon
->SafelyProcessEvent(event
);
83 icon_popup_menu(GtkWidget
*, wxTaskBarIcon
* taskBarIcon
)
85 wxTaskBarIconEvent
event(wxEVT_TASKBAR_CLICK
, taskBarIcon
);
86 taskBarIcon
->SafelyProcessEvent(event
);
91 icon_button_press_event(GtkWidget
*, GdkEventButton
* event
, wxTaskBarIcon
* taskBarIcon
)
93 if (event
->type
== GDK_BUTTON_PRESS
)
95 if (event
->button
== 1)
96 icon_activate(NULL
, taskBarIcon
);
97 else if (event
->button
== 3)
98 icon_popup_menu(NULL
, taskBarIcon
);
103 #if GTK_CHECK_VERSION(2,10,0)
105 status_icon_popup_menu(GtkStatusIcon
*, guint
, guint
, wxTaskBarIcon
* taskBarIcon
)
107 icon_popup_menu(NULL
, taskBarIcon
);
111 //-----------------------------------------------------------------------------
113 bool wxTaskBarIconBase::IsAvailable()
116 g_snprintf(name
, sizeof(name
), "_NET_SYSTEM_TRAY_S%d",
117 gdk_x11_get_default_screen());
118 Atom atom
= gdk_x11_get_xatom_by_name(name
);
120 Window manager
= XGetSelectionOwner(gdk_x11_get_default_xdisplay(), atom
);
122 return manager
!= None
;
124 //-----------------------------------------------------------------------------
126 wxTaskBarIcon::Private::Private(wxTaskBarIcon
* taskBarIcon
)
128 m_taskBarIcon
= taskBarIcon
;
130 m_eggTrayIcon
= NULL
;
136 wxTaskBarIcon::Private::~Private()
139 g_object_unref(m_statusIcon
);
140 else if (m_eggTrayIcon
)
142 g_signal_handlers_disconnect_by_func(m_eggTrayIcon
, (void*)icon_destroy
, this);
143 gtk_widget_destroy(m_eggTrayIcon
);
147 m_win
->PopEventHandler();
152 gtk_object_destroy(GTK_OBJECT(m_tooltips
));
153 g_object_unref(m_tooltips
);
157 void wxTaskBarIcon::Private::SetIcon()
159 #if GTK_CHECK_VERSION(2,10,0)
160 if (gtk_check_version(2,10,0) == NULL
)
163 gtk_status_icon_set_from_pixbuf(m_statusIcon
, m_bitmap
.GetPixbuf());
166 m_statusIcon
= gtk_status_icon_new_from_pixbuf(m_bitmap
.GetPixbuf());
167 g_signal_connect(m_statusIcon
, "activate",
168 G_CALLBACK(icon_activate
), m_taskBarIcon
);
169 g_signal_connect(m_statusIcon
, "popup_menu",
170 G_CALLBACK(status_icon_popup_menu
), m_taskBarIcon
);
179 GtkWidget
* image
= GTK_BIN(m_eggTrayIcon
)->child
;
180 gtk_image_set_from_pixbuf(GTK_IMAGE(image
), m_bitmap
.GetPixbuf());
184 m_eggTrayIcon
= GTK_WIDGET(egg_tray_icon_new("wxTaskBarIcon"));
185 gtk_widget_add_events(m_eggTrayIcon
, GDK_BUTTON_PRESS_MASK
);
186 g_signal_connect(m_eggTrayIcon
, "size_allocate",
187 G_CALLBACK(icon_size_allocate
), this);
188 g_signal_connect(m_eggTrayIcon
, "destroy",
189 G_CALLBACK(icon_destroy
), this);
190 g_signal_connect(m_eggTrayIcon
, "button_press_event",
191 G_CALLBACK(icon_button_press_event
), m_taskBarIcon
);
192 g_signal_connect(m_eggTrayIcon
, "popup_menu",
193 G_CALLBACK(icon_popup_menu
), m_taskBarIcon
);
194 GtkWidget
* image
= gtk_image_new_from_pixbuf(m_bitmap
.GetPixbuf());
195 gtk_container_add(GTK_CONTAINER(m_eggTrayIcon
), image
);
196 gtk_widget_show_all(m_eggTrayIcon
);
200 const char *tip_text
= NULL
;
201 if (!m_tipText
.empty())
202 tip_text
= m_tipText
.c_str();
204 #if GTK_CHECK_VERSION(2,10,0)
206 gtk_status_icon_set_tooltip(m_statusIcon
, tip_text
);
210 if (tip_text
&& m_tooltips
== NULL
)
212 m_tooltips
= gtk_tooltips_new();
213 g_object_ref(m_tooltips
);
214 gtk_object_sink(GTK_OBJECT(m_tooltips
));
217 gtk_tooltips_set_tip(m_tooltips
, m_eggTrayIcon
, tip_text
, "");
219 #endif // wxUSE_TOOLTIPS
222 void wxTaskBarIcon::Private::size_allocate(int width
, int height
)
225 EggTrayIcon
* icon
= EGG_TRAY_ICON(m_eggTrayIcon
);
226 if (egg_tray_icon_get_orientation(icon
) == GTK_ORIENTATION_VERTICAL
)
231 int w
= m_bitmap
.GetWidth();
232 int h
= m_bitmap
.GetHeight();
233 if (w
> size
|| h
> size
)
235 if (w
> size
) w
= size
;
236 if (h
> size
) h
= size
;
238 gdk_pixbuf_scale_simple(m_bitmap
.GetPixbuf(), w
, h
, GDK_INTERP_BILINEAR
);
239 GtkImage
* image
= GTK_IMAGE(GTK_BIN(m_eggTrayIcon
)->child
);
240 gtk_image_set_from_pixbuf(image
, pixbuf
);
241 g_object_unref(pixbuf
);
244 //-----------------------------------------------------------------------------
246 IMPLEMENT_DYNAMIC_CLASS(wxTaskBarIcon
, wxEvtHandler
)
248 wxTaskBarIcon::wxTaskBarIcon()
250 m_priv
= new Private(this);
253 wxTaskBarIcon::~wxTaskBarIcon()
258 bool wxTaskBarIcon::SetIcon(const wxIcon
& icon
, const wxString
& tooltip
)
260 m_priv
->m_bitmap
= icon
;
261 m_priv
->m_tipText
= tooltip
;
266 bool wxTaskBarIcon::RemoveIcon()
269 m_priv
= new Private(this);
273 bool wxTaskBarIcon::IsIconInstalled() const
275 return m_priv
->m_statusIcon
|| m_priv
->m_eggTrayIcon
;
278 bool wxTaskBarIcon::PopupMenu(wxMenu
* menu
)
281 if (m_priv
->m_win
== NULL
)
283 m_priv
->m_win
= new wxTopLevelWindow(
284 NULL
, wxID_ANY
, wxString(), wxDefaultPosition
, wxDefaultSize
, 0);
285 m_priv
->m_win
->PushEventHandler(this);
287 wxPoint
point(-1, -1);
288 #ifdef __WXUNIVERSAL__
289 point
= wxGetMousePosition();
291 m_priv
->m_win
->PopupMenu(menu
, point
);
292 #endif // wxUSE_MENUS
296 #endif // wxUSE_TASKBARICON