2007-01-28 [wwp] 2.7.2cvs4
authorTristan Chabredier <wwp@claws-mail.org>
Sun, 28 Jan 2007 12:05:08 +0000 (12:05 +0000)
committerTristan Chabredier <wwp@claws-mail.org>
Sun, 28 Jan 2007 12:05:08 +0000 (12:05 +0000)
* src/mainwindow.c
* src/mainwindow.h
* src/plugins/trayicon/trayicon.c
* src/plugins/trayicon/trayicon_prefs.c
* src/plugins/trayicon/trayicon_prefs.h
Added a new TrayIcon plugin option to close to tray
(WM's hotkey and [X] button will hide the window instead
of closing it - closing CM can be done using the tray icon
menu or the File menu).
Improved visibility handling in trayicon, clicking the
trayicon now raise the window to current desktop when it
was either minimized/shaded/on another desktop.
Thanks to Paul for testing and fixing a strange behaviour
in KDE ;-).

ChangeLog
PATCHSETS
configure.ac
src/mainwindow.c
src/mainwindow.h
src/plugins/trayicon/trayicon.c
src/plugins/trayicon/trayicon_prefs.c
src/plugins/trayicon/trayicon_prefs.h

index 33777d30d05b1863246cf9b991583feb3af8b73f..90c1991dea0c237e09bf1201cb6c8c4e72282a26 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2007-01-28 [wwp]       2.7.2cvs4
+
+       * src/mainwindow.c
+       * src/mainwindow.h
+       * src/plugins/trayicon/trayicon.c
+       * src/plugins/trayicon/trayicon_prefs.c
+       * src/plugins/trayicon/trayicon_prefs.h
+               Added a new TrayIcon plugin option to close to tray
+               (WM's hotkey and [X] button will hide the window instead
+               of closing it - closing CM can be done using the tray icon
+               menu or the File menu).
+               Improved visibility handling in trayicon, clicking the
+               trayicon now raise the window to current desktop when it
+               was either minimized/shaded/on another desktop.
+               Thanks to Paul for testing and fixing a strange behaviour
+               in KDE ;-).
+
 2007-01-27 [paul]      2.7.2cvs3
 
        * src/prefs_folder_item.c
index c5fdc67ac35275fe2620dbd4deb374e030bd372b..e26a7db99f0f165a59e1853189ab7454e6b3ade6 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.42.2.26 -r 1.42.2.27 NEWS;  cvs diff -u -r 1.8.2.30 -r 1.8.2.31 README;  cvs diff -u -r 1.1.2.15 -r 1.1.2.16 RELEASE_NOTES;  cvs diff -u -r 1.654.2.2372 -r 1.654.2.2373 configure.ac;  ) > 2.7.2cvs1.patchset
 ( cvs diff -u -r 1.4.2.8 -r 1.4.2.9 src/plugins/trayicon/Makefile.am;  cvs diff -u -r 1.14.2.47 -r 1.14.2.48 src/plugins/trayicon/trayicon.c;  diff -u /dev/null src/plugins/trayicon/trayicon_prefs.c;  diff -u /dev/null src/plugins/trayicon/trayicon_prefs.h;  ) > 2.7.2cvs2.patchset
 ( cvs diff -u -r 1.52.2.36 -r 1.52.2.37 src/prefs_folder_item.c;  cvs diff -u -r 1.1.2.16 -r 1.1.2.17 src/prefs_receive.c;  cvs diff -u -r 1.1.2.17 -r 1.1.2.18 src/plugins/pgpcore/prefs_gpg.c;  ) > 2.7.2cvs3.patchset
