[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