Statistics
| Revision:

root / src / trayicon.c @ 1198

History | View | Annotate | Download (10.3 kB)

1
/*
2
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3
 * Copyright (C) 1999-2006 Hiroyuki Yamamoto
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
 */
19
20
#ifdef HAVE_CONFIG_H
21
#  include "config.h"
22
#endif
23
24
#include <glib.h>
25
#include <glib/gi18n.h>
26
#include <gtk/gtkwindow.h>
27
#include <gtk/gtkeventbox.h>
28
#include <gtk/gtktooltips.h>
29
#include <gtk/gtkimage.h>
30
#include <gtk/gtkmenu.h>
31
#include <gtk/gtkmenuitem.h>
32
#include <gtk/gtkversion.h>
33
34
#include "eggtrayicon.h"
35
#include "trayicon.h"
36
#include "mainwindow.h"
37
#include "utils.h"
38
#include "gtkutils.h"
39
#include "eggtrayicon.h"
40
#include "stock_pixmap.h"
41
#include "menu.h"
42
#include "main.h"
43
#include "inc.h"
44
#include "compose.h"
45
#include "gtkutils.h"
46
47
#if GTK_CHECK_VERSION(2, 10, 0) || defined(GDK_WINDOWING_X11)
48
49
#if GTK_CHECK_VERSION(2, 10, 0)
50
51
#include <gtk/gtkstatusicon.h>
52
53
static TrayIcon trayicon;
54
static GtkWidget *trayicon_menu;
55
static gboolean default_tooltip = FALSE;
56
57
static void trayicon_activated                (GtkStatusIcon        *status_icon,
58
                                         gpointer         data);
59
static void trayicon_popup_menu_cb        (GtkStatusIcon        *status_icon,
60
                                         guint                 button,
61
                                         guint                 activate_time,
62
                                         gpointer         data);
63
64
#else
65
66
static TrayIcon trayicon;
67
static GtkWidget *trayicon_img;
68
static GtkWidget *eventbox;
69
static GtkTooltips *trayicon_tip;
70
static GtkWidget *trayicon_menu;
71
static gboolean default_tooltip = FALSE;
72
73
static void trayicon_button_pressed        (GtkWidget        *widget,
74
                                         GdkEventButton        *event,
75
                                         gpointer         data);
76
static void trayicon_destroy_cb                (GtkWidget        *widget,
77
                                         gpointer         data);
78
79
#endif
80
81
static void trayicon_window_present        (GtkWindow        *window);
82
83
static void trayicon_present                (GtkWidget        *widget,
84
                                         gpointer         data);
85
static void trayicon_inc                (GtkWidget        *widget,
86
                                         gpointer         data);
87
static void trayicon_inc_all                (GtkWidget        *widget,
88
                                         gpointer         data);
89
static void trayicon_send                (GtkWidget        *widget,
90
                                         gpointer         data);
91
static void trayicon_compose                (GtkWidget        *widget,
92
                                         gpointer         data);
93
static void trayicon_app_exit                (GtkWidget        *widget,
94
                                         gpointer         data);
