[Pkg-mozext-commits] [firetray] 146/399: * fix UI updating when toggling hides_single_window, show_icon_on_hide * add popup menu items for hidden windows to be shown individually
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 a803ceff17a331d1c243edad574a9593ed0ce074
Author: foudfou <foudil.newbie+git at gmail.com>
Date: Fri Jan 20 23:44:57 2012 +0100
* fix UI updating when toggling hides_single_window, show_icon_on_hide
* add popup menu items for hidden windows to be shown individually
I'm not quite satisfied with the global design/partitioning of the code accross
namespaces. Some ideas to explore: extract code related to the popup menu,
don't "wrap" window-related function into the Handler.
---
README.md | 3 ++
src/chrome/content/options.xul | 2 +-
src/chrome/content/overlay.js | 14 +++++
src/chrome/locale/en-US/options.dtd | 3 +-
src/modules/FiretrayHandler.jsm | 2 +
src/modules/ctypes/gtk.jsm | 7 ++-
src/modules/gtk2/FiretrayStatusIcon.jsm | 85 +++++++++++++++++++++++++++++--
src/modules/gtk2/FiretrayWindow.jsm | 11 ++++
8 files changed, 119 insertions(+), 8 deletions(-)
diff --git a/README.md b/README.md
index 63cdfc5..2aa87a3 100644
--- a/README.md
+++ b/README.md
@@ -54,6 +54,9 @@ KNOWN BUGS
the scope of this addon, but you may want to give a try to the
[MailAlert extension](https://addons.mozilla.org/en-US/thunderbird/addon/mailbox-alert/)
+* child windows (compose message, preferences, ...) are not handled by
+ Firetray. For ex., they are not hidden along with there top-level window.
+
Acknowledgment
--------------
diff --git a/src/chrome/content/options.xul b/src/chrome/content/options.xul
index cfa95fa..1ed1f8c 100644
--- a/src/chrome/content/options.xul
+++ b/src/chrome/content/options.xul
@@ -33,7 +33,7 @@
<tabbox>
<tabs>
- <tab label="&general_options;"/>
+ <tab label="&windows_icon_options;"/>
<tab label="&mail_options;" id="mail_tab" />
</tabs>
<tabpanels flex="1">
diff --git a/src/chrome/content/overlay.js b/src/chrome/content/overlay.js
index 6380bd7..df27aab 100644
--- a/src/chrome/content/overlay.js
+++ b/src/chrome/content/overlay.js
@@ -82,10 +82,24 @@ var firetrayChrome = {
}
},
+ // 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':
+ if (firetray.StatusIcon.popupMenuWindowItemsHandled())
+ firetray.StatusIcon.showAllPopupMenuWindowItems(true);
+ else
+ firetray.StatusIcon.hideAllPopupMenuWindowItems(true);
+ break;
+ case 'show_icon_on_hide':
+ firetray.Handler.showHideIcon();
+ break;
+ default:
+ }
break;
default:
}
diff --git a/src/chrome/locale/en-US/options.dtd b/src/chrome/locale/en-US/options.dtd
index f3aa08e..58dc23f 100644
--- a/src/chrome/locale/en-US/options.dtd
+++ b/src/chrome/locale/en-US/options.dtd
@@ -3,8 +3,7 @@
<!ENTITY NOT_IMPLEMENTED_YET "NOT IMPLEMENTED YET">
-<!ENTITY general_options "General">
-<!ENTITY input_options "Input">
+<!ENTITY windows_icon_options "Windows and Icon">
<!ENTITY mail_options "Mail">
<!ENTITY windows_behaviour "Windows behaviour">
diff --git a/src/modules/FiretrayHandler.jsm b/src/modules/FiretrayHandler.jsm
index 5f5db44..dcafdc3 100644
--- a/src/modules/FiretrayHandler.jsm
+++ b/src/modules/FiretrayHandler.jsm
@@ -187,6 +187,8 @@ firetray.Handler = {
if (firetray.Utils.prefService.getBoolPref('show_icon_on_hide'))
firetray.Handler.setIconVisibility(
(firetray.Handler.visibleWindowsCount !== firetray.Handler.windowsCount));
+ else
+ firetray.Handler.setIconVisibility(true);
},
/** nsIBaseWindow, nsIXULWindow, ... */
diff --git a/src/modules/ctypes/gtk.jsm b/src/modules/ctypes/gtk.jsm
index 74d5ecf..8dad3cd 100644
--- a/src/modules/ctypes/gtk.jsm
+++ b/src/modules/ctypes/gtk.jsm
@@ -45,6 +45,7 @@ function gtk_defines(lib) {
this.GtkMenu = ctypes.StructType("GtkMenu");
// use ctypes.cast(menu, LibGtkStatusIcon.GtkMenuShell.ptr);
this.GtkMenuShell = ctypes.StructType("GtkMenuShell");
+ this.GtkMenuItem = ctypes.StructType("GtkMenuItem");
this.GtkImageMenuItem = ctypes.StructType("GtkImageMenuItem");
this.GtkWindow = ctypes.StructType("GtkWindow");
this.GtkWindowType = ctypes.int; // enum
@@ -76,6 +77,8 @@ function gtk_defines(lib) {
lib.lazy_bind("gtk_status_icon_set_tooltip_text", ctypes.void_t, this.GtkStatusIcon.ptr, ctypes.char.ptr);
lib.lazy_bind("gtk_status_icon_set_visible", ctypes.void_t, this.GtkStatusIcon.ptr, gobject.gboolean);
lib.lazy_bind("gtk_menu_new", this.GtkMenu.ptr);
+ lib.lazy_bind("gtk_menu_item_set_label", ctypes.void_t, this.GtkMenuItem.ptr, gobject.gchar.ptr);
+ lib.lazy_bind("gtk_image_menu_item_new", this.GtkImageMenuItem.ptr);
lib.lazy_bind("gtk_image_menu_item_new_with_label", this.GtkImageMenuItem.ptr, gobject.gchar.ptr);
lib.lazy_bind("gtk_image_new_from_stock", this.GtkWidget.ptr, gobject.gchar.ptr, ctypes.int); // enum
lib.lazy_bind("gtk_image_menu_item_set_image", ctypes.void_t, this.GtkImageMenuItem.ptr, this.GtkWidget.ptr);
@@ -99,8 +102,8 @@ function gtk_defines(lib) {
lib.lazy_bind("gtk_window_set_decorated", ctypes.void_t, this.GtkWindow.ptr, gobject.gboolean);
lib.lazy_bind("gtk_widget_hide_on_delete", gobject.gboolean, this.GtkWidget.ptr);
- // lib.lazy_bind("gtk_widget_hide", ctypes.void_t, this.GtkWidget.ptr);
- // lib.lazy_bind("gtk_widget_show", ctypes.void_t, this.GtkWidget.ptr);
+ lib.lazy_bind("gtk_widget_hide", ctypes.void_t, this.GtkWidget.ptr);
+ lib.lazy_bind("gtk_widget_show", ctypes.void_t, this.GtkWidget.ptr);
lib.lazy_bind("gtk_widget_get_events", gobject.gint, this.GtkWidget.ptr);
lib.lazy_bind("gtk_widget_get_events", gobject.gint, this.GtkWidget.ptr);
lib.lazy_bind("gtk_widget_add_events", ctypes.void_t, this.GtkWidget.ptr, gobject.gint);
diff --git a/src/modules/gtk2/FiretrayStatusIcon.jsm b/src/modules/gtk2/FiretrayStatusIcon.jsm
index e1406b2..850d188 100644
--- a/src/modules/gtk2/FiretrayStatusIcon.jsm
+++ b/src/modules/gtk2/FiretrayStatusIcon.jsm
@@ -16,6 +16,7 @@ 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))
@@ -24,9 +25,11 @@ if ("undefined" == typeof(firetray.Handler))
firetray.StatusIcon = {
initialized: false,
- callbacks: {}, // pointers to JS functions. MUST LIVE DURING ALL THE EXECUTION
+ // pointers to JS functions. MUST LIVE DURING ALL THE EXECUTION
+ callbacks: {menuItemWindowActivate: {}},
trayIcon: null,
menu: null,
+ menuSeparatorWindows: null,
MIN_FONT_SIZE: 4,
init: function() {
@@ -60,7 +63,7 @@ firetray.StatusIcon = {
this.initialized = false;
},
- _buildPopupMenu: function() {
+ _buildPopupMenu: function() { // FIXME: function too long
this.menu = gtk.gtk_menu_new();
var menuShell = ctypes.cast(this.menu, gtk.GtkMenuShell.ptr);
var addMenuSeparator = false;
@@ -131,6 +134,11 @@ firetray.StatusIcon = {
this.callbacks.onScroll = gtk.GCallbackOnScroll_t(that.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) {
@@ -148,6 +156,77 @@ firetray.StatusIcon = {
}
},
+ // 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'));
+ },
+
+ // 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);
+ },
+
+ 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);
+ },
+
+ showSinglePopupMenuWindowItem: function(xid) {
+ LOG("showSinglePopupMenuWindowItem");
+ let menuItemWindow = firetray.Handler.gtkPopupMenuWindowItems.get(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(menuItemWindow, gtk.GtkMenuItem.ptr), title);
+ gtk.gtk_widget_show(ctypes.cast(menuItemWindow, gtk.GtkWidget.ptr));
+ gtk.gtk_widget_show(ctypes.cast(firetray.StatusIcon.menuSeparatorWindows, gtk.GtkWidget.ptr));
+ },
+
+ 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)) {
+ LOG("hiding menuSeparatorWindows");
+ gtk.gtk_widget_hide(
+ ctypes.cast(firetray.StatusIcon.menuSeparatorWindows, gtk.GtkWidget.ptr));
+ }
+ },
+
+ showAllPopupMenuWindowItems: function(filterVisibleWindows) {
+ for (let xid in firetray.Handler.windows)
+ if (!filterVisibleWindows || !firetray.Handler.windows[xid].visibility)
+ this.showSinglePopupMenuWindowItem(xid);
+ },
+
+ hideAllPopupMenuWindowItems: function(forceHideSeparator) {
+ for (let xid in firetray.Handler.windows)
+ this.hideSinglePopupMenuWindowItem(xid, forceHideSeparator);
+ },
+
onScroll: function(icon, event, data) {
let iconGpointer = ctypes.cast(icon, gobject.gpointer);
let gdkEventScroll = ctypes.cast(event, gdk.GdkEventScroll.ptr);
@@ -219,7 +298,7 @@ firetray.Handler.setIconTooltipDefault = function() {
this.setIconTooltip(this.appNameOriginal);
};
-firetray.Handler.setIconText = function(text, color) { // TODO: split into smaller functions;
+firetray.Handler.setIconText = function(text, color) { // FIXME: function too long
LOG("setIconText, color="+color);
if (typeof(text) != "string")
throw new TypeError();
diff --git a/src/modules/gtk2/FiretrayWindow.jsm b/src/modules/gtk2/FiretrayWindow.jsm
index 7ef1f54..bfa3f0f 100644
--- a/src/modules/gtk2/FiretrayWindow.jsm
+++ b/src/modules/gtk2/FiretrayWindow.jsm
@@ -412,6 +412,7 @@ firetray.Window = {
// 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() {
@@ -430,6 +431,7 @@ firetray.Handler.registerWindow = function(win) {
try {
this.gtkWindows.insert(xid, gtkWin);
this.gdkWindows.insert(xid, gdkWin);
+ firetray.StatusIcon.addPopupMenuWindowItem(xid);
} catch (x) {
if (x.name === "RangeError") // instanceof not working :-(
win.alert(x+"\n\nYou seem to have more than "+FIRETRAY_WINDOW_COUNT_MAX
@@ -477,6 +479,7 @@ firetray.Handler._unregisterWindowByXID = function(xid) {
throw new DeleteError();
this.gtkWindows.remove(xid);
this.gdkWindows.remove(xid);
+ firetray.StatusIcon.removePopupMenuWindowItem(xid);
} else {
ERROR("can't unregister unknown window "+xid);
return false;
@@ -507,11 +510,17 @@ firetray.Handler.showSingleWindow = function(xid) {
firetray.Handler.windows[xid].visibility = true;
firetray.Handler.visibleWindowsCount += 1;
+ try {
+ LOG("popupMenuWindowItemsHandled="+firetray.StatusIcon.popupMenuWindowItemsHandled());
+ if (firetray.StatusIcon.popupMenuWindowItemsHandled())
+ firetray.StatusIcon.hideSinglePopupMenuWindowItem(xid);
firetray.Handler.showHideIcon();
+ } catch(x) {ERROR(x);}
};
// NOTE: we keep using high-level cross-plat BaseWindow.visibility (instead of
// gdk_window_show_unraised)
+/* FIXME: hiding windows should also hide child windows */
firetray.Handler.hideSingleWindow = function(xid) {
LOG("hideSingleWindow");
@@ -523,6 +532,8 @@ firetray.Handler.hideSingleWindow = function(xid) {
firetray.Handler.windows[xid].visibility = false;
firetray.Handler.visibleWindowsCount -= 1;
+ if (firetray.StatusIcon.popupMenuWindowItemsHandled())
+ firetray.StatusIcon.showSinglePopupMenuWindowItem(xid);
firetray.Handler.showHideIcon();
};
--
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