[pan2/testing: 251/279] roughly implement gtk_status_icon for tray minimize
- From: Heinrich MÃller <henmull src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [pan2/testing: 251/279] roughly implement gtk_status_icon for tray minimize
- Date: Sat, 3 Dec 2011 22:42:30 +0000 (UTC)
commit b88abe93aeb0697495c7b449eb5645e83358db74
Author: Heinrich MÃller <sphemuel stud informatik uni-erlangen de>
Date: Wed Nov 23 21:49:55 2011 +0100
roughly implement gtk_status_icon for tray minimize
pan/gui/pan.cc | 132 +++++++++++++++++++++++++++++++++++++++++++++++++-
pan/gui/prefs-ui.cc | 4 ++
2 files changed, 133 insertions(+), 3 deletions(-)
---
diff --git a/pan/gui/pan.cc b/pan/gui/pan.cc
index 6d1b1c0..9f3dbec 100644
--- a/pan/gui/pan.cc
+++ b/pan/gui/pan.cc
@@ -33,6 +33,7 @@ extern "C" {
#include <windows.h>
#endif
+#include <config.h>
#include <pan/general/debug.h>
#include <pan/general/log.h>
#include <pan/general/file-util.h>
@@ -61,6 +62,7 @@ using namespace pan;
namespace
{
+
GMainLoop * nongui_gmainloop (0);
void mainloop ()
@@ -88,9 +90,13 @@ namespace
gtk_main_quit ();
}
- gboolean delete_event_cb (GtkWidget *, GdkEvent *, gpointer )
+ gboolean delete_event_cb (GtkWidget * w, GdkEvent *, gpointer user_data)
{
- mainloop_quit ();
+ Prefs* prefs (static_cast<Prefs*>(user_data));
+ if(prefs->get_flag ("status-icon", true))
+ gtk_widget_hide(w);
+ else
+ mainloop_quit ();
return true; // don't invoke the default handler that destroys the widget
}
@@ -139,6 +145,122 @@ namespace
return true;
}
+ struct StatusIconPrefsListener : public Prefs::Listener,
+ public Queue::Listener
+ {
+ static gboolean status_icon_periodic_refresh (gpointer p)
+ {
+ StatusIconPrefsListener * pl (static_cast<StatusIconPrefsListener*>(p));
+ pl->update_status_tooltip();
+ }
+
+ StatusIconPrefsListener(GtkStatusIcon * i, Queue& q) : icon(i), queue(q),
+ tasks_active(0), tasks_total(0), is_online(false)
+ {
+ update_status_tooltip();
+ status_icon_timeout_tag = g_timeout_add (250, status_icon_periodic_refresh, this);
+ }
+
+ ~StatusIconPrefsListener()
+ {
+ g_source_remove (status_icon_timeout_tag);
+ }
+
+ void on_prefs_flag_changed (const StringView &key, bool value)
+ {
+ if(key == "status-icon")
+ gtk_status_icon_set_visible(icon, value);
+ }
+ virtual void on_prefs_int_changed (const StringView& key, int color) {}
+ virtual void on_prefs_string_changed (const StringView& key, const StringView& value) {}
+ virtual void on_prefs_color_changed (const StringView& key, const GdkColor& color) {}
+
+ void update_status_tooltip()
+ {
+ char buf[512];
+ g_snprintf(buf,sizeof(buf), "<i>Pan %s : %s</i> \n"
+ "<b>Tasks running:</b> %d\n"
+ "<b>Total queued:</b> %d\n"
+ "<b>Speed:</b> %.1f KiBps\n",
+ PACKAGE_VERSION, is_online ? "online" : "offline",
+ tasks_active, tasks_total, queue.get_speed_KiBps());
+ gtk_status_icon_set_tooltip_markup(icon, buf);
+ }
+
+ virtual void on_queue_task_active_changed (Queue&, Task&, bool active)
+ {
+ if (active) ++tasks_active; else --tasks_active; update_status_tooltip();
+ }
+ virtual void on_queue_tasks_added (Queue&, int index UNUSED, int count)
+ {
+ tasks_total += count; update_status_tooltip();
+ }
+ virtual void on_queue_task_removed (Queue&, Task&, int pos UNUSED)
+ {
+ --tasks_total;
+ }
+ virtual void on_queue_task_moved (Queue&, Task&, int new_pos UNUSED, int old_pos UNUSED) {}
+ virtual void on_queue_connection_count_changed (Queue&, int count) {}
+ virtual void on_queue_size_changed (Queue&, int active, int total)
+ {
+ tasks_total = total;
+ tasks_active = active;
+ update_status_tooltip();
+ }
+ virtual void on_queue_online_changed (Queue&, bool online)
+ {
+ is_online = online; update_status_tooltip();
+ }
+ virtual void on_queue_error (Queue&, const StringView& message) {}
+
+ private:
+ GtkStatusIcon *icon;
+ Queue& queue;
+ int tasks_active;
+ int tasks_total;
+ bool is_online;
+ guint status_icon_timeout_tag;
+ };
+
+ StatusIconPrefsListener* _status_icon;
+
+ void status_icon_activate (GtkStatusIcon *icon, gpointer data)
+ {
+ GtkWindow * window = GTK_WINDOW(data);
+ if(gtk_window_is_active (window))
+ gtk_widget_hide ((GtkWidget *) window);
+ else {
+// gtk_widget_hide ((GtkWidget *) window); // dirty hack
+ gtk_widget_show ((GtkWidget *) window);
+ }
+ }
+
+ void status_icon_popup_menu (GtkStatusIcon *icon,
+ guint button,
+ guint activation_time,
+ gpointer data)
+ {
+ GtkMenu * menu = GTK_MENU(data);
+ gtk_menu_popup(menu, NULL, NULL, NULL, NULL, button, activation_time);
+ }
+
+ void run_pan_with_status_icon (GtkWindow * window, GdkPixbuf * pixbuf, Queue& queue, Prefs & prefs)
+ {
+ GtkStatusIcon * icon = gtk_status_icon_new_from_pixbuf (pixbuf);
+ GtkWidget * menu = gtk_menu_new ();
+ GtkWidget * menu_quit = gtk_image_menu_item_new_from_stock ( GTK_STOCK_QUIT, NULL);
+ gtk_status_icon_set_visible(icon, prefs.get_flag("status-icon", true));
+ StatusIconPrefsListener* pl = _status_icon = new StatusIconPrefsListener(icon, queue);
+ prefs.add_listener(pl); //todo remove listener on exit
+ queue.add_listener(pl);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_quit);
+ gtk_widget_show_all(menu);
+ g_signal_connect(icon, "activate", G_CALLBACK(status_icon_activate), window);
+ g_signal_connect(icon, "popup-menu", G_CALLBACK(status_icon_popup_menu), menu);
+ g_signal_connect(menu_quit, "activate", G_CALLBACK(mainloop_quit), NULL);
+ }
+
+
void run_pan_in_window (Data & data,
Queue & queue,
Prefs & prefs,
@@ -146,7 +268,7 @@ namespace
GtkWindow * window)
{
{
- const gulong delete_cb_id = g_signal_connect (window, "delete-event", G_CALLBACK(delete_event_cb), 0);
+ const gulong delete_cb_id = g_signal_connect (window, "delete-event", G_CALLBACK(delete_event_cb), &prefs);
GUI gui (data, queue, prefs, group_prefs);
gtk_container_add (GTK_CONTAINER(window), gui.root());
@@ -410,10 +532,14 @@ main (int argc, char *argv[])
gtk_window_set_title (GTK_WINDOW(window), "Pan");
gtk_window_set_resizable (GTK_WINDOW(window), true);
gtk_window_set_default_icon (pixbuf);
+ run_pan_with_status_icon(GTK_WINDOW(window), pixbuf, queue, prefs);
g_object_unref (pixbuf);
run_pan_in_window (data, queue, prefs, group_prefs, GTK_WINDOW(window));
}
+ prefs.remove_listener(_status_icon);
+ queue.remove_listener(_status_icon);
+
worker_pool.cancel_all_silently ();
if (prefs.get_flag("clear-article-cache-on-shutdown", false)) {
diff --git a/pan/gui/prefs-ui.cc b/pan/gui/prefs-ui.cc
index cdd7f68..acb78c2 100644
--- a/pan/gui/prefs-ui.cc
+++ b/pan/gui/prefs-ui.cc
@@ -541,6 +541,10 @@ PrefsDialog :: PrefsDialog (Prefs& prefs, GtkWindow* parent):
gtk_misc_set_alignment (GTK_MISC(l), 0.0, 0.5);
gtk_label_set_mnemonic_widget(GTK_LABEL(l), w);
HIG::workarea_add_row (t, &row, w, l);
+ HIG :: workarea_add_section_title (t, &row, _("Status Icon"));
+ HIG :: workarea_add_section_spacer (t, row, 3);
+ w = new_check_button (_("Hide window to system tray instead of closing it"), "status-icon", true, prefs);
+ HIG :: workarea_add_wide_control (t, &row, w);
HIG :: workarea_finish (t, &row);
gtk_notebook_append_page (GTK_NOTEBOOK(notebook), t, gtk_label_new_with_mnemonic(_("_Behavior")));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]