95
96
TrayIcon *trayicon_create(MainWindow *mainwin)
97
{
98
        GtkWidget *menuitem;
99
100
#if GTK_CHECK_VERSION(2, 10, 0)
101
        GdkPixbuf *pixbuf;
102
103
#ifdef G_OS_WIN32
104
        stock_pixbuf_gdk(NULL, STOCK_PIXMAP_SYLPHEED_SMALL, &pixbuf);
105
#else
106
        stock_pixbuf_gdk(NULL, STOCK_PIXMAP_SYLPHEED, &pixbuf);
107
#endif
108
        trayicon.status_icon = gtk_status_icon_new_from_pixbuf(pixbuf);
109
110
        g_signal_connect(G_OBJECT(trayicon.status_icon), "activate",
111
                         G_CALLBACK(trayicon_activated), mainwin);
112
        g_signal_connect(G_OBJECT(trayicon.status_icon), "popup-menu",
113
                         G_CALLBACK(trayicon_popup_menu_cb), mainwin);
114
#else
115
        trayicon.widget = GTK_WIDGET(egg_tray_icon_new("Sylpheed"));
116
        g_signal_connect(G_OBJECT(trayicon.widget), "destroy",
117
                         G_CALLBACK(trayicon_destroy_cb), mainwin);
118
119
        eventbox = gtk_event_box_new();
120
        gtk_widget_show(eventbox);
121
        gtk_container_add(GTK_CONTAINER(trayicon.widget), eventbox);
122
        g_signal_connect(G_OBJECT(eventbox), "button_press_event",
123
                         G_CALLBACK(trayicon_button_pressed), mainwin);
124
        trayicon_img = stock_pixbuf_widget_scale(NULL, STOCK_PIXMAP_SYLPHEED,
125
                                                 24, 24);
126
        gtk_widget_show(trayicon_img);
127
        gtk_container_add(GTK_CONTAINER(eventbox), trayicon_img);
128
129
        trayicon_tip = gtk_tooltips_new();
130
#endif
131
        default_tooltip = FALSE;
132
        trayicon_set_tooltip(NULL);
133
134
        if (!trayicon_menu) {
135
                trayicon_menu = gtk_menu_new();
136
                gtk_widget_show(trayicon_menu);
137
                MENUITEM_ADD_WITH_MNEMONIC(trayicon_menu, menuitem,
138
                                           _("_Display Sylpheed"), 0);
139
                g_signal_connect(G_OBJECT(menuitem), "activate",
140
                                 G_CALLBACK(trayicon_present), mainwin);
141
                MENUITEM_ADD(trayicon_menu, menuitem, NULL, 0);
142
                MENUITEM_ADD_WITH_MNEMONIC(trayicon_menu, menuitem,
143
                                           _("Get from _current account"), 0);
144
                g_signal_connect(G_OBJECT(menuitem), "activate",
145
                                 G_CALLBACK(trayicon_inc), mainwin);
146
                MENUITEM_ADD_WITH_MNEMONIC(trayicon_menu, menuitem,
147
                                           _("Get from _all accounts"), 0);
148
                g_signal_connect(G_OBJECT(menuitem), "activate",
149
                                 G_CALLBACK(trayicon_inc_all), mainwin);
150
                MENUITEM_ADD_WITH_MNEMONIC(trayicon_menu, menuitem,
151
                                           _("_Send queued messages"), 0);
152
                g_signal_connect(G_OBJECT(menuitem), "activate",
153
                                 G_CALLBACK(trayicon_send), mainwin);
154
155
                MENUITEM_ADD(trayicon_menu, menuitem, NULL, 0);
156
                MENUITEM_ADD_WITH_MNEMONIC(trayicon_menu, menuitem,
157
                                           _("Compose _new message"), 0);
158
                g_signal_connect(G_OBJECT(menuitem), "activate",
159
                                 G_CALLBACK(trayicon_compose), mainwin);
160
161
                MENUITEM_ADD(trayicon_menu, menuitem, NULL, 0);
162
                MENUITEM_ADD_WITH_MNEMONIC(trayicon_menu, menuitem,
163
                                           _("E_xit"), 0);
164
                g_signal_connect(G_OBJECT(menuitem), "activate",
165
                                 G_CALLBACK(trayicon_app_exit), mainwin);
166
        }
167
168
        return &trayicon;
169
}
170
171
#if GTK_CHECK_VERSION(2, 10, 0)
172
173
void trayicon_show(TrayIcon *tray_icon)
174
{
175
        gtk_status_icon_set_visible(tray_icon->status_icon, TRUE);
176
};
177
178
void trayicon_hide(TrayIcon *tray_icon)
179
{
180
        gtk_status_icon_set_visible(tray_icon->status_icon, FALSE);
181
}
182
183
void trayicon_destroy(TrayIcon *tray_icon)
184
{
185
        g_object_unref(tray_icon->status_icon);
186
        tray_icon->status_icon = NULL;
187
}
188
189
void trayicon_set_tooltip(const gchar *text)
190
{
191
        if (text) {
192
                default_tooltip = FALSE;
193
                gtk_status_icon_set_tooltip(trayicon.status_icon, text);
194
        } else if (!default_tooltip) {
195
                default_tooltip = TRUE;
196
                gtk_status_icon_set_tooltip(trayicon.status_icon,
197
                                            _("Sylpheed"));
198
        }
199
}
200
201
static guint notify_tag = 0;
202
203
gboolean notify_timeout_cb(gpointer data)
204
{
205
        gtk_status_icon_set_blinking(trayicon.status_icon, FALSE);
206
        notify_tag = 0;
207
        return FALSE;
208
}
209
210
void trayicon_set_notify(gboolean enabled)
211
{
212
        if (enabled && notify_tag == 0) {
213
                gtk_status_icon_set_blinking(trayicon.status_icon, enabled);
214
                notify_tag = g_timeout_add(5000, notify_timeout_cb, NULL);
215
        } else if (!enabled && notify_tag > 0)
216
                g_source_remove(notify_tag);
217
}
218
219
void trayicon_set_stock_icon(StockPixmap icon)
220
{
221
        GdkPixbuf *pixbuf;
222
        GdkPixbuf *scaled_pixbuf;
223
224
        stock_pixbuf_gdk(NULL, icon, &pixbuf);
225
        scaled_pixbuf = gdk_pixbuf_scale_simple(pixbuf, 24, 24,
226
                                                GDK_INTERP_HYPER);
227
        gtk_status_icon_set_from_pixbuf(trayicon.status_icon, scaled_pixbuf);
228
        g_object_unref(scaled_pixbuf);
229
}
230
231
static void trayicon_activated(GtkStatusIcon *status_icon, gpointer data)
232
{
233
        MainWindow *mainwin = (MainWindow *)data;
234
235
        trayicon_window_present(GTK_WINDOW(mainwin->window));
236
}
237
238
static void trayicon_popup_menu_cb(GtkStatusIcon *status_icon, guint button,
239
                                   guint activate_time, gpointer data)
