aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--ChangeLog.ja12
-rw-r--r--libsylph/prefs_common.c1
-rw-r--r--libsylph/prefs_common.h1
-rw-r--r--src/mainwindow.c12
-rw-r--r--src/mainwindow.h3
-rw-r--r--src/prefs_common_dialog.c21
-rw-r--r--src/trayicon.c168
-rw-r--r--src/trayicon.h21
9 files changed, 203 insertions, 47 deletions
diff --git a/ChangeLog b/ChangeLog
index a23a90cf..94be6488 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
2006-09-26
+ * libsylph/prefs_common.[ch]
+ src/trayicon.[ch]
+ src/prefs_common_dialog.c
+ src/mainwindow.c: implemented tray icon in Win32 using GtkStatusIcon.
+ Just present window with left click of the tray icon.
+ Removed 'About' menu.
+ Added 'Display Sylpheed' menu.
+ Added 'Minimize to tray icon' option.
+
+2006-09-26
+
* libsylph/session.[ch]: win32: made workaround for state machine
freeze problem in GLib >= 2.8.x.
session_read_data_as_file_cb(): reset Session::read_buf_len to
diff --git a/ChangeLog.ja b/ChangeLog.ja
index 7288c0f2..12d0b53d 100644
--- a/ChangeLog.ja
+++ b/ChangeLog.ja
@@ -1,5 +1,17 @@
2006-09-26
+ * libsylph/prefs_common.[ch]
+ src/trayicon.[ch]
+ src/prefs_common_dialog.c
+ src/mainwindow.c: GtkStatusIcon を使用して Win32 でトレイアイコンを
+ 実装。
+ トレイアイコンの左クリックでウィンドウを表示するだけにした。
+ 「このプログラムについて」メニューを削除。
+ 「Sylpheedを表示」メニューを追加。
+ 「最小化時にトレイアイコンに格納する」オプションを追加。
+
+2006-09-26
+
* libsylph/session.[ch]: win32: GLib >= 2.8.x でステートマシンが
フリーズする問題に対処。
session_read_data_as_file_cb(): 予期せず idle 関数が呼ばれるのを
diff --git a/libsylph/prefs_common.c b/libsylph/prefs_common.c
index 24d67589..80c2fd2c 100644
--- a/libsylph/prefs_common.c
+++ b/libsylph/prefs_common.c
@@ -332,6 +332,7 @@ static PrefParam param[] = {
#endif
{"show_trayicon", "TRUE", &prefs_common.show_trayicon, P_BOOL},
+ {"minimize_to_tray", "FALSE", &prefs_common.minimize_to_tray, P_BOOL},
/* Other */
{"receive_dialog_mode", "1", &prefs_common.recv_dialog_mode, P_ENUM},
diff --git a/libsylph/prefs_common.h b/libsylph/prefs_common.h
index 5d9eb9d5..0bfda22a 100644
--- a/libsylph/prefs_common.h
+++ b/libsylph/prefs_common.h
@@ -235,6 +235,7 @@ struct _PrefsCommon
gboolean immediate_exec;
gboolean comply_gnome_hig;
gboolean show_trayicon;
+ gboolean minimize_to_tray;
/* Other */
RecvDialogMode recv_dialog_mode;
diff --git a/src/mainwindow.c b/src/mainwindow.c
index 3a46c90a..814fbcf5 100644
--- a/src/mainwindow.c
+++ b/src/mainwindow.c
@@ -849,7 +849,7 @@ MainWindow *main_window_create(SeparateType type)
GtkWidget *ac_button;
GtkWidget *ac_label;
- GtkWidget *tray_icon;
+ TrayIcon *tray_icon;
FolderView *folderview;
SummaryView *summaryview;
@@ -966,7 +966,7 @@ MainWindow *main_window_create(SeparateType type)
tray_icon = trayicon_create(mainwin);
if (tray_icon && prefs_common.show_trayicon)
- gtk_widget_show(tray_icon);
+ trayicon_show(tray_icon);
/* create views */
mainwin->folderview = folderview = folderview_create();
@@ -1222,10 +1222,10 @@ void main_window_reflect_prefs_all(void)
if (mainwin->tray_icon) {
if (prefs_common.show_trayicon)
- gtk_widget_show(mainwin->tray_icon);
+ trayicon_show(mainwin->tray_icon);
else {
/* trayicon is automatically restored after this */
- gtk_widget_destroy(mainwin->tray_icon);
+ trayicon_destroy(mainwin->tray_icon);
}
}
@@ -2807,6 +2807,10 @@ static gboolean main_window_window_state_cb(GtkWidget *widget,
mainwin->window_hidden = FALSE;
}
+ if (mainwin->window_hidden &&
+ prefs_common.show_trayicon && prefs_common.minimize_to_tray)
+ gtk_window_set_skip_taskbar_hint(GTK_WINDOW(widget), TRUE);
+
return FALSE;
}
diff --git a/src/mainwindow.h b/src/mainwindow.h
index f5162655..9c591fe8 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -33,6 +33,7 @@ typedef struct _MainWindow MainWindow;
#include "headerview.h"
#include "messageview.h"
#include "logwindow.h"
+#include "trayicon.h"
#include "gtkutils.h"
typedef enum
@@ -102,7 +103,7 @@ struct _MainWindow
GtkWidget *ac_label;
GtkWidget *ac_menu;
- GtkWidget *tray_icon;
+ TrayIcon *tray_icon;
/* context IDs for status bar */
gint mainwin_cid;
diff --git a/src/prefs_common_dialog.c b/src/prefs_common_dialog.c
index 13f4e311..0a0e4e20 100644
--- a/src/prefs_common_dialog.c
+++ b/src/prefs_common_dialog.c
@@ -188,8 +188,9 @@ static struct Interface {
GtkWidget *checkbtn_immedexec;
#ifndef G_OS_WIN32
GtkWidget *checkbtn_comply_gnome_hig;
- GtkWidget *checkbtn_show_trayicon;
#endif
+ GtkWidget *checkbtn_show_trayicon;
+ GtkWidget *checkbtn_minimize_to_tray;
} interface;
static struct Other {
@@ -457,9 +458,11 @@ static PrefsUIData ui_data[] = {
#ifndef G_OS_WIN32
{"comply_gnome_hig", &interface.checkbtn_comply_gnome_hig,
prefs_set_data_from_toggle, prefs_set_toggle},
+#endif
{"show_trayicon", &interface.checkbtn_show_trayicon,
prefs_set_data_from_toggle, prefs_set_toggle},
-#endif
+ {"minimize_to_tray", &interface.checkbtn_minimize_to_tray,
+ prefs_set_data_from_toggle, prefs_set_toggle},
/* Other */
{"receive_dialog_mode", &other.optmenu_recvdialog,
@@ -2051,8 +2054,9 @@ static void prefs_details_create(void)
GtkWidget *label;
#ifndef G_OS_WIN32
GtkWidget *checkbtn_comply_gnome_hig;
- GtkWidget *checkbtn_show_trayicon;
#endif
+ GtkWidget *checkbtn_show_trayicon;
+ GtkWidget *checkbtn_minimize_to_tray;
GtkWidget *button_keybind;
@@ -2115,16 +2119,20 @@ static void prefs_details_create(void)
_("Messages will be marked until execution "
"if this is turned off."));
-#ifndef G_OS_WIN32
vbox2 = gtk_vbox_new (FALSE, 0);
gtk_widget_show (vbox2);
gtk_box_pack_start (GTK_BOX (vbox_tab), vbox2, FALSE, FALSE, 0);
+#ifndef G_OS_WIN32
PACK_CHECK_BUTTON (vbox2, checkbtn_comply_gnome_hig,
_("Make the order of buttons comply with GNOME HIG"));
+#endif
PACK_CHECK_BUTTON (vbox2, checkbtn_show_trayicon,
_("Display tray icon"));
-#endif
+ PACK_CHECK_BUTTON (vbox2, checkbtn_minimize_to_tray,
+ _("Minimize to tray icon"));
+ SET_TOGGLE_SENSITIVITY (checkbtn_show_trayicon,
+ checkbtn_minimize_to_tray);
hbox1 = gtk_hbox_new (FALSE, 8);
gtk_widget_show (hbox1);
@@ -2157,8 +2165,9 @@ static void prefs_details_create(void)
#ifndef G_OS_WIN32
interface.checkbtn_comply_gnome_hig = checkbtn_comply_gnome_hig;
- interface.checkbtn_show_trayicon = checkbtn_show_trayicon;
#endif
+ interface.checkbtn_show_trayicon = checkbtn_show_trayicon;
+ interface.checkbtn_minimize_to_tray = checkbtn_minimize_to_tray;
}
static GtkWidget *prefs_other_create(void)
diff --git a/src/trayicon.c b/src/trayicon.c
index f150729f..668ce9cb 100644
--- a/src/trayicon.c
+++ b/src/trayicon.c
@@ -29,6 +29,7 @@
#include <gtk/gtkimage.h>
#include <gtk/gtkmenu.h>
#include <gtk/gtkmenuitem.h>
+#include <gtk/gtkversion.h>
#include "eggtrayicon.h"
#include "trayicon.h"
@@ -41,11 +42,27 @@
#include "main.h"
#include "inc.h"
#include "compose.h"
-#include "about.h"
-#ifdef GDK_WINDOWING_X11
+#if GTK_CHECK_VERSION(2, 10, 0) || defined(GDK_WINDOWING_X11)
-static GtkWidget *trayicon;
+#if GTK_CHECK_VERSION(2, 10, 0)
+
+#include <gtk/gtkstatusicon.h>
+
+static TrayIcon trayicon;
+static GtkWidget *trayicon_menu;
+static gboolean default_tooltip = FALSE;
+
+static void trayicon_activated (GtkStatusIcon *status_icon,
+ gpointer data);
+static void trayicon_popup_menu_cb (GtkStatusIcon *status_icon,
+ guint button,
+ guint activate_time,
+ gpointer data);
+
+#else
+
+static TrayIcon trayicon;
static GtkWidget *trayicon_img;
static GtkWidget *eventbox;
static GtkTooltips *trayicon_tip;
@@ -58,6 +75,10 @@ static void trayicon_button_pressed (GtkWidget *widget,
static void trayicon_destroy_cb (GtkWidget *widget,
gpointer data);
+#endif
+
+static void trayicon_present (GtkWidget *widget,
+ gpointer data);
static void trayicon_inc (GtkWidget *widget,
gpointer data);
static void trayicon_inc_all (GtkWidget *widget,
@@ -66,22 +87,31 @@ static void trayicon_send (GtkWidget *widget,
gpointer data);
static void trayicon_compose (GtkWidget *widget,
gpointer data);
-static void trayicon_about (GtkWidget *widget,
- gpointer data);
static void trayicon_app_exit (GtkWidget *widget,
gpointer data);
-GtkWidget *trayicon_create(MainWindow *mainwin)
+TrayIcon *trayicon_create(MainWindow *mainwin)
{
GtkWidget *menuitem;
- trayicon = GTK_WIDGET(egg_tray_icon_new("Sylpheed"));
- g_signal_connect(G_OBJECT(trayicon), "destroy",
+#if GTK_CHECK_VERSION(2, 10, 0)
+ GdkPixbuf *pixbuf;
+
+ stock_pixbuf_gdk(NULL, STOCK_PIXMAP_SYLPHEED, &pixbuf);
+ trayicon.status_icon = gtk_status_icon_new_from_pixbuf(pixbuf);
+
+ g_signal_connect(G_OBJECT(trayicon.status_icon), "activate",
+ G_CALLBACK(trayicon_activated), mainwin);
+ g_signal_connect(G_OBJECT(trayicon.status_icon), "popup-menu",
+ G_CALLBACK(trayicon_popup_menu_cb), mainwin);
+#else
+ trayicon.widget = GTK_WIDGET(egg_tray_icon_new("Sylpheed"));
+ g_signal_connect(G_OBJECT(trayicon.widget), "destroy",
G_CALLBACK(trayicon_destroy_cb), mainwin);
eventbox = gtk_event_box_new();
gtk_widget_show(eventbox);
- gtk_container_add(GTK_CONTAINER(trayicon), eventbox);
+ gtk_container_add(GTK_CONTAINER(trayicon.widget), eventbox);
g_signal_connect(G_OBJECT(eventbox), "button_press_event",
G_CALLBACK(trayicon_button_pressed), mainwin);
trayicon_img = stock_pixbuf_widget_scale(NULL, STOCK_PIXMAP_SYLPHEED,
@@ -89,14 +119,20 @@ GtkWidget *trayicon_create(MainWindow *mainwin)
gtk_widget_show(trayicon_img);
gtk_container_add(GTK_CONTAINER(eventbox), trayicon_img);
- default_tooltip = FALSE;
trayicon_tip = gtk_tooltips_new();
+#endif
+ default_tooltip = FALSE;
trayicon_set_tooltip(NULL);
if (!trayicon_menu) {
trayicon_menu = gtk_menu_new();
gtk_widget_show(trayicon_menu);
MENUITEM_ADD_WITH_MNEMONIC(trayicon_menu, menuitem,
+ _("_Display Sylpheed"), 0);
+ g_signal_connect(G_OBJECT(menuitem), "activate",
+ G_CALLBACK(trayicon_present), mainwin);
+ MENUITEM_ADD(trayicon_menu, menuitem, NULL, 0);
+ MENUITEM_ADD_WITH_MNEMONIC(trayicon_menu, menuitem,
_("Get from _current account"), 0);
g_signal_connect(G_OBJECT(menuitem), "activate",
G_CALLBACK(trayicon_inc), mainwin);
@@ -117,27 +153,82 @@ GtkWidget *trayicon_create(MainWindow *mainwin)
MENUITEM_ADD(trayicon_menu, menuitem, NULL, 0);
MENUITEM_ADD_WITH_MNEMONIC(trayicon_menu, menuitem,
- _("_About"), 0);
- g_signal_connect(G_OBJECT(menuitem), "activate",
- G_CALLBACK(trayicon_about), NULL);
- MENUITEM_ADD_WITH_MNEMONIC(trayicon_menu, menuitem,
_("E_xit"), 0);
g_signal_connect(G_OBJECT(menuitem), "activate",
G_CALLBACK(trayicon_app_exit), mainwin);
}
- return trayicon;
+ return &trayicon;
}
+#if GTK_CHECK_VERSION(2, 10, 0)
+
void trayicon_set_tooltip(const gchar *text)
{
if (text) {
default_tooltip = FALSE;
- gtk_tooltips_set_tip(trayicon_tip, trayicon, text, NULL);
+ gtk_status_icon_set_tooltip(trayicon.status_icon, text);
} else if (!default_tooltip) {
default_tooltip = TRUE;
- gtk_tooltips_set_tip(trayicon_tip, trayicon, _("Sylpheed"),
+ gtk_status_icon_set_tooltip(trayicon.status_icon,
+ _("Sylpheed"));
+ }
+}
+
+void trayicon_set_stock_icon(StockPixmap icon)
+{
+ GdkPixbuf *pixbuf;
+ GdkPixbuf *scaled_pixbuf;
+
+ stock_pixbuf_gdk(NULL, icon, &pixbuf);
+ scaled_pixbuf = gdk_pixbuf_scale_simple(pixbuf, 24, 24,
+ GDK_INTERP_HYPER);
+ gtk_status_icon_set_from_pixbuf(trayicon.status_icon, scaled_pixbuf);
+ g_object_unref(scaled_pixbuf);
+}
+
+void trayicon_show(TrayIcon *tray_icon)
+{
+ gtk_status_icon_set_visible(trayicon.status_icon, TRUE);
+};
+
+void trayicon_destroy(TrayIcon *tray_icon)
+{
+#if 0
+ g_object_unref(tray_icon->status_icon);
+ tray_icon->status_icon = NULL;
+#endif
+ gtk_status_icon_set_visible(tray_icon->status_icon, FALSE);
+}
+
+static void trayicon_activated(GtkStatusIcon *status_icon, gpointer data)
+{
+ MainWindow *mainwin = (MainWindow *)data;
+ GtkWindow *window = GTK_WINDOW(mainwin->window);
+
+ gtk_window_set_skip_taskbar_hint(window, FALSE);
+ gtk_window_present(window);
+}
+
+static void trayicon_popup_menu_cb(GtkStatusIcon *status_icon, guint button,
+ guint activate_time, gpointer data)
+{
+ gtk_menu_popup(GTK_MENU(trayicon_menu), NULL, NULL, NULL, NULL,
+ button, activate_time);
+}
+
+#else
+
+void trayicon_set_tooltip(const gchar *text)
+{
+ if (text) {
+ default_tooltip = FALSE;
+ gtk_tooltips_set_tip(trayicon_tip, trayicon.widget, text,
NULL);
+ } else if (!default_tooltip) {
+ default_tooltip = TRUE;
+ gtk_tooltips_set_tip(trayicon_tip, trayicon.widget,
+ _("Sylpheed"), NULL);
}
}
@@ -153,6 +244,17 @@ void trayicon_set_stock_icon(StockPixmap icon)
g_object_unref(scaled_pixbuf);
}
+void trayicon_show(TrayIcon *tray_icon)
+{
+ gtk_widget_show(tray_icon->widget);
+};
+
+void trayicon_destroy(TrayIcon *tray_icon)
+{
+ gtk_widget_destroy(tray_icon->widget);
+ tray_icon->widget = NULL;
+}
+
static void trayicon_button_pressed(GtkWidget *widget, GdkEventButton *event,
gpointer data)
{
@@ -163,15 +265,8 @@ static void trayicon_button_pressed(GtkWidget *widget, GdkEventButton *event,
return;
if (event->button == 1) {
- if (mainwin->window_hidden || mainwin->window_obscured) {
- gtk_window_set_skip_taskbar_hint(window, FALSE);
- gtk_window_present(window);
- /* window may be obscured by always-on-top windows */
- mainwin->window_obscured = FALSE;
- } else {
- gtk_window_iconify(window);
- gtk_window_set_skip_taskbar_hint(window, TRUE);
- }
+ gtk_window_set_skip_taskbar_hint(window, FALSE);
+ gtk_window_present(window);
} else if (event->button == 3) {
gtk_menu_popup(GTK_MENU(trayicon_menu), NULL, NULL, NULL, NULL,
event->button, event->time);
@@ -191,6 +286,17 @@ static void trayicon_destroy_cb(GtkWidget *widget, gpointer data)
g_idle_add(trayicon_restore, data);
}
+#endif
+
+static void trayicon_present(GtkWidget *widget, gpointer data)
+{
+ MainWindow *mainwin = (MainWindow *)data;
+ GtkWindow *window = GTK_WINDOW(mainwin->window);
+
+ gtk_window_set_skip_taskbar_hint(window, FALSE);
+ gtk_window_present(window);
+}
+
static void trayicon_inc(GtkWidget *widget, gpointer data)
{
if (!inc_is_active() && !gtkut_window_modal_exist())
@@ -215,12 +321,6 @@ static void trayicon_compose(GtkWidget *widget, gpointer data)
compose_new(NULL, NULL, NULL, NULL);
}
-static void trayicon_about(GtkWidget *widget, gpointer data)
-{
- if (!gtkut_window_modal_exist())
- about_show();
-}
-
static void trayicon_app_exit(GtkWidget *widget, gpointer data)
{
MainWindow *mainwin = (MainWindow *)data;
@@ -229,7 +329,7 @@ static void trayicon_app_exit(GtkWidget *widget, gpointer data)
app_will_exit(FALSE);
}
-#else /* GDK_WINDOWING_X11 */
+#else /* GTK_CHECK_VERSION(2, 10, 0) || defined(GDK_WINDOWING_X11) */
GtkWidget *trayicon_create(MainWindow *mainwin)
{
@@ -244,4 +344,4 @@ void trayicon_set_stock_icon(StockPixmap icon)
{
}
-#endif /* GDK_WINDOWING_X11 */
+#endif /* GTK_CHECK_VERSION(2, 10, 0) || defined(GDK_WINDOWING_X11) */
diff --git a/src/trayicon.h b/src/trayicon.h
index b15c132b..a5869666 100644
--- a/src/trayicon.h
+++ b/src/trayicon.h
@@ -1,6 +1,6 @@
/*
* Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 Hiroyuki Yamamoto
+ * Copyright (C) 1999-2006 Hiroyuki Yamamoto
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,11 +22,28 @@
#include <glib.h>
#include <gtk/gtkwidget.h>
+#include <gtk/gtkversion.h>
+
+#if GTK_CHECK_VERSION(2, 10, 0)
+# include <gtk/gtkstatusicon.h>
+#endif
+
+typedef struct _TrayIcon TrayIcon;
#include "mainwindow.h"
#include "stock_pixmap.h"
-GtkWidget *trayicon_create (MainWindow *mainwin);
+struct _TrayIcon
+{
+#if GTK_CHECK_VERSION(2, 10, 0)
+ GtkStatusIcon *status_icon;
+#else
+ GtkWidget *widget;
+#endif
+};
+
+TrayIcon *trayicon_create (MainWindow *mainwin);
+void trayicon_destroy (TrayIcon *tray_icon);
void trayicon_set_tooltip (const gchar *text);
void trayicon_set_stock_icon (StockPixmap icon);