diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | ChangeLog.ja | 12 | ||||
-rw-r--r-- | libsylph/prefs_common.c | 1 | ||||
-rw-r--r-- | libsylph/prefs_common.h | 1 | ||||
-rw-r--r-- | src/mainwindow.c | 12 | ||||
-rw-r--r-- | src/mainwindow.h | 3 | ||||
-rw-r--r-- | src/prefs_common_dialog.c | 21 | ||||
-rw-r--r-- | src/trayicon.c | 168 | ||||
-rw-r--r-- | src/trayicon.h | 21 |
9 files changed, 203 insertions, 47 deletions
@@ -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); |