240
{
241
        gtk_menu_popup(GTK_MENU(trayicon_menu), NULL, NULL, NULL, NULL,
242
                       button, activate_time);
243
}
244
245
#else
246
247
void trayicon_show(TrayIcon *tray_icon)
248
{
249
        gtk_widget_show(tray_icon->widget);
250
};
251
252
void trayicon_hide(TrayIcon *tray_icon)
253
{
254
        gtk_widget_destroy(tray_icon->widget);
255
        tray_icon->widget = NULL;
256
}
257
258
void trayicon_destroy(TrayIcon *tray_icon)
259
{
260
        g_signal_handlers_disconnect_by_func(G_OBJECT(trayicon->widget),
261
                                             G_CALLBACK(trayicon_destroy_cb),
262
                                             mainwin);
263
        gtk_widget_destroy(tray_icon->widget);
264
        tray_icon->widget = NULL;
265
}
266
267
void trayicon_set_tooltip(const gchar *text)
268
{
269
        if (text) {
270
                default_tooltip = FALSE;
271
                gtk_tooltips_set_tip(trayicon_tip, trayicon.widget, text,
272
                                     NULL);
273
        } else if (!default_tooltip) {
274
                default_tooltip = TRUE;
275
                gtk_tooltips_set_tip(trayicon_tip, trayicon.widget,
276
                                     _("Sylpheed"), NULL);
277
        }
278
}
279
280
void trayicon_set_notify(gboolean enabled)
281
{
282
}
283
284
void trayicon_set_stock_icon(StockPixmap icon)
285
{
286
        GdkPixbuf *pixbuf;
287
        GdkPixbuf *scaled_pixbuf;
288
289
        stock_pixbuf_gdk(NULL, icon, &pixbuf);
290
        scaled_pixbuf = gdk_pixbuf_scale_simple(pixbuf, 24, 24,
291
                                                GDK_INTERP_HYPER);
292
        gtk_image_set_from_pixbuf(GTK_IMAGE(trayicon_img), scaled_pixbuf);
293
        g_object_unref(scaled_pixbuf);
294
}
295
296
static void trayicon_button_pressed(GtkWidget *widget, GdkEventButton *event,
297
                                    gpointer data)