+( cvs diff -u -r 1.274.2.168 -r 1.274.2.169 src/mainwindow.c;  cvs diff -u -r 1.39.2.31 -r 1.39.2.32 src/mainwindow.h;  cvs diff -u -r 1.14.2.48 -r 1.14.2.49 src/plugins/trayicon/trayicon.c;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 src/plugins/trayicon/trayicon_prefs.c;  cvs diff -u -r 1.1.2.1 -r 1.1.2.2 src/plugins/trayicon/trayicon_prefs.h;  ) > 2.7.2cvs4.patchset
index cb216b92726f944a09ec46d7fdaa5c62af1f87dd..5f33c0512cbfd8d2105a7002536c3d77b69b36a7 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=7
 MICRO_VERSION=2
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=3
+EXTRA_VERSION=4
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index c6ae75284b8764659ea0b6662a2fd36cf72727ec..734f8ac10da413c8d2b2cbe1297a3026a2070a79 100644 (file)
@@ -467,6 +467,9 @@ static void sync_cb          ( MainWindow *mainwin,
 static gboolean mainwindow_focus_in_event      (GtkWidget      *widget, 
                                                 GdkEventFocus  *focus,
                                                 gpointer        data);
+static gboolean mainwindow_visibility_event_cb (GtkWidget      *widget, 
+                                                GdkEventVisibility     *state,
+                                                gpointer        data);
 static void main_window_reply_cb                       (MainWindow     *mainwin, 
                                                 guint           action,
                                                 GtkWidget      *widget);
@@ -882,6 +885,7 @@ static GtkItemFactoryEntry mainwin_entries[] =
 
 static gboolean offline_ask_sync = TRUE;
 static guint lastkey;
+static gboolean is_obscured = FALSE;
 
 static gboolean main_window_accel_activate (GtkAccelGroup *accelgroup,
                                             GObject *arg1,
@@ -1420,9 +1424,12 @@ MainWindow *main_window_create()
           menu items in different menus             */
        menu_connect_identical_items();
 
-
        gtk_window_iconify(GTK_WINDOW(mainwin->window));
 
+       g_signal_connect(G_OBJECT(window), "visibility_notify_event",
+                        G_CALLBACK(mainwindow_visibility_event_cb), mainwin);
+       gtk_widget_add_events(GTK_WIDGET(window), GDK_VISIBILITY_NOTIFY_MASK);
+
        if (prefs_common.layout_mode == VERTICAL_LAYOUT)
                summary_relayout(mainwin->summaryview); 
 
@@ -2841,8 +2848,11 @@ static gint main_window_close_cb(GtkWidget *widget, GdkEventAny *event,
                                 gpointer data)
 {
        MainWindow *mainwin = (MainWindow *)data;
+       gboolean close_allowed = TRUE;
 
-       if (mainwin->lock_count == 0)
+       hooks_invoke(MAIN_WINDOW_CLOSE, &close_allowed);
+
+       if (close_allowed && mainwin->lock_count == 0)
                app_exit_cb(data, 0, widget);
 
        return TRUE;
@@ -3758,6 +3768,18 @@ static gboolean mainwindow_focus_in_event(GtkWidget *widget, GdkEventFocus *focu
        return FALSE;
 }
 
+static gboolean mainwindow_visibility_event_cb(GtkWidget *widget, GdkEventVisibility *event,
+                                         gpointer data)
+{
+       is_obscured = (event->state == GDK_VISIBILITY_FULLY_OBSCURED);
+       return FALSE;
+}
+
+gboolean mainwindow_is_obscured(void)
+{
+       return is_obscured;
+}
+
 #define BREAK_ON_MODIFIER_KEY() \
        if ((event->state & (GDK_MOD1_MASK|GDK_CONTROL_MASK)) != 0) break
 
index 62c20e09b798c8756efb4a8802fb557bcf5877b0..c549f31fd1ecf07201a0546c90bf82b7494297fb 100644 (file)
@@ -33,6 +33,7 @@ typedef struct _MainWindow  MainWindow;
 
 #define OFFLINE_SWITCH_HOOKLIST "offline_switch"
 #define ACCOUNT_LIST_CHANGED_HOOKLIST "account_list_changed"
+#define MAIN_WINDOW_CLOSE "mainwindow_close"
 
 typedef enum
 {
@@ -201,4 +202,5 @@ void mainwindow_learn                             (MainWindow *mainwin,
 void mainwindow_jump_to                              (const gchar       *target);
 void mainwindow_show_error                   (void);
 void mainwindow_clear_error                  (MainWindow *mainwin);
+gboolean mainwindow_is_obscured      (void);
 #endif /* __MAINWINDOW_H__ */
index b68ec70448700cd2bc622d49c93189bd421b40ef..a91784abcee06484802c9e78e83117ee23c5b807 100644 (file)
@@ -64,6 +64,7 @@ static guint item_hook_id;
 static guint folder_hook_id;
 static guint offline_hook_id;
 static guint account_hook_id;
+static guint close_hook_id;
 
 static GdkPixmap *newmail_pixmap[2];
 static GdkPixmap *newmail_bitmap[2];
@@ -246,6 +247,20 @@ static gboolean offline_update_hook(gpointer source, gpointer data)
        return FALSE;
 }
 
+static gboolean trayicon_close_hook(gpointer source, gpointer data)
+{
+       if (source) {
+               gboolean *close_allowed = (gboolean*)source;
+               MainWindow *mainwin = mainwindow_get_mainwindow();
+
+               if (trayicon_prefs.close_to_tray)
+                       *close_allowed = FALSE;
+               if (GTK_WIDGET_VISIBLE(GTK_WIDGET(mainwin->window)))
+                       main_window_hide(mainwin);
+       }
+       return FALSE;
+}
+
 static void resize_cb(GtkWidget *widget, GtkRequisition *req,
                      gpointer user_data)
 {
@@ -266,8 +281,15 @@ static gboolean click_cb(GtkWidget * widget,
        switch (event->button) {
        case 1:
                if (GTK_WIDGET_VISIBLE(GTK_WIDGET(mainwin->window))) {
-                       main_window_hide(mainwin);
+                       if ((gdk_window_get_state(GTK_WIDGET(mainwin->window)->window)&GDK_WINDOW_STATE_ICONIFIED)
+                                       || mainwindow_is_obscured()) {
+                               gtk_window_deiconify(GTK_WINDOW(mainwin->window));
+                               main_window_show(mainwin);
+                       } else {
+                               main_window_hide(mainwin);
+                       }
                } else {
+                       gtk_window_deiconify(GTK_WINDOW(mainwin->window));
                        main_window_show(mainwin);
         }
                break;
@@ -378,7 +400,13 @@ int plugin_init(gchar **error)
 
        account_hook_id = hooks_register_hook (ACCOUNT_LIST_CHANGED_HOOKLIST, trayicon_set_accounts_hook, NULL);
        if (offline_hook_id == -1) {
-               *error = g_strdup(_("Failed to register offline switch hook"));
+               *error = g_strdup(_("Failed to register account list changed hook"));
+               return -1;
+       }
+
+       close_hook_id = hooks_register_hook (MAIN_WINDOW_CLOSE, trayicon_close_hook, NULL);
+       if (close_hook_id == -1) {
+               *error = g_strdup(_("Failed to register close hook"));
                return -1;
        }
 
@@ -405,6 +433,7 @@ void plugin_done(void)
        hooks_unregister_hook(FOLDER_UPDATE_HOOKLIST, folder_hook_id);
        hooks_unregister_hook(OFFLINE_SWITCH_HOOKLIST, offline_hook_id);
        hooks_unregister_hook(ACCOUNT_LIST_CHANGED_HOOKLIST, account_hook_id);
+       hooks_unregister_hook(MAIN_WINDOW_CLOSE, close_hook_id);
 
        if (claws_is_exiting())
                return;
index b9c7808c6419854a0a8990ab9649771f407ba6cf..8abb23289de0cc67d22f4c2fbd7bfdcdad19ed8c 100644 (file)
@@ -42,10 +42,12 @@ typedef struct _TrayIconPage TrayIconPage;
 struct _TrayIconPage {
         PrefsPage page;
         GtkWidget *hide_at_startup;
+               GtkWidget *close_to_tray;
 };
 
 static PrefParam param[] = {
         {"hide_at_startup", "FALSE", &trayicon_prefs.hide_at_startup, P_BOOL, NULL, NULL, NULL},
+        {"close_to_tray", "FALSE", &trayicon_prefs.close_to_tray, P_BOOL, NULL, NULL, NULL},
         {0,0,0,0,0,0,0}
 };
 
@@ -93,6 +95,8 @@ static void create_trayicon_prefs_page(PrefsPage *page,
         GtkWidget *vbox;
         GtkWidget *hide_at_startup_checkbox;
        GtkTooltips *hide_at_startup_tooltip;
+        GtkWidget *close_to_tray_checkbox;
+       GtkTooltips *close_to_tray_tooltip;
 
         vbox = gtk_vbox_new(FALSE, 3);
         gtk_container_set_border_width(GTK_CONTAINER(vbox), VBOX_BORDER);
@@ -108,7 +112,18 @@ static void create_trayicon_prefs_page(PrefsPage *page,
        gtk_tooltips_set_tip(GTK_TOOLTIPS(hide_at_startup_tooltip), hide_at_startup_checkbox,
                             _("Hide Claws Mail at start-up"), NULL);
         
+       close_to_tray_tooltip = gtk_tooltips_new();
+        close_to_tray_checkbox = gtk_check_button_new_with_label
+                               (_("Close to tray"));
+        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(close_to_tray_checkbox),
+                                     trayicon_prefs.close_to_tray);
+        gtk_box_pack_start(GTK_BOX(vbox), close_to_tray_checkbox, FALSE, FALSE, 0);
+        gtk_widget_show(close_to_tray_checkbox);
+       gtk_tooltips_set_tip(GTK_TOOLTIPS(close_to_tray_tooltip), close_to_tray_checkbox,
+                            _("Hide Claws Mail using the tray icon instead of closing it\nwhen the window close button is clicked"), NULL);
+
         prefs_page->hide_at_startup = hide_at_startup_checkbox;
+        prefs_page->close_to_tray = close_to_tray_checkbox;
         prefs_page->page.widget = vbox;
 }
 
@@ -126,6 +141,8 @@ static void save_trayicon_prefs(PrefsPage *page)
         
         trayicon_prefs.hide_at_startup = gtk_toggle_button_get_active
                                (GTK_TOGGLE_BUTTON(prefs_page->hide_at_startup));
+        trayicon_prefs.close_to_tray = gtk_toggle_button_get_active
+                               (GTK_TOGGLE_BUTTON(prefs_page->close_to_tray));
         
         pref_file = prefs_write_open(rc_file_path);
         g_free(rc_file_path);
index 69361709561aa9033a847aed54750b1d2b05362d..003d23b6f4e38346f01ffc267c45dc013f83f32b 100644 (file)
@@ -26,7 +26,8 @@ typedef struct _TrayIconPrefs TrayIconPrefs;
 
 struct _TrayIconPrefs
 {
-       gboolean hide_at_startup;       /**< hide when  */
+       gboolean hide_at_startup;       /**< hide main-window at startup */
+       gboolean close_to_tray; /**< hide main-window when [X] is clicked */
 };
 
 extern TrayIconPrefs trayicon_prefs;