[Pkg-mozext-commits] [firetray] 149/399: * extract FiretrayPopupMenu.jsm from FiretrayStatusIcon.jsm * fix visibilityRate * fix: have only one prefListener * refactor PopupMenu functions * clean
David Prévot
taffit at alioth.debian.org
Tue Oct 29 18:23:31 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 eb8ce310f4049bcd2ce1fe3cd14f0558b7085bcc
Author: foudfou <foudil.newbie+git at gmail.com>
Date: Mon Jan 23 04:04:05 2012 +0100
* extract FiretrayPopupMenu.jsm from FiretrayStatusIcon.jsm
* fix visibilityRate
* fix: have only one prefListener
* refactor PopupMenu functions
* clean
---
src/chrome/content/overlay.js | 44 +-----
src/modules/FiretrayHandler.jsm | 21 +++
src/modules/FiretrayPrefListener.jsm | 50 +++++++
src/modules/gtk2/FiretrayPopupMenu.jsm | 221 +++++++++++++++++++++++++++++++
src/modules/gtk2/FiretrayStatusIcon.jsm | 209 +++--------------------------
src/modules/gtk2/FiretrayWindow.jsm | 62 ++++-----
6 files changed, 341 insertions(+), 266 deletions(-)
diff --git a/src/chrome/content/overlay.js b/src/chrome/content/overlay.js
index 934f86d..f93652e 100644
--- a/src/chrome/content/overlay.js
+++ b/src/chrome/content/overlay.js
@@ -8,20 +8,10 @@ if ("undefined" == typeof(Ci)) var Ci = Components.interfaces;
if ("undefined" == typeof(Cu)) var Cu = Components.utils;
// https://groups.google.com/group/mozilla.dev.extensions/browse_thread/thread/e89e9c2a834ff2b6#
-var firetrayChrome = {
+var firetrayChrome = { // each new window gets a new firetrayChrome !
onLoad: function(win) {
- // strings a chrome-specific
- this.strings = document.getElementById("firetray-strings");
-
- try {
- // Set up preference change observer
- firetray.Utils.prefService.QueryInterface(Ci.nsIPrefBranch2);
- firetray.Utils.prefService.addObserver("", firetrayChrome, false);
- } catch (x) {
- ERROR(x);
- return false;
- }
+ this.strings = document.getElementById("firetray-strings"); // chrome-specific
LOG("Handler initialized: "+firetray.Handler.initialized);
let init = firetray.Handler.initialized || firetray.Handler.init();
@@ -35,8 +25,6 @@ var firetrayChrome = {
// prevent window closing.
win.addEventListener('close', firetrayChrome.onClose, true);
- // NOTE: each new window gets a new firetrayChrome, and hence listens to
- // pref changes
if (!firetray.Handler.appStarted
&& firetray.Utils.prefService.getBoolPref('start_hidden')) {
@@ -51,13 +39,10 @@ var firetrayChrome = {
},
onQuit: function(win) {
- // Remove observer
- firetray.Utils.prefService.removeObserver("", firetrayChrome);
-
firetray.Handler.unregisterWindow(win);
- /* NOTE: don't firetray.Handler.initialized=false here, otherwise after a
- window close, a new window will create a new handler (and hence, a new
+ /* NOTE: don't do firetray.Handler.initialized=false here, otherwise after
+ a window close, a new window will create a new handler (and hence, a new
tray icon) */
LOG('Firetray UNLOADED !');
},
@@ -80,28 +65,7 @@ var firetrayChrome = {
firetray.Handler.hideAllWindows();
event && event.preventDefault(); // no event when called directly (xul)
}
- },
-
- // the chosen design is not to destroy/re-create existing objects, but
- // show/hide (Gtk objects) and apply/not (callbacks) them instead
- observe: function(subject, topic, data) {
- switch (topic) {
- case "nsPref:changed":
- LOG('Pref changed: '+data);
- switch (data) {
- case 'hides_single_window':
- firetray.Handler.updatePopupMenu();
- break;
- case 'show_icon_on_hide':
- firetray.Handler.showHideIcon();
- break;
- default:
- }
- break;
- default:
- }
}
-
};
// should be sufficient for a delayed Startup (no need for window.setTimeout())
diff --git a/src/modules/FiretrayHandler.jsm b/src/modules/FiretrayHandler.jsm
index dcafdc3..25aea8d 100644
--- a/src/modules/FiretrayHandler.jsm
+++ b/src/modules/FiretrayHandler.jsm
@@ -11,6 +11,7 @@ Cu.import("resource://gre/modules/ctypes.jsm");
Cu.import("resource://firetray/ctypes/gobject.jsm");
Cu.import("resource://firetray/ctypes/gtk.jsm");
Cu.import("resource://firetray/commons.js");
+Cu.import("resource://firetray/FiretrayPrefListener.jsm");
Cu.import("resource://firetray/FiretrayVersionChange.jsm");
/**
@@ -45,6 +46,8 @@ firetray.Handler = {
visibleWindowsCount: 0,
init: function() { // does creates icon
+ firetray.PrefListener.register(false);
+
this.appNameOriginal = Services.appinfo.name;
this.FILENAME_DEFAULT = firetray.Utils.chromeToPath(
"chrome://firetray/skin/" + this.appNameOriginal.toLowerCase() + this.FILENAME_SUFFIX);
@@ -105,6 +108,8 @@ firetray.Handler = {
},
shutdown: function() {
+ firetray.PrefListener.unregister();
+
if (this.inMailApp)
firetray.Messaging.shutdown();
firetray.StatusIcon.shutdown();
@@ -272,3 +277,19 @@ firetray.Handler = {
}
}; // firetray.Handler
+
+
+firetray.PrefListener = new PrefListener(
+ "extensions.firetray.",
+ function(branch, name) {
+ LOG('Pref changed: '+name);
+ switch (name) {
+ case 'hides_single_window':
+ firetray.Handler.updatePopupMenu();
+ break;
+ case 'show_icon_on_hide':
+ firetray.Handler.showHideIcon();
+ break;
+ default:
+ }
+ });
diff --git a/src/modules/FiretrayPrefListener.jsm b/src/modules/FiretrayPrefListener.jsm
new file mode 100644
index 0000000..670ee68
--- /dev/null
+++ b/src/modules/FiretrayPrefListener.jsm
@@ -0,0 +1,50 @@
+/* -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+// https://developer.mozilla.org/en/Code_snippets/Preferences
+
+var EXPORTED_SYMBOLS = [ "PrefListener" ];
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+
+/**
+ * @constructor
+ *
+ * @param {string} branch_name
+ * @param {Function} callback must have the following arguments:
+ * branch, pref_leaf_name
+ */
+function PrefListener(branch_name, callback) {
+ // Keeping a reference to the observed preference branch or it will get
+ // garbage collected.
+ var prefService = Components.classes["@mozilla.org/preferences-service;1"]
+ .getService(Components.interfaces.nsIPrefService);
+ this._branch = prefService.getBranch(branch_name);
+ this._branch.QueryInterface(Components.interfaces.nsIPrefBranch2);
+ this._callback = callback;
+}
+
+PrefListener.prototype.observe = function(subject, topic, data) {
+ if (topic == 'nsPref:changed')
+ this._callback(this._branch, data);
+};
+
+/**
+ * @param {boolean=} trigger if true triggers the registered function
+ * on registration, that is, when this method is called.
+ */
+PrefListener.prototype.register = function(trigger) {
+ this._branch.addObserver('', this, false);
+ if (trigger) {
+ let that = this;
+ this._branch.getChildList('', {}).
+ forEach(function (pref_leaf_name)
+ { that._callback(that._branch, pref_leaf_name); });
+ }
+};
+
+PrefListener.prototype.unregister = function() {
+ if (this._branch)
+ this._branch.removeObserver('', this);
+};
diff --git a/src/modules/gtk2/FiretrayPopupMenu.jsm b/src/modules/gtk2/FiretrayPopupMenu.jsm
new file mode 100644
index 0000000..207bf82
--- /dev/null
+++ b/src/modules/gtk2/FiretrayPopupMenu.jsm
@@ -0,0 +1,221 @@
+/* -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+var EXPORTED_SYMBOLS = [ "firetray" ];
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/ctypes.jsm");
+Cu.import("resource://firetray/ctypes/gobject.jsm");
+Cu.import("resource://firetray/ctypes/gtk.jsm");
+Cu.import("resource://firetray/commons.js");
+
+if ("undefined" == typeof(firetray.StatusIcon))
+ ERROR("This module MUST be imported from/after StatusIcon !");
+
+
+firetray.PopupMenu = {
+ initialized: false,
+ // pointers to JS functions. MUST LIVE DURING ALL THE EXECUTION
+ callbacks: {menuItemWindowActivate: {}},
+ menu: null,
+ menuSeparatorWindows: null,
+ MIN_FONT_SIZE: 4,
+
+ init: function() { // FIXME: function too long
+ this.menu = gtk.gtk_menu_new();
+ var menuShell = ctypes.cast(this.menu, gtk.GtkMenuShell.ptr);
+ var addMenuSeparator = false;
+
+ if (firetray.Handler.inBrowserApp) {
+ var menuItemNewWindowLabel = firetray.Utils.strings.GetStringFromName("popupMenu.itemLabel.NewWindow");
+ var menuItemNewWindow = gtk.gtk_image_menu_item_new_with_label(
+ menuItemNewWindowLabel);
+ var menuItemNewWindowIcon = gtk.gtk_image_new_from_stock(
+ "gtk-new", gtk.GTK_ICON_SIZE_MENU);
+ gtk.gtk_image_menu_item_set_image(menuItemNewWindow, menuItemNewWindowIcon);
+ gtk.gtk_menu_shell_append(menuShell, ctypes.cast(menuItemNewWindow, gtk.GtkWidget.ptr));
+
+ this.callbacks.menuItemNewWindowActivate = gobject.GCallback_t(
+ firetray.Handler.openBrowserWindow);
+ gobject.g_signal_connect(menuItemNewWindow, "activate",
+ firetray.PopupMenu.callbacks.menuItemNewWindowActivate, null);
+
+ addMenuSeparator = true;
+ }
+
+ if (firetray.Handler.inMailApp) {
+ var menuItemNewMessageLabel = firetray.Utils.strings.GetStringFromName("popupMenu.itemLabel.NewMessage");
+ var menuItemNewMessage = gtk.gtk_image_menu_item_new_with_label(
+ menuItemNewMessageLabel);
+ var menuItemNewMessageIcon = gtk.gtk_image_new_from_stock(
+ "gtk-edit", gtk.GTK_ICON_SIZE_MENU);
+ gtk.gtk_image_menu_item_set_image(menuItemNewMessage, menuItemNewMessageIcon);
+ gtk.gtk_menu_shell_append(menuShell, ctypes.cast(menuItemNewMessage, gtk.GtkWidget.ptr));
+
+ this.callbacks.menuItemNewMessageActivate = gobject.GCallback_t(
+ firetray.Handler.openMailMessage);
+ gobject.g_signal_connect(menuItemNewMessage, "activate",
+ firetray.PopupMenu.callbacks.menuItemNewMessageActivate, null);
+
+ addMenuSeparator = true;
+ }
+
+ if (addMenuSeparator) {
+ var menuSeparator = gtk.gtk_separator_menu_item_new();
+ gtk.gtk_menu_shell_append(menuShell, ctypes.cast(menuSeparator, gtk.GtkWidget.ptr));
+ }
+
+ // shouldn't need to convert to utf8 thank to js-ctypes
+ var menuItemQuitLabel = firetray.Utils.strings.GetStringFromName("popupMenu.itemLabel.Quit");
+ var menuItemQuit = gtk.gtk_image_menu_item_new_with_label(
+ menuItemQuitLabel);
+ var menuItemQuitIcon = gtk.gtk_image_new_from_stock(
+ "gtk-quit", gtk.GTK_ICON_SIZE_MENU);
+ gtk.gtk_image_menu_item_set_image(menuItemQuit, menuItemQuitIcon);
+ gtk.gtk_menu_shell_append(menuShell, ctypes.cast(menuItemQuit, gtk.GtkWidget.ptr));
+
+ this.callbacks.menuItemQuitActivate = gobject.GCallback_t(
+ firetray.Handler.quitApplication);
+ gobject.g_signal_connect(menuItemQuit, "activate",
+ firetray.PopupMenu.callbacks.menuItemQuitActivate, null);
+
+ var menuWidget = ctypes.cast(this.menu, gtk.GtkWidget.ptr);
+ gtk.gtk_widget_show_all(menuWidget);
+
+ var menuSeparatorWindows = gtk.gtk_separator_menu_item_new();
+ gtk.gtk_menu_shell_prepend(menuShell, ctypes.cast(menuSeparatorWindows, gtk.GtkWidget.ptr));
+ this.menuSeparatorWindows = menuSeparatorWindows;
+
+ this.initialized = true;
+ return true;
+ },
+
+ shutdown: function() {
+ firetray.Utils.tryCloseLibs([gobject, gtk]);
+ this.initialized = false;
+ },
+
+ popup: function(icon, button, activateTime, menu) {
+ LOG("menu-popup");
+ LOG("ARGS="+icon+", "+button+", "+activateTime+", "+menu);
+
+ try {
+ var gtkMenuPtr = ctypes.cast(menu, gtk.GtkMenu.ptr);
+ var iconGpointer = ctypes.cast(icon, gobject.gpointer);
+ gtk.gtk_menu_popup(
+ gtkMenuPtr, null, null, gtk.gtk_status_icon_position_menu,
+ iconGpointer, button, activateTime);
+ } catch (x) { ERROR(x); }
+ },
+
+ // we'll be creating menuItems for windows (and not showing them) even if
+ // hides_single_window is false, because if hides_single_window becomes true,
+ // we'll just have to show the menuItems
+ addWindowItem: function(xid) { // on registerWindow
+ var menuItemWindow = this.addItem();
+ firetray.Handler.gtkPopupMenuWindowItems.insert(xid, menuItemWindow);
+
+ this.callbacks.menuItemWindowActivate[xid] = gobject.GCallback_t(
+ function(){firetray.Handler.showSingleWindow(xid);});
+ gobject.g_signal_connect(menuItemWindow, "activate",
+ firetray.PopupMenu.callbacks.menuItemWindowActivate[xid], null);
+ this.setWindowItemLabel(menuItemWindow, xid); // default to xid
+
+ LOG("add gtkPopupMenuWindowItems: "+firetray.Handler.gtkPopupMenuWindowItems.count);
+ },
+
+ addItem: function() {
+ var menuItem = gtk.gtk_image_menu_item_new();
+ var menuShell = ctypes.cast(this.menu, gtk.GtkMenuShell.ptr);
+ gtk.gtk_menu_shell_prepend(menuShell, ctypes.cast(menuItem, gtk.GtkWidget.ptr));
+ return menuItem;
+ },
+
+ removeWindowItem: function(xid) { // on unregisterWindow
+ let menuItemWindow = firetray.Handler.gtkPopupMenuWindowItems.get(xid);
+ firetray.Handler.gtkPopupMenuWindowItems.remove(xid);
+ this.removeItem(menuItemWindow);
+ LOG("remove gtkPopupMenuWindowItems: "+firetray.Handler.gtkPopupMenuWindowItems.count);
+ },
+ removeItem: function(item) {
+ gtk.gtk_widget_destroy(ctypes.cast(item, gtk.GtkWidget.ptr));
+ },
+
+ showAllWindowItemsOnlyVisibleWindows: function() {
+ for (let xid in firetray.Handler.windows)
+ if (!firetray.Handler.windows[xid].visibility)
+ this.showSingleWindowItem(xid);
+ },
+
+ showSingleWindowItem: function(xid) {
+ LOG("showSingleWindowItem");
+ let menuItemWindow = firetray.Handler.gtkPopupMenuWindowItems.get(xid);
+ this.showItem(menuItemWindow);
+ this.setWindowItemLabel(menuItemWindow, firetray.Window.getWindowTitle(xid));
+ this.showWindowSeparator();
+ },
+
+ showItem: function(menuItem) {
+ gtk.gtk_widget_show(ctypes.cast(menuItem, gtk.GtkWidget.ptr));
+ },
+
+ setWindowItemLabel: function(menuItem, label) {
+ LOG("about to set title: "+label);
+ if (label)
+ gtk.gtk_menu_item_set_label(ctypes.cast(menuItem, gtk.GtkMenuItem.ptr), label);
+ },
+
+ hideAllWindowItems: function() {
+ for (let xid in firetray.Handler.windows)
+ this.hideSingleWindowItemAndSeparator(xid);
+ },
+
+ // PopupMenu.hideItem(firetray.Handler.gtkPopupMenuWindowItems.get(xid))
+ hideSingleWindowItemAndSeparator: function(xid) {
+ this.hideSingleWindowItem(xid);
+ this.hideWindowSeparator();
+ },
+
+ hideSingleWindowItemAndSeparatorMaybe: function(xid) {
+ this.hideSingleWindowItem(xid);
+ if (firetray.Handler.visibleWindowsCount === firetray.Handler.windowsCount)
+ this.hideWindowSeparator();
+ },
+
+ hideSingleWindowItem: function(xid) {
+ LOG("hideSingleWindowItem");
+ let menuItemWindow = firetray.Handler.gtkPopupMenuWindowItems.get(xid);
+ this.hideItem(menuItemWindow);
+ },
+
+ hideItem: function(menuItem) {
+ gtk.gtk_widget_hide(ctypes.cast(menuItem, gtk.GtkWidget.ptr));
+ },
+
+ showWindowSeparator: function() {
+ LOG("showing menuSeparatorWindows");
+ gtk.gtk_widget_show(ctypes.cast(this.menuSeparatorWindows, gtk.GtkWidget.ptr));
+ },
+ hideWindowSeparator: function() {
+ LOG("hiding menuSeparatorWindows");
+ gtk.gtk_widget_hide(ctypes.cast(this.menuSeparatorWindows, gtk.GtkWidget.ptr));
+ }
+
+}; // firetray.PopupMenu
+
+
+firetray.Handler.popupMenuWindowItemsHandled = function() {
+ return (firetray.Handler.inBrowserApp &&
+ firetray.Utils.prefService.getBoolPref('hides_single_window'));
+};
+
+firetray.Handler.updatePopupMenu = function() {
+ if (firetray.Handler.popupMenuWindowItemsHandled())
+ firetray.PopupMenu.showAllWindowItemsOnlyVisibleWindows();
+ else
+ firetray.PopupMenu.hideAllWindowItems();
+};
diff --git a/src/modules/gtk2/FiretrayStatusIcon.jsm b/src/modules/gtk2/FiretrayStatusIcon.jsm
index 5541a01..7174ac8 100644
--- a/src/modules/gtk2/FiretrayStatusIcon.jsm
+++ b/src/modules/gtk2/FiretrayStatusIcon.jsm
@@ -13,10 +13,8 @@ Cu.import("resource://firetray/ctypes/cairo.jsm");
Cu.import("resource://firetray/ctypes/gobject.jsm");
Cu.import("resource://firetray/ctypes/gdk.jsm");
Cu.import("resource://firetray/ctypes/gtk.jsm");
-Cu.import("resource://firetray/ctypes/libc.jsm");
Cu.import("resource://firetray/ctypes/pango.jsm");
Cu.import("resource://firetray/ctypes/pangocairo.jsm");
-Cu.import("resource://firetray/ctypes/x11.jsm");
Cu.import("resource://firetray/commons.js");
if ("undefined" == typeof(firetray.Handler))
@@ -26,11 +24,8 @@ if ("undefined" == typeof(firetray.Handler))
firetray.StatusIcon = {
initialized: false,
// pointers to JS functions. MUST LIVE DURING ALL THE EXECUTION
- callbacks: {menuItemWindowActivate: {}},
+ callbacks: {},
trayIcon: null,
- menu: null,
- menuSeparatorWindows: null,
- MIN_FONT_SIZE: 4,
init: function() {
try {
@@ -43,16 +38,13 @@ firetray.StatusIcon = {
firetray.Handler.setIconImageDefault();
- this._buildPopupMenu();
-
firetray.Handler.setIconTooltipDefault();
- LOG("showHideAllWindows: "+firetray.Handler.hasOwnProperty("showHideAllWindows"));
- this.callbacks.iconActivate = gtk.GCallbackStatusIconActivate_t(
- firetray.Handler.showHideAllWindows);
- let handlerId = gobject.g_signal_connect(firetray.StatusIcon.trayIcon,
- "activate", firetray.StatusIcon.callbacks.iconActivate, null);
- LOG("g_connect activate="+handlerId);
+ Cu.import("resource://firetray/gtk2/FiretrayPopupMenu.jsm");
+ if (!firetray.PopupMenu.init())
+ return false;
+
+ this.addCallbacks();
this.initialized = true;
return true;
@@ -63,179 +55,23 @@ firetray.StatusIcon = {
this.initialized = false;
},
- _buildPopupMenu: function() { // FIXME: function too long
- this.menu = gtk.gtk_menu_new();
- var menuShell = ctypes.cast(this.menu, gtk.GtkMenuShell.ptr);
- var addMenuSeparator = false;
-
- if (firetray.Handler.inBrowserApp) {
- var menuItemNewWindowLabel = firetray.Utils.strings.GetStringFromName("popupMenu.itemLabel.NewWindow");
- var menuItemNewWindow = gtk.gtk_image_menu_item_new_with_label(
- menuItemNewWindowLabel);
- var menuItemNewWindowIcon = gtk.gtk_image_new_from_stock(
- "gtk-new", gtk.GTK_ICON_SIZE_MENU);
- gtk.gtk_image_menu_item_set_image(menuItemNewWindow, menuItemNewWindowIcon);
- gtk.gtk_menu_shell_append(menuShell, ctypes.cast(menuItemNewWindow, gtk.GtkWidget.ptr));
-
- this.callbacks.menuItemNewWindowActivate = gobject.GCallback_t(
- firetray.Handler.openBrowserWindow);
- gobject.g_signal_connect(menuItemNewWindow, "activate",
- firetray.StatusIcon.callbacks.menuItemNewWindowActivate, null);
-
- addMenuSeparator = true;
- }
-
- if (firetray.Handler.inMailApp) {
- var menuItemNewMessageLabel = firetray.Utils.strings.GetStringFromName("popupMenu.itemLabel.NewMessage");
- var menuItemNewMessage = gtk.gtk_image_menu_item_new_with_label(
- menuItemNewMessageLabel);
- var menuItemNewMessageIcon = gtk.gtk_image_new_from_stock(
- "gtk-edit", gtk.GTK_ICON_SIZE_MENU);
- gtk.gtk_image_menu_item_set_image(menuItemNewMessage, menuItemNewMessageIcon);
- gtk.gtk_menu_shell_append(menuShell, ctypes.cast(menuItemNewMessage, gtk.GtkWidget.ptr));
-
- this.callbacks.menuItemNewMessageActivate = gobject.GCallback_t(
- firetray.Handler.openMailMessage);
- gobject.g_signal_connect(menuItemNewMessage, "activate",
- firetray.StatusIcon.callbacks.menuItemNewMessageActivate, null);
-
- addMenuSeparator = true;
- }
-
- if (addMenuSeparator) {
- var menuSeparator = gtk.gtk_separator_menu_item_new();
- gtk.gtk_menu_shell_append(menuShell, ctypes.cast(menuSeparator, gtk.GtkWidget.ptr));
- }
-
- // shouldn't need to convert to utf8 thank to js-ctypes
- var menuItemQuitLabel = firetray.Utils.strings.GetStringFromName("popupMenu.itemLabel.Quit");
- var menuItemQuit = gtk.gtk_image_menu_item_new_with_label(
- menuItemQuitLabel);
- var menuItemQuitIcon = gtk.gtk_image_new_from_stock(
- "gtk-quit", gtk.GTK_ICON_SIZE_MENU);
- gtk.gtk_image_menu_item_set_image(menuItemQuit, menuItemQuitIcon);
- gtk.gtk_menu_shell_append(menuShell, ctypes.cast(menuItemQuit, gtk.GtkWidget.ptr));
-
- this.callbacks.menuItemQuitActivate = gobject.GCallback_t(
- firetray.Handler.quitApplication);
- gobject.g_signal_connect(menuItemQuit, "activate",
- firetray.StatusIcon.callbacks.menuItemQuitActivate, null);
-
- var menuWidget = ctypes.cast(this.menu, gtk.GtkWidget.ptr);
- gtk.gtk_widget_show_all(menuWidget);
-
+ addCallbacks: function() {
/* NOTE: here we do use a function handler (instead of a function
- definition) because we need the args passed to it ! As a consequence, we
- need to abandon 'this' in popupMenu() */
- let that = this;
- this.callbacks.popupMenu = gtk.GCallbackMenuPopup_t(that.popupMenu);
+ definition) because we need the args passed to it ! As a consequence, we
+ need to abandon 'this' in PopupMenu.popup() */
+ this.callbacks.menuPopup = gtk.GCallbackMenuPopup_t(firetray.PopupMenu.popup);
gobject.g_signal_connect(this.trayIcon, "popup-menu",
- firetray.StatusIcon.callbacks.popupMenu, this.menu);
- this.callbacks.onScroll = gtk.GCallbackOnScroll_t(that.onScroll);
+ firetray.StatusIcon.callbacks.menuPopup, firetray.PopupMenu.menu);
+ this.callbacks.onScroll = gtk.GCallbackOnScroll_t(firetray.StatusIcon.onScroll);
gobject.g_signal_connect(this.trayIcon, "scroll-event",
- firetray.StatusIcon.callbacks.onScroll, null);
-
- var menuSeparatorWindows = gtk.gtk_separator_menu_item_new();
- gtk.gtk_menu_shell_prepend(menuShell, ctypes.cast(menuSeparatorWindows, gtk.GtkWidget.ptr));
- firetray.StatusIcon.menuSeparatorWindows = menuSeparatorWindows;
-
- },
-
- popupMenu: function(icon, button, activateTime, menu) {
- LOG("menu-popup");
- LOG("ARGS="+icon+", "+button+", "+activateTime+", "+menu);
-
- try {
- var gtkMenuPtr = ctypes.cast(menu, gtk.GtkMenu.ptr);
- var iconGpointer = ctypes.cast(icon, gobject.gpointer);
- gtk.gtk_menu_popup(
- gtkMenuPtr, null, null, gtk.gtk_status_icon_position_menu,
- iconGpointer, button, activateTime);
- } catch (x) {
- ERROR(x);
- }
- },
-
- // we keep the definition here, as it is(?) specific to the
- // platform-dependant StatusIcon (there might be no popup menu in other
- // platforms)
- popupMenuWindowItemsHandled: function() {
- return (firetray.Handler.inBrowserApp &&
- firetray.Utils.prefService.getBoolPref('hides_single_window'));
- },
+ firetray.StatusIcon.callbacks.onScroll, null);
- // we'll be creating menuItems for windows (and not showing them) even if
- // hides_single_window is false, because if hides_single_window becomes true,
- // we'll just have to show the menuItems
- addPopupMenuWindowItem: function(xid) { // on registerWindow
- var menuItemWindow = gtk.gtk_image_menu_item_new();
- firetray.Handler.gtkPopupMenuWindowItems.insert(xid, menuItemWindow);
-
- var menuShell = ctypes.cast(firetray.StatusIcon.menu, gtk.GtkMenuShell.ptr);
- gtk.gtk_menu_shell_prepend(menuShell,
- ctypes.cast(menuItemWindow, gtk.GtkWidget.ptr));
-
- this.callbacks.menuItemWindowActivate[xid] = gobject.GCallback_t(
- function(){firetray.Handler.showSingleWindow(xid);});
- gobject.g_signal_connect(menuItemWindow, "activate",
- firetray.StatusIcon.callbacks.menuItemWindowActivate[xid], null);
-
- LOG("add gtkPopupMenuWindowItems: "+firetray.Handler.gtkPopupMenuWindowItems.count);
- },
-
- setPopupMenuWindowItemLabel: function(menuItem, xid) {
- let title = firetray.Handler.windows[xid].baseWin.title;
- let tailIndex = title.indexOf(" - Mozilla "+firetray.Handler.appNameOriginal);
- if (tailIndex !== -1)
- title = title.substring(0, tailIndex);
- gtk.gtk_menu_item_set_label(ctypes.cast(menuItem, gtk.GtkMenuItem.ptr), title);
- },
-
- removePopupMenuWindowItem: function(xid) { // on unregisterWindow
- let menuItemWindow = firetray.Handler.gtkPopupMenuWindowItems.get(xid);
- firetray.Handler.gtkPopupMenuWindowItems.remove(xid);
- gtk.gtk_widget_destroy(ctypes.cast(menuItemWindow, gtk.GtkWidget.ptr));
-
- LOG("remove gtkPopupMenuWindowItems: "+firetray.Handler.gtkPopupMenuWindowItems.count);
- },
-
- showAllPopupMenuWindowItems: function(filterVisibleWindows) {
- for (let xid in firetray.Handler.windows)
- if (!filterVisibleWindows || !firetray.Handler.windows[xid].visibility)
- this.showSinglePopupMenuWindowItem(xid);
- },
-
- showSinglePopupMenuWindowItem: function(xid) {
- LOG("showSinglePopupMenuWindowItem");
- let menuItemWindow = firetray.Handler.gtkPopupMenuWindowItems.get(xid);
- gtk.gtk_widget_show(ctypes.cast(menuItemWindow, gtk.GtkWidget.ptr));
- this.setPopupMenuWindowItemLabel(menuItemWindow, xid); // not when creating item !
- this.showPopupMenuWindowSeparator();
- },
-
- hideAllPopupMenuWindowItems: function(forceHideSeparator) {
- for (let xid in firetray.Handler.windows)
- this.hideSinglePopupMenuWindowItem(xid, forceHideSeparator);
- },
-
- // PopupMenu.hideItem(firetray.Handler.gtkPopupMenuWindowItems.get(xid))
- hideSinglePopupMenuWindowItem: function(xid, forceHideSeparator) {
- LOG("hideSinglePopupMenuWindowItem");
- let menuItemWindow = firetray.Handler.gtkPopupMenuWindowItems.get(xid);
- gtk.gtk_widget_hide(ctypes.cast(menuItemWindow, gtk.GtkWidget.ptr)); // on hideSingleWindow
-
- if (forceHideSeparator || (firetray.Handler.visibleWindowsCount === firetray.Handler.windowsCount)) {
- this.hidePopupMenuWindowSeparator();
- }
- },
-
- showPopupMenuWindowSeparator: function() {
- LOG("showing menuSeparatorWindows");
- gtk.gtk_widget_show(ctypes.cast(firetray.StatusIcon.menuSeparatorWindows, gtk.GtkWidget.ptr));
- },
- hidePopupMenuWindowSeparator: function() {
- LOG("hiding menuSeparatorWindows");
- gtk.gtk_widget_hide(ctypes.cast(firetray.StatusIcon.menuSeparatorWindows, gtk.GtkWidget.ptr));
+ LOG("showHideAllWindows: "+firetray.Handler.hasOwnProperty("showHideAllWindows"));
+ this.callbacks.iconActivate = gtk.GCallbackStatusIconActivate_t(
+ firetray.Handler.showHideAllWindows);
+ let handlerId = gobject.g_signal_connect(firetray.StatusIcon.trayIcon,
+ "activate", firetray.StatusIcon.callbacks.iconActivate, null);
+ LOG("g_connect activate="+handlerId);
},
onScroll: function(icon, event, data) {
@@ -421,10 +257,3 @@ firetray.Handler.setIconVisibility = function(visible) {
gtk.gtk_status_icon_set_visible(firetray.StatusIcon.trayIcon, visible);
return true;
};
-
-firetray.Handler.updatePopupMenu = function() {
- if (firetray.StatusIcon.popupMenuWindowItemsHandled())
- firetray.StatusIcon.showAllPopupMenuWindowItems(true);
- else
- firetray.StatusIcon.hideAllPopupMenuWindowItems(true);
-};
diff --git a/src/modules/gtk2/FiretrayWindow.jsm b/src/modules/gtk2/FiretrayWindow.jsm
index 5336599..22a4e76 100644
--- a/src/modules/gtk2/FiretrayWindow.jsm
+++ b/src/modules/gtk2/FiretrayWindow.jsm
@@ -46,6 +46,13 @@ var _find_data_t = ctypes.StructType("_find_data_t", [
{ outWindow: gtk.GtkWindow.ptr }
]);
+// NOTE: storing ctypes pointers into a JS object doesn't work: pointers are
+// "evolving" after a while (maybe due to back and forth conversion). So we
+// need to store them into a real ctypes array !
+firetray.Handler.gtkWindows = new ctypesMap(gtk.GtkWindow.ptr),
+firetray.Handler.gdkWindows = new ctypesMap(gdk.GdkWindow.ptr),
+firetray.Handler.gtkPopupMenuWindowItems = new ctypesMap(gtk.GtkImageMenuItem.ptr),
+
firetray.Window = {
@@ -172,7 +179,7 @@ firetray.Window = {
throw new DeleteError();
firetray.Handler.gtkWindows.remove(xid);
firetray.Handler.gdkWindows.remove(xid);
- firetray.StatusIcon.removePopupMenuWindowItem(xid);
+ firetray.PopupMenu.removeWindowItem(xid);
} else {
ERROR("can't unregister unknown window "+xid);
return false;
@@ -368,6 +375,15 @@ firetray.Window = {
return desktop;
},
+ getWindowTitle: function(xid) {
+ let title = firetray.Handler.windows[xid].baseWin.title;
+ let tailIndex = title.indexOf(" - Mozilla "+firetray.Handler.appNameOriginal);
+ if (tailIndex !== -1)
+ return title.substring(0, tailIndex)
+ else
+ return null;
+ },
+
filterWindow: function(xev, gdkEv, data) {
if (!xev)
return gdk.GDK_FILTER_CONTINUE;
@@ -395,19 +411,6 @@ firetray.Window = {
}
break;
- case x11.ClientMessage: // not very useful
- LOG("ClientMessage");
-/* KEPT FOR LATER USE
- let xclient = ctypes.cast(xev, x11.XClientMessageEvent.ptr);
- LOG("xclient.data="+xclient.contents.data);
- LOG("message_type="+xclient.contents.message_type+", format="+xclient.contents.format);
- if (strEquals(xclient.contents.data[0], x11.current.Atoms.WM_DELETE_WINDOW)) {
- LOG("Delete Window prevented");
- return gdk.GDK_FILTER_REMOVE;
- }
-*/
- break;
-
default:
// LOG("xany.type="+xany.contents.type);
break;
@@ -424,13 +427,6 @@ firetray.Window = {
///////////////////////// firetray.Handler overriding /////////////////////////
-// NOTE: storing ctypes pointers into a JS object doesn't work: pointers are
-// "evolving" after a while (maybe due to back and forth conversion). So we
-// need to store them into a real ctypes array !
-firetray.Handler.gtkWindows = new ctypesMap(gtk.GtkWindow.ptr),
-firetray.Handler.gdkWindows = new ctypesMap(gdk.GdkWindow.ptr),
-firetray.Handler.gtkPopupMenuWindowItems = new ctypesMap(gtk.GtkImageMenuItem.ptr),
-
/** debug facility */
firetray.Handler.dumpWindows = function() {
LOG(firetray.Handler.windowsCount);
@@ -450,7 +446,7 @@ firetray.Handler.registerWindow = function(win) {
try {
this.gtkWindows.insert(xid, gtkWin);
this.gdkWindows.insert(xid, gdkWin);
- firetray.StatusIcon.addPopupMenuWindowItem(xid);
+ firetray.PopupMenu.addWindowItem(xid);
} catch (x) {
if (x.name === "RangeError") // instanceof not working :-(
win.alert(x+"\n\nYou seem to have more than "+FIRETRAY_WINDOW_COUNT_MAX
@@ -470,12 +466,6 @@ firetray.Handler.registerWindow = function(win) {
// delete_event_cb (in gtk2/nsWindow.cpp), but we prefer to use the
// provided 'close' JS event
-/* KEPT FOR LATER USE
- this.windows[xid].onWindowStateCb = gtk.GCallbackWindowStateEvent_t(firetray.Window.onWindowState);
- this.windows[xid].onWindowStateCbId = gobject.g_signal_connect(gtkWin, "window-state-event", this.windows[xid].onWindowStateCb, null);
- LOG("g_connect window-state-event="+this.windows[xid].onWindowStateCbId);
-*/
-
this.windows[xid].filterWindowCb = gdk.GdkFilterFunc_t(firetray.Window.filterWindow);
gdk.gdk_window_add_filter(gdkWin, this.windows[xid].filterWindowCb, null);
@@ -492,7 +482,6 @@ firetray.Handler.registerWindow = function(win) {
firetray.Handler.unregisterWindow = function(win) {
LOG("unregister window");
-
let xid = firetray.Window.getXIDFromChromeWindow(win);
return firetray.Window.unregisterWindowByXID(xid);
};
@@ -510,8 +499,8 @@ firetray.Handler.showSingleWindow = function(xid) {
firetray.Handler.windows[xid].visibility = true;
firetray.Handler.visibleWindowsCount += 1;
- if (firetray.StatusIcon.popupMenuWindowItemsHandled())
- firetray.StatusIcon.hideSinglePopupMenuWindowItem(xid);
+ if (firetray.Handler.popupMenuWindowItemsHandled())
+ firetray.PopupMenu.hideSingleWindowItemAndSeparatorMaybe(xid);
firetray.Handler.showHideIcon();
};
@@ -529,8 +518,8 @@ firetray.Handler.hideSingleWindow = function(xid) {
firetray.Handler.windows[xid].visibility = false;
firetray.Handler.visibleWindowsCount -= 1;
- if (firetray.StatusIcon.popupMenuWindowItemsHandled())
- firetray.StatusIcon.showSinglePopupMenuWindowItem(xid);
+ if (firetray.Handler.popupMenuWindowItemsHandled())
+ firetray.PopupMenu.showSingleWindowItem(xid);
firetray.Handler.showHideIcon();
};
@@ -543,10 +532,11 @@ firetray.Handler.showHideAllWindows = function(gtkStatusIcon, userData) {
LOG("windowsCount="+firetray.Handler.windowsCount);
let visibilityRate = firetray.Handler.visibleWindowsCount/firetray.Handler.windowsCount;
LOG("visibilityRate="+visibilityRate);
- if (visibilityRate > 0.5) // TODO: should be configurable
- firetray.Handler.hideAllWindows();
- else
+ if ((0.5 < visibilityRate) && (visibilityRate < 1)
+ || visibilityRate === 0) // TODO: should be configurable
firetray.Handler.showAllWindows();
+ else
+ firetray.Handler.hideAllWindows();
let stopPropagation = true;
return stopPropagation;
--
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