298
{
299
        MainWindow *mainwin = (MainWindow *)data;
300
301
        if (!event)
302
                return;
303
304
        if (event->button == 1)
305
                trayicon_window_present(GTK_WINDOW(mainwin->window));
306
        else if (event->button == 3) {
307
                gtk_menu_popup(GTK_MENU(trayicon_menu), NULL, NULL, NULL, NULL,
308
                               event->button, event->time);
309
        }
310
}
311
312
static gboolean trayicon_restore(gpointer data)
313
{
314
        MainWindow *mainwin = (MainWindow *)data;
315
316
        mainwin->tray_icon = trayicon_create(mainwin);
317
        return FALSE;
318
}
319
320
static void trayicon_destroy_cb(GtkWidget *widget, gpointer data)
321
{
322
        g_idle_add(trayicon_restore, data);
323
}
324
325
#endif
326
327
static void trayicon_window_present(GtkWindow *window)
328
{
329
        gtk_window_set_skip_taskbar_hint(window, FALSE);
330
        gtk_window_present(window);
331
}
332
333
static void trayicon_present(GtkWidget *widget, gpointer data)
334
{
335
        MainWindow *mainwin = (MainWindow *)data;
336
337
        trayicon_window_present(GTK_WINDOW(mainwin->window));
338
}
339
340
static void trayicon_inc(GtkWidget *widget, gpointer data)
341
{
342
        if (!inc_is_active() && !gtkut_window_modal_exist())
343
                inc_mail((MainWindow *)data);
344
}
345
346
static void trayicon_inc_all(GtkWidget *widget, gpointer data)
347
{
348
        if (!inc_is_active() && !gtkut_window_modal_exist())
349
                inc_all_account_mail((MainWindow *)data, FALSE);
350
}
351
352
static void trayicon_send(GtkWidget *widget, gpointer data)
353
{
354
        if (!gtkut_window_modal_exist())
355
                main_window_send_queue((MainWindow *)data);
356
}
357
358
static void trayicon_compose(GtkWidget *widget, gpointer data)
359
{
360
        if (!gtkut_window_modal_exist())
361
                compose_new(NULL, NULL, NULL, NULL);
362
}
363
364
static void trayicon_app_exit(GtkWidget *widget, gpointer data)
365
{
366
        MainWindow *mainwin = (MainWindow *)data;
367
368
        if (mainwin->lock_count == 0 && !gtkut_window_modal_exist())
369
                app_will_exit(FALSE);
370
}
371
372
#else /* GTK_CHECK_VERSION(2, 10, 0) || defined(GDK_WINDOWING_X11) */
373
374
TrayIcon *trayicon_create(MainWindow *mainwin)
375
{
376
        return NULL;
377
}
378
379
void trayicon_show(TrayIcon *tray_icon)
380
{
381
}
382
383
void trayicon_hide(TrayIcon *tray_icon)
384
{
385
}
386
387
void trayicon_destroy(TrayIcon *tray_icon)
388
{
389
}
390
391
void trayicon_set_tooltip(const gchar *text)
392
{
393
}
394
395
void trayicon_set_notify(gboolean enabled)
396
{
397
}
398
399
void trayicon_set_stock_icon(StockPixmap icon)
400
{
401
}
402
403
#endif /* GTK_CHECK_VERSION(2, 10, 0) || defined(GDK_WINDOWING_X11) */