[Pkg-mozext-commits] [firetray] 35/399: * rewrite LibGtkStatusIcon.jsm with XPCOMUtils (will need to watch for xpcom-shutdown for closing libs !) * icon handling moved to MoztIconLinux.jsm * tray icon changes (icon+tooltip) according to unreadMsgCount * strings (localization) provided by commons.js
David Prévot
taffit at alioth.debian.org
Tue Oct 29 18:23:09 UTC 2013
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to branch dfsg-clean
in repository firetray.
commit 25644e0a88cc4ed1e83a8b4f1ee5f6d0cf968a81
Author: foudfou <foudil.newbie+git at gmail.com>
Date: Wed Sep 7 23:50:18 2011 +0200
* rewrite LibGtkStatusIcon.jsm with XPCOMUtils (will need to watch for
xpcom-shutdown for closing libs !)
* icon handling moved to MoztIconLinux.jsm
* tray icon changes (icon+tooltip) according to unreadMsgCount
* strings (localization) provided by commons.js
---
TODO | 2 -
src/chrome/locale/en-US/overlay.properties | 1 +
src/chrome/skin/message-mail-new.png | Bin 0 -> 770 bytes
src/modules/LibGtkStatusIcon.jsm | 350 +++++++++++++++++-----------
src/modules/MoztHandler.jsm | 78 +------
src/modules/MoztIconLinux.jsm | 123 ++++++++++
src/modules/MoztMessaging.jsm | 17 +-
src/modules/commons.js | 4 +-
8 files changed, 360 insertions(+), 215 deletions(-)
diff --git a/TODO b/TODO
index 3b38c85..c56d9d0 100644
--- a/TODO
+++ b/TODO
@@ -1,5 +1,3 @@
-* change tray icon according to unreadMsgCount
-
* make multi-platform. At least have js-ctypes library call dependant on OS detection. (best would be to have the OS-dependant modules loaded at startup)
* convert to a https://developer.mozilla.org/en/Extensions/Bootstrapped_extensions
diff --git a/src/chrome/locale/en-US/overlay.properties b/src/chrome/locale/en-US/overlay.properties
index 2d4f601..81bd21d 100644
--- a/src/chrome/locale/en-US/overlay.properties
+++ b/src/chrome/locale/en-US/overlay.properties
@@ -1,2 +1,3 @@
extensions.moztray at foudil.fr.description=A system tray extension for linux.
popupMenu.itemLabel.Quit=Quit
+icon.tooltip.unread_messages=#1 unread message;#1 unread messages
diff --git a/src/chrome/skin/message-mail-new.png b/src/chrome/skin/message-mail-new.png
new file mode 100644
index 0000000..3691cb7
Binary files /dev/null and b/src/chrome/skin/message-mail-new.png differ
diff --git a/src/modules/LibGtkStatusIcon.jsm b/src/modules/LibGtkStatusIcon.jsm
index 02342d6..0da7157 100644
--- a/src/modules/LibGtkStatusIcon.jsm
+++ b/src/modules/LibGtkStatusIcon.jsm
@@ -2,145 +2,225 @@
var EXPORTED_SYMBOLS = ["LibGtkStatusIcon"];
+const LIB_GTK = "libgtk-x11-2.0.so.0";
+
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
-const LIB_GTK = "libgtk-x11-2.0.so.0";
-
-var LibGtkStatusIcon = {
-
- _lib: null,
-
- init: function() {
- // If ctypes doesn't exist, try to get it
- Cu.import("resource://gre/modules/ctypes.jsm");
- // If we still don't have ctypes, this isn't going to work...
- if (typeof(ctypes) == "undefined") {
- throw ("Could not load JS-Ctypes");
- }
-
- Cu.import("resource://moztray/LibGObject.jsm");
- Cu.import("resource://moztray/LibGdkWindow.jsm");
-
- try {
- // Try to start up dependencies - if they fail, they'll throw
- // exceptions. ex: LibGObject.init();
-
- this._lib = ctypes.open(LIB_GTK);
- if (!this._lib)
- throw ("Could not load " + LIB_GTK);
-
- } catch (e) {
- this.shutdown();
- throw(e);
- }
-
- // Ok, we got everything - let's declare.
- this._declare();
- },
-
- shutdown: function() {
- // Close our connection to the library.
- if (this._lib)
- this._lib.close();
- },
-
- _declare: function() {
- // Types
-
- this.GtkStatusIcon = ctypes.StructType("GtkStatusIcon");
-
- this.GtkStyle = ctypes.StructType("GtkStyle");
- this.GtkRequisition = ctypes.StructType(
- "GtkRequisition", [
- { width: LibGObject.gint },
- { height: LibGObject.gint }
- ]);
- this.GtkAllocation = ctypes.StructType(
- "GtkAllocation", [
- { x: LibGObject.gint },
- { y: LibGObject.gint },
- { width: LibGObject.gint },
- { height: LibGObject.gint }
- ]);
-
- /* NOTE: recursive struct needs define() and included structs MUST be
- * defined ! */
- this.GtkWidget = ctypes.StructType("GtkWidget");
- this.GtkWidget.define([
- { "style": this.GtkStyle.ptr },
- { "requisition": this.GtkRequisition },
- { "allocation": this.GtkAllocation },
- { "window": LibGdkWindow.GdkWindow.ptr },
- { "parent": this.GtkWidget.ptr }
- ]);
-
- this.GtkMenu = ctypes.StructType("GtkMenu");
- this.GtkMenuShell = ctypes.StructType("GtkMenuShell");
- // use ctypes.cast(menu, LibGtkStatusIcon.GtkMenuShell.ptr);
- this.GtkImageMenuItem = ctypes.StructType("GtkImageMenuItem");
-
- this.GtkMenuPositionFunc = ctypes.FunctionType(
- ctypes.default_abi, ctypes.void_t,
- [this.GtkMenu.ptr, LibGObject.gint.ptr, LibGObject.gint.ptr,
- LibGObject.gboolean.ptr, LibGObject.gpointer]).ptr;
-
- this.GCallbackMenuPopup_t = ctypes.FunctionType(
- ctypes.default_abi, ctypes.void_t,
- [this.GtkStatusIcon.ptr, LibGObject.guint, LibGObject.guint,
- LibGObject.gpointer]).ptr;
-
- // Consts
- this.GTK_ICON_SIZE_MENU = 1;
-
- // Functions
-
- this.gtk_status_icon_new = this._lib.declare(
- "gtk_status_icon_new", ctypes.default_abi, this.GtkStatusIcon.ptr);
-
- this.gtk_status_icon_set_from_file = this._lib.declare(
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/ctypes.jsm");
+Cu.import("resource://moztray/LibGObject.jsm");
+Cu.import("resource://moztray/LibGdkWindow.jsm");
+
+
+XPCOMUtils.defineLazyGetter(this, "libgtk", function() {
+ var libgtk = ctypes.open(LIB_GTK);
+ if (!libgtk)
+ throw "libgtk is unavailable";
+ return libgtk;
+});
+
+
+// Structures
+
+XPCOMUtils.defineLazyGetter(this, "GCallback", function() {
+ return ctypes.void_t.ptr;
+});
+
+XPCOMUtils.defineLazyGetter(this, "GtkStatusIcon", function() {
+ return ctypes.StructType("GtkStatusIcon");
+});
+
+XPCOMUtils.defineLazyGetter(this, "GtkStyle", function() {
+ return ctypes.StructType("GtkStyle");
+});
+
+XPCOMUtils.defineLazyGetter(this, "GtkRequisition", function() {
+ return ctypes.StructType(
+ "GtkRequisition", [
+ { width: LibGObject.gint },
+ { height: LibGObject.gint }
+ ]);
+});
+
+XPCOMUtils.defineLazyGetter(this, "GtkAllocation", function() {
+ return ctypes.StructType(
+ "GtkAllocation", [
+ { x: LibGObject.gint },
+ { y: LibGObject.gint },
+ { width: LibGObject.gint },
+ { height: LibGObject.gint }
+ ]);
+});
+
+/* NOTE: recursive struct needs define() and included structs MUST be
+ * defined ! */
+XPCOMUtils.defineLazyGetter(this, "GtkWidget", function() {
+ var GtkWidget = ctypes.StructType("GtkWidget");
+ GtkWidget.define([
+ { "style": GtkStyle.ptr },
+ { "requisition": GtkRequisition },
+ { "allocation": GtkAllocation },
+ { "window": LibGdkWindow.GdkWindow.ptr },
+ { "parent": GtkWidget.ptr }
+ ]);
+ return GtkWidget;
+});
+
+XPCOMUtils.defineLazyGetter(this, "GtkMenu", function() {
+ return ctypes.StructType("GtkMenu");
+});
+
+// use ctypes.cast(menu, LibGtkStatusIcon.GtkMenuShell.ptr);
+XPCOMUtils.defineLazyGetter(this, "GtkMenuShell", function() {
+ return ctypes.StructType("GtkMenuShell");
+});
+
+XPCOMUtils.defineLazyGetter(this, "GtkImageMenuItem", function() {
+ return ctypes.StructType("GtkImageMenuItem");
+});
+
+XPCOMUtils.defineLazyGetter(this, "GtkMenuPositionFunc", function() {
+ return ctypes.FunctionType(
+ ctypes.default_abi, ctypes.void_t,
+ [GtkMenu.ptr, LibGObject.gint.ptr, LibGObject.gint.ptr,
+ LibGObject.gboolean.ptr, LibGObject.gpointer]).ptr;
+});
+
+XPCOMUtils.defineLazyGetter(this, "GCallbackMenuPopup_t", function() {
+ return ctypes.FunctionType(
+ ctypes.default_abi, ctypes.void_t,
+ [GtkStatusIcon.ptr, LibGObject.guint, LibGObject.guint,
+ LibGObject.gpointer]).ptr;
+});
+
+
+// Functions
+
+XPCOMUtils.defineLazyGetter(this, "gtk_status_icon_new", function() {
+ var gtk_status_icon_new = libgtk.declare(
+ "gtk_status_icon_new", ctypes.default_abi, GtkStatusIcon.ptr);
+ if (!gtk_status_icon_new)
+ throw "gtk_status_icon_new is unavailable";
+ return gtk_status_icon_new;
+});
+
+XPCOMUtils.defineLazyGetter(this, "gtk_status_icon_set_from_file", function() {
+ var gtk_status_icon_set_from_file = libgtk.declare(
"gtk_status_icon_set_from_file", ctypes.default_abi, ctypes.void_t,
- this.GtkStatusIcon.ptr, ctypes.char.ptr);
-
- this.gtk_status_icon_set_tooltip_text = this._lib.declare(
- "gtk_status_icon_set_tooltip_text", ctypes.default_abi, ctypes.void_t,
- this.GtkStatusIcon.ptr, ctypes.char.ptr);
-
- this.gtk_menu_new = this._lib.declare(
- "gtk_menu_new", ctypes.default_abi, this.GtkMenu.ptr);
-
- this.gtk_image_menu_item_new_with_label = this._lib.declare(
- "gtk_image_menu_item_new_with_label", ctypes.default_abi, this.GtkImageMenuItem.ptr,
- LibGObject.gchar.ptr);
-
- this.gtk_image_new_from_stock = this._lib.declare(
- "gtk_image_new_from_stock", ctypes.default_abi, this.GtkWidget.ptr,
- LibGObject.gchar.ptr, ctypes.int); // enum
-
- this.gtk_image_menu_item_set_image = this._lib.declare(
- "gtk_image_menu_item_set_image", ctypes.default_abi, ctypes.void_t,
- this.GtkImageMenuItem.ptr, this.GtkWidget.ptr);
-
- this.gtk_menu_shell_append = this._lib.declare(
- "gtk_menu_shell_append", ctypes.default_abi, ctypes.void_t,
- this.GtkMenuShell.ptr, this.GtkImageMenuItem.ptr);
-
- this.gtk_widget_show_all = this._lib.declare(
- "gtk_widget_show_all", ctypes.default_abi, ctypes.void_t,
- this.GtkWidget.ptr);
-
- this.gtk_menu_popup = this._lib.declare(
- "gtk_menu_popup", ctypes.default_abi, ctypes.void_t,
- this.GtkMenu.ptr, this.GtkWidget.ptr, this.GtkWidget.ptr,
- this.GtkMenuPositionFunc, LibGObject.gpointer, LibGObject.guint,
- LibGObject.guint);
-
- this.gtk_status_icon_position_menu = this._lib.declare(
- "gtk_status_icon_position_menu", ctypes.default_abi, ctypes.void_t,
- this.GtkMenu.ptr, LibGObject.gint.ptr, LibGObject.gint.ptr,
- LibGObject.gboolean.ptr, LibGObject.gpointer);
-
- }
+ GtkStatusIcon.ptr, ctypes.char.ptr);
+ if (!gtk_status_icon_set_from_file)
+ throw "gtk_status_icon_set_from_file is unavailable";
+ return gtk_status_icon_set_from_file;
+});
+
+XPCOMUtils.defineLazyGetter(this, "gtk_status_icon_set_tooltip_text", function() {
+ var gtk_status_icon_set_tooltip_text = libgtk.declare(
+ "gtk_status_icon_set_tooltip_text", ctypes.default_abi, ctypes.void_t,
+ GtkStatusIcon.ptr, ctypes.char.ptr);
+ if (!gtk_status_icon_set_tooltip_text)
+ throw "gtk_status_icon_set_tooltip_text unavailable";
+ return gtk_status_icon_set_tooltip_text;
+});
+
+XPCOMUtils.defineLazyGetter(this, "gtk_menu_new", function() {
+ var gtk_menu_new = libgtk.declare(
+ "gtk_menu_new", ctypes.default_abi, GtkMenu.ptr);
+ if (!gtk_menu_new)
+ throw "gtk_menu_new is unavailable";
+ return gtk_menu_new;
+});
+
+XPCOMUtils.defineLazyGetter(this, "gtk_image_menu_item_new_with_label", function() {
+ var gtk_image_menu_item_new_with_label = libgtk.declare(
+ "gtk_image_menu_item_new_with_label", ctypes.default_abi, GtkImageMenuItem.ptr,
+ LibGObject.gchar.ptr);
+ if (!gtk_image_menu_item_new_with_label)
+ throw "gtk_image_menu_item_new_with_label is unavailable";
+ return gtk_image_menu_item_new_with_label;
+});
+
+XPCOMUtils.defineLazyGetter(this, "gtk_image_new_from_stock", function() {
+ var gtk_image_new_from_stock = libgtk.declare(
+ "gtk_image_new_from_stock", ctypes.default_abi, GtkWidget.ptr,
+ LibGObject.gchar.ptr, ctypes.int); // enum
+ if (!gtk_image_new_from_stock)
+ throw "gtk_image_new_from_stock is unavailable";
+ return gtk_image_new_from_stock;
+});
+
+XPCOMUtils.defineLazyGetter(this, "gtk_image_menu_item_set_image", function() {
+ var gtk_image_menu_item_set_image = libgtk.declare(
+ "gtk_image_menu_item_set_image", ctypes.default_abi, ctypes.void_t,
+ GtkImageMenuItem.ptr, GtkWidget.ptr);
+ if (!gtk_image_menu_item_set_image)
+ throw "gtk_image_menu_item_set_image is unavailable";
+ return gtk_image_menu_item_set_image;
+});
+
+XPCOMUtils.defineLazyGetter(this, "gtk_menu_shell_append", function() {
+ var gtk_menu_shell_append = libgtk.declare(
+ "gtk_menu_shell_append", ctypes.default_abi, ctypes.void_t,
+ GtkMenuShell.ptr, GtkImageMenuItem.ptr);
+ if (!gtk_menu_shell_append)
+ throw "gtk_menu_shell_append is unavailable";
+ return gtk_menu_shell_append;
+});
+
+XPCOMUtils.defineLazyGetter(this, "gtk_widget_show_all", function() {
+ var gtk_widget_show_all = libgtk.declare(
+ "gtk_widget_show_all", ctypes.default_abi, ctypes.void_t,
+ GtkWidget.ptr);
+ if (!gtk_widget_show_all)
+ throw "gtk_widget_show_all is unavailable";
+ return gtk_widget_show_all;
+});
+
+XPCOMUtils.defineLazyGetter(this, "gtk_menu_popup", function() {
+ var gtk_menu_popup = libgtk.declare(
+ "gtk_menu_popup", ctypes.default_abi, ctypes.void_t,
+ GtkMenu.ptr, GtkWidget.ptr, GtkWidget.ptr,
+ GtkMenuPositionFunc, LibGObject.gpointer, LibGObject.guint,
+ LibGObject.guint);
+ if (!gtk_menu_popup)
+ throw "gtk_menu_popup is unavailable is unavailable";
+ return gtk_menu_popup;
+});
+
+XPCOMUtils.defineLazyGetter(this, "gtk_status_icon_position_menu", function() {
+ var gtk_status_icon_position_menu = libgtk.declare(
+ "gtk_status_icon_position_menu", ctypes.default_abi, ctypes.void_t,
+ GtkMenu.ptr, LibGObject.gint.ptr, LibGObject.gint.ptr,
+ LibGObject.gboolean.ptr, LibGObject.gpointer);
+ if (!gtk_status_icon_position_menu)
+ throw "gtk_status_icon_position_menu is unavailable";
+ return gtk_status_icon_position_menu;
+});
+var LibGtkStatusIcon = {
+ GTK_ICON_SIZE_MENU: 1,
+ libgtk: libgtk,
+ GCallback: GCallback,
+ GtkStatusIcon: GtkStatusIcon,
+ GtkStyle: GtkStyle,
+ GtkRequisition: GtkRequisition,
+ GtkAllocation: GtkAllocation,
+ GtkWidget: GtkWidget,
+ GtkMenu: GtkMenu,
+ GtkMenuShell: GtkMenuShell,
+ GtkImageMenuItem: GtkImageMenuItem,
+ GtkMenuPositionFunc: GtkMenuPositionFunc,
+ GCallbackMenuPopup_t: GCallbackMenuPopup_t,
+ gtk_status_icon_new: gtk_status_icon_new,
+ gtk_status_icon_set_from_file: gtk_status_icon_set_from_file,
+ gtk_status_icon_set_tooltip_text: gtk_status_icon_set_tooltip_text,
+ gtk_menu_new: gtk_menu_new,
+ gtk_image_menu_item_new_with_label: gtk_image_menu_item_new_with_label,
+ gtk_image_new_from_stock: gtk_image_new_from_stock,
+ gtk_image_menu_item_set_image: gtk_image_menu_item_set_image,
+ gtk_menu_shell_append: gtk_menu_shell_append,
+ gtk_widget_show_all: gtk_widget_show_all,
+ gtk_menu_popup: gtk_menu_popup,
+ gtk_status_icon_position_menu: gtk_status_icon_position_menu
};
diff --git a/src/modules/MoztHandler.jsm b/src/modules/MoztHandler.jsm
index 1c9a28c..3d1fce6 100644
--- a/src/modules/MoztHandler.jsm
+++ b/src/modules/MoztHandler.jsm
@@ -12,9 +12,6 @@ Cu.import("resource://moztray/LibGObject.jsm");
Cu.import("resource://moztray/LibGtkStatusIcon.jsm");
Cu.import("resource://moztray/commons.js");
-const MOZT_ICON_DIR = "chrome/skin/";
-const MOZT_ICON_SUFFIX = "32.png";
-
/**
* mozt namespace.
*/
@@ -22,12 +19,6 @@ if ("undefined" == typeof(mozt)) {
var mozt = {};
};
-// pointers to JS functions. should *not* be eaten by GC ("Running global
-// cleanup code from study base classes" ?)
-var mozt_iconActivateCb;
-var mozt_popupMenuCb;
-var mozt_menuItemQuitActivateCb;
-
/**
* Singleton object for tray icon management
*/
@@ -37,9 +28,6 @@ var mozt_menuItemQuitActivateCb;
// (https://developer.mozilla.org/en/XUL_School/JavaScript_Object_Management)
mozt.Handler = {
initialized: false,
- strings: null,
- tryIcon: null,
- menu: null,
_windowsHidden: false,
_handledDOMWindows: [],
@@ -156,13 +144,11 @@ mozt.Handler = {
LOG("ARGS="+icon+", "+button+", "+activateTime+", "+menu);
try {
- LibGtkStatusIcon.init(); // before anything !!!
var gtkMenuPtr = ctypes.cast(menu, LibGtkStatusIcon.GtkMenu.ptr);
var iconGpointer = ctypes.cast(icon, LibGObject.gpointer);
LibGtkStatusIcon.gtk_menu_popup(
gtkMenuPtr, null, null, LibGtkStatusIcon.gtk_status_icon_position_menu,
iconGpointer, button, activateTime);
- LibGtkStatusIcon.shutdown();
} catch (x) {
LOG(x);
}
@@ -181,10 +167,6 @@ mozt.Handler = {
init: function() { // creates icon
- // initialize l10n
- this.strings = Services.strings
- .createBundle("chrome://moztray/locale/overlay.properties");
-
// platform checks
let runtimeOS = Services.appinfo.OS; // "WINNT", "Linux", "Darwin"
// version checked during install, so we shouldn't need to care
@@ -193,68 +175,14 @@ mozt.Handler = {
if (runtimeOS != "Linux") {
Components.utils.reportError("MOZTRAY: only Linux platform supported at this time. Moztray not loaded");
return false;
- // Cu.import("resource://moztray/MoztHandler-Linux.jsm");
}
+ Cu.import("resource://moztray/MoztIconLinux.jsm");
// init all handled windows
this._updateHandledDOMWindows();
- try {
-
- // instanciate tray icon
- LibGtkStatusIcon.init();
- this.trayIcon = LibGtkStatusIcon.gtk_status_icon_new();
- let mozApp = Services.appinfo.name.toLowerCase();
- let iconFilename = MOZT_ICON_DIR + mozApp + MOZT_ICON_SUFFIX;
- LibGtkStatusIcon.gtk_status_icon_set_from_file(this.trayIcon,
- iconFilename);
-
- // build icon popup menu
- this.menu = LibGtkStatusIcon.gtk_menu_new();
- // shouldn't need to convert to utf8 thank to js-ctypes
- var menuItemQuitLabel = this.strings.GetStringFromName("popupMenu.itemLabel.Quit");
- var menuItemQuit = LibGtkStatusIcon.gtk_image_menu_item_new_with_label(
- menuItemQuitLabel);
- var menuItemQuitIcon = LibGtkStatusIcon.gtk_image_new_from_stock(
- "gtk-quit", LibGtkStatusIcon.GTK_ICON_SIZE_MENU);
- LibGtkStatusIcon.gtk_image_menu_item_set_image(menuItemQuit, menuItemQuitIcon);
- var menuShell = ctypes.cast(this.menu, LibGtkStatusIcon.GtkMenuShell.ptr);
- LibGtkStatusIcon.gtk_menu_shell_append(menuShell, menuItemQuit);
-
- mozt_menuItemQuitActivateCb = LibGObject.GCallback_t(
- function(){mozt.Handler.quitApplication();});
- LibGObject.g_signal_connect(menuItemQuit, "activate",
- mozt_menuItemQuitActivateCb, null);
-
- var menuWidget = ctypes.cast(this.menu, LibGtkStatusIcon.GtkWidget.ptr);
- LibGtkStatusIcon.gtk_widget_show_all(menuWidget);
-
- // here we do use a function handler because we need the args passed to
- // it ! But we need to abandon 'this' in popupMenu()
- mozt_popupMenuCb =
- LibGtkStatusIcon.GCallbackMenuPopup_t(mozt.Handler.popupMenu);
- LibGObject.g_signal_connect(this.trayIcon, "popup-menu",
- mozt_popupMenuCb, this.menu);
-
- // set tooltip. bugs on hover:
- // Gdk-CRITICAL **: IA__gdk_window_get_root_coords: assertion `GDK_IS_WINDOW (window)' failed
- LibGtkStatusIcon.gtk_status_icon_set_tooltip_text(this.trayIcon,
- mozApp);
-
- // close lib
- LibGtkStatusIcon.shutdown();
-
- // watch out for binding problems ! here we prefer to keep 'this' in
- // showHideToTray() and abandon the args.
- mozt_iconActivateCb = LibGObject.GCallback_t(
- function(){mozt.Handler.showHideToTray();});
- LibGObject.g_signal_connect(this.trayIcon, "activate",
- mozt_iconActivateCb, null);
-
- } catch (x) {
- Components.utils.reportError(x);
- return false;
- }
+ // instanciate tray icon
+ mozt.IconLinux.init();
// check if in mail app
var mozAppId = Services.appinfo.ID;
diff --git a/src/modules/MoztIconLinux.jsm b/src/modules/MoztIconLinux.jsm
new file mode 100644
index 0000000..fba42df
--- /dev/null
+++ b/src/modules/MoztIconLinux.jsm
@@ -0,0 +1,123 @@
+/* -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+var EXPORTED_SYMBOLS = [ "mozt" ];
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/ctypes.jsm");
+Cu.import("resource://moztray/LibGObject.jsm");
+Cu.import("resource://moztray/LibGtkStatusIcon.jsm");
+Cu.import("resource://moztray/commons.js");
+
+if ("undefined" == typeof(mozt.Handler))
+ ERROR("MoztIcon*.jsm MUST be imported from/after MoztHandler !");
+
+// pointers to JS functions. should *not* be eaten by GC ("Running global
+// cleanup code from study base classes" ?)
+var mozt_iconActivateCb;
+var mozt_popupMenuCb;
+var mozt_menuItemQuitActivateCb;
+
+mozt.IconLinux = {
+ tryIcon: null,
+ menu: null,
+ appName: null,
+ ICON_FILENAME_DEFAULT: null,
+ ICON_DIR: "chrome/skin/", // FIXME: retrieve from chromeregistery
+ ICON_SUFFIX: "32.png",
+
+ init: function() {
+
+ try {
+
+ // init tray icon, some variables
+ this.trayIcon = LibGtkStatusIcon.gtk_status_icon_new();
+ this.appName = Services.appinfo.name.toLowerCase();
+ this.ICON_FILENAME_DEFAULT = this.ICON_DIR + this.appName + this.ICON_SUFFIX;
+
+ this.setDefaultImage();
+
+ // build icon popup menu
+ this.menu = LibGtkStatusIcon.gtk_menu_new();
+ // shouldn't need to convert to utf8 thank to js-ctypes
+ var menuItemQuitLabel = mozt.Utils.strings.GetStringFromName("popupMenu.itemLabel.Quit");
+ var menuItemQuit = LibGtkStatusIcon.gtk_image_menu_item_new_with_label(
+ menuItemQuitLabel);
+ var menuItemQuitIcon = LibGtkStatusIcon.gtk_image_new_from_stock(
+ "gtk-quit", LibGtkStatusIcon.GTK_ICON_SIZE_MENU);
+ LibGtkStatusIcon.gtk_image_menu_item_set_image(menuItemQuit, menuItemQuitIcon);
+ var menuShell = ctypes.cast(this.menu, LibGtkStatusIcon.GtkMenuShell.ptr);
+ LibGtkStatusIcon.gtk_menu_shell_append(menuShell, menuItemQuit);
+
+ mozt_menuItemQuitActivateCb = LibGObject.GCallback_t(
+ function(){mozt.Handler.quitApplication();});
+ LibGObject.g_signal_connect(menuItemQuit, "activate",
+ mozt_menuItemQuitActivateCb, null);
+
+ var menuWidget = ctypes.cast(this.menu, LibGtkStatusIcon.GtkWidget.ptr);
+ LibGtkStatusIcon.gtk_widget_show_all(menuWidget);
+
+ // here we do use a function handler because we need the args passed to
+ // it ! But we need to abandon 'this' in popupMenu()
+ mozt_popupMenuCb =
+ LibGtkStatusIcon.GCallbackMenuPopup_t(mozt.Handler.popupMenu);
+ LibGObject.g_signal_connect(this.trayIcon, "popup-menu",
+ mozt_popupMenuCb, this.menu);
+
+ this.setDefaultTooltip();
+
+ // watch out for binding problems ! here we prefer to keep 'this' in
+ // showHideToTray() and abandon the args.
+ mozt_iconActivateCb = LibGObject.GCallback_t(
+ function(){mozt.Handler.showHideToTray();});
+ LibGObject.g_signal_connect(this.trayIcon, "activate",
+ mozt_iconActivateCb, null);
+
+ } catch (x) {
+ Components.utils.reportError(x);
+ return false;
+ }
+
+ return true;
+ },
+
+ setImage: function(filename) {
+ if (!this.trayIcon)
+ return false;
+
+ try {
+ LibGtkStatusIcon.gtk_status_icon_set_from_file(this.trayIcon,
+ filename);
+ } catch (x) {
+ ERROR(x);
+ return false;
+ }
+ return true;
+ },
+
+ setDefaultImage: function() {
+ if (!this.ICON_FILENAME_DEFAULT)
+ throw "Default application icon filename not set";
+ LOG(this.ICON_FILENAME_DEFAULT);
+ this.setImage(this.ICON_FILENAME_DEFAULT);
+ },
+
+ // GTK bug: Gdk-CRITICAL **: IA__gdk_window_get_root_coords: assertion `GDK_IS_WINDOW (window)' failed
+ setTooltip: function(toolTipStr) {
+ if (!this.trayIcon)
+ return false;
+ LibGtkStatusIcon.gtk_status_icon_set_tooltip_text(this.trayIcon,
+ toolTipStr);
+ return true;
+ },
+
+ setDefaultTooltip: function() {
+ if (!this.appName)
+ throw "application name not initialized";
+ this.setTooltip(this.appName);
+ }
+
+}; // mozt.IconLinux
diff --git a/src/modules/MoztMessaging.jsm b/src/modules/MoztMessaging.jsm
index 6318126..e290e09 100644
--- a/src/modules/MoztMessaging.jsm
+++ b/src/modules/MoztMessaging.jsm
@@ -7,6 +7,8 @@ const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource:///modules/mailServices.js");
+Cu.import("resource://gre/modules/PluralForm.jsm");
+Cu.import("resource://moztray/MoztIconLinux.jsm");
Cu.import("resource://moztray/commons.js");
const FLDR_UNINTERESTING =
@@ -61,8 +63,6 @@ mozt.Messaging = {
*/
// TODO: check count correctly updated if folder/account creation/deletion
OnItemIntPropertyChanged: function(folder, property, oldValue, newValue) {
- LOG("OnItemIntPropertyChanged fired with property: "+property);
-
if (property.toString() === "TotalUnreadMessages" &&
!(folder.flags & FLDR_UNINTERESTING)) {
LOG("Unread msgs for folder "+folder.prettyName+" was "+oldValue+" became "+newValue);
@@ -98,6 +98,19 @@ mozt.Messaging = {
ERROR(x);
}
LOG("TotalUnread="+this._unreadMsgCount);
+
+ // update icon
+ if (this._unreadMsgCount > 0) {
+ mozt.IconLinux.setImage(mozt.IconLinux.ICON_DIR + "message-mail-new.png");
+ let localizedMessage = PluralForm.get(
+ this._unreadMsgCount, mozt.Utils.strings.GetStringFromName("icon.tooltip.unread_messages"))
+ .replace("#1", this._unreadMsgCount);;
+ mozt.IconLinux.setTooltip(localizedMessage);
+ }
+ else {
+ mozt.IconLinux.setDefaultImage();
+ mozt.IconLinux.setDefaultTooltip();
+ }
}
};
diff --git a/src/modules/commons.js b/src/modules/commons.js
index 9f31578..0ff85c8 100644
--- a/src/modules/commons.js
+++ b/src/modules/commons.js
@@ -33,6 +33,8 @@ if ("undefined" == typeof(mozt)) {
});
}, this);
+
mozt.Utils = {
- prefService: Services.prefs.getBranch("extensions.moztray.")
+ prefService: Services.prefs.getBranch("extensions.moztray."),
+ strings: Services.strings.createBundle("chrome://moztray/locale/overlay.properties")
};
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/firetray.git
More information about the Pkg-mozext-commits
mailing list