[Pkg-mozext-commits] [firetray] 123/399: * complete per-window registration and show/hide handeling * fix storage of Gdk-/GtkWindows pointers (ctypesMap.jsm)

David Prévot taffit at alioth.debian.org
Tue Oct 29 18:23:26 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 aadf7278161e361e1d85b7ee84011e94e73cc05b
Author: foudfou <foudil.newbie+git at gmail.com>
Date:   Sun Jan 1 01:45:48 2012 +0100

    * complete per-window registration and show/hide handeling
    * fix storage of Gdk-/GtkWindows pointers (ctypesMap.jsm)
---
 src/chrome/content/overlay.js           |   17 +-
 src/install.rdf                         |    2 +-
 src/modules/FiretrayHandler.jsm         |   34 +++-
 src/modules/commons.js                  |    8 +
 src/modules/ctypesMap.jsm               |   68 ++++++++
 src/modules/gtk2/FiretrayStatusIcon.jsm |    1 +
 src/modules/gtk2/FiretrayWindow.jsm     |  291 +++++++++++++++++--------------
 7 files changed, 272 insertions(+), 149 deletions(-)

diff --git a/src/chrome/content/overlay.js b/src/chrome/content/overlay.js
index 72ff241..532b856 100644
--- a/src/chrome/content/overlay.js
+++ b/src/chrome/content/overlay.js
@@ -24,7 +24,10 @@ var firetrayChrome = {
       return false;
     }
 
+    LOG("Handler initialized: "+firetray.Handler.initialized);
     let init = firetray.Handler.initialized || firetray.Handler.init();
+
+    LOG("ONLOAD"); firetray.Handler.dumpWindows();
     firetray.Handler.registerWindow(win);
 
     // update unread messages count
@@ -55,15 +58,19 @@ var firetrayChrome = {
   // TODO: prevent preceding warning about closing multiple tabs (browser.tabs.warnOnClose)
   onClose: function(event) {
     LOG('Firetray CLOSE');
+    let win = event.originalTarget;
+    if (!win instanceof ChromeWindow)
+      throw new TypeError('originalTarget not a ChromeWindow');
+
     let hides_on_close = firetray.Utils.prefService.getBoolPref('hides_on_close');
     let hides_single_window = firetray.Utils.prefService.getBoolPref('hides_single_window');
     LOG('hides_on_close: '+hides_on_close+', hides_single_window='+hides_single_window);
-    LOG('event.originalTarget: '+event.originalTarget);
     if (hides_on_close) {
-      if (hides_single_window)
-        firetray.Window.hideWindow(window);
-      else
-        firetray.Handler.hideAllWindows(window);
+      if (hides_single_window) {
+        let winId = firetray.Handler.getWindowIdFromChromeWindow(win);
+        firetray.Handler.hideSingleWindow(winId);
+      } else
+        firetray.Handler.hideAllWindows();
       event && event.preventDefault(); // no event when called directly (xul)
     }
   },
diff --git a/src/install.rdf b/src/install.rdf
index 23cfd80..cc219c0 100644
--- a/src/install.rdf
+++ b/src/install.rdf
@@ -5,7 +5,7 @@
     <em:unpack>true</em:unpack> <!-- needed for embedded icons -->
     <em:type>2</em:type>
     <em:name>FireTray</em:name>
-    <em:version>0.4.0a5</em:version>
+    <em:version>0.4.0a6</em:version>
     <em:creator>Hua Luo, Francesco Solero, Foudil BRÉTEL</em:creator>
     <em:contributor>Hua Luo, Francesco Solero (Firetray original authors)</em:contributor>
     <em:homepageURL>https://github.com/foudfou/firetray</em:homepageURL>
diff --git a/src/modules/FiretrayHandler.jsm b/src/modules/FiretrayHandler.jsm
index c061b4c..69e387b 100644
--- a/src/modules/FiretrayHandler.jsm
+++ b/src/modules/FiretrayHandler.jsm
@@ -20,7 +20,7 @@ if ("undefined" == typeof(firetray)) {
 };
 
 /**
- * Singleton object and abstraction for tray icon management.
+ * Singleton object and abstraction for windows and tray icon management.
  */
 // NOTE: modules work outside of the window scope. Unlike scripts in the
 // chrome, modules don't have access to objects such as window, document, or
@@ -35,7 +35,9 @@ firetray.Handler = {
   FILENAME_NEWMAIL: null,
   runtimeOS: null,
   inMailApp: false,
-  windows: [],
+  windows: {},
+  windowsCount: 0,
+  visibleWindowsCount: 0,
 
   init: function() {            // does creates icon
     this.appName = Services.appinfo.name.toLowerCase();
@@ -58,17 +60,16 @@ firetray.Handler = {
       LOG('FiretrayStatusIcon imported');
       Cu.import("resource://firetray/gtk2/FiretrayWindow.jsm");
       LOG('FiretrayWindow imported');
-
-      // instanciate tray icon
-      firetray.StatusIcon.init();
-      LOG('StatusIcon initialized');
-
       break;
     default:
       ERROR("FIRETRAY: only Linux platform supported at this time. Firetray not loaded");
       return false;
     }
 
+    // instanciate tray icon
+    firetray.StatusIcon.init();
+    LOG('StatusIcon initialized');
+
     // check if in mail app
     var mozAppId = Services.appinfo.ID;
     if (mozAppId === THUNDERBIRD_ID || mozAppId === SEAMONKEY_ID) {
@@ -107,15 +108,30 @@ firetray.Handler = {
     return true;
   },
 
-  // these get overridden in OS-specific Icon handlers
+  // these get overridden in OS-specific Window handlers
   setImage: function(filename) {},
   setImageDefault: function() {},
   setText: function(text, color) {},
   setTooltip: function(localizedMessage) {},
   setTooltipDefault: function() {},
-  showHideAllWindows: function() {},
   registerWindow: function(win) {},
   unregisterWindow: function(win) {},
+  getWindowIdFromChromeWindow: function(win) {},
+  hideSingleWindow: function(winId) {},
+  showSingleWindow: function(winId) {},
+  showHideAllWindows: function() {},
+
+  showAllWindows: function() {
+    for (let winId in firetray.Handler.windows)
+      if (!firetray.Handler.windows[winId].visibility)
+        firetray.Handler.showSingleWindow(winId);
+  },
+  hideAllWindows: function() {
+    for (let winId in firetray.Handler.windows) {
+      if (firetray.Handler.windows[winId].visibility)
+        firetray.Handler.hideSingleWindow(winId);
+    }
+  },
 
   _getBaseOrXULWindowFromDOMWindow: function(win, winType) {
     let winInterface, winOut;
diff --git a/src/modules/commons.js b/src/modules/commons.js
index 3fe7372..28ff8a5 100644
--- a/src/modules/commons.js
+++ b/src/modules/commons.js
@@ -198,3 +198,11 @@ function isEmpty(obj) {
 function strEquals(obj1, obj2) {
   return obj1.toString() === obj2.toString();
 }
+
+// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Custom_Error_Types
+function DeleteError(message) {
+    this.name = "DeleteError";
+    this.message = message || "Could not delete object memeber";
+}
+DeleteError.prototype = new Error();
+DeleteError.prototype.constructor = DeleteError;
diff --git a/src/modules/ctypesMap.jsm b/src/modules/ctypesMap.jsm
new file mode 100644
index 0000000..6fc430c
--- /dev/null
+++ b/src/modules/ctypesMap.jsm
@@ -0,0 +1,68 @@
+/* -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+
+var EXPORTED_SYMBOLS = [ "ctypesMap", "CTYPES_ARRAY_MAX_SIZE" ];
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
+Cu.import("resource://gre/modules/ctypes.jsm");
+Cu.import("resource://firetray/logging.jsm");
+Cu.import("resource://firetray/commons.js");
+
+const FIRETRAY_WINDOW_COUNT_MAX = 64;
+
+/**
+ * basic Hash mapping a key (of any type) to a cell in a ctypes array
+ */
+function ctypesMap(t) {
+  this.array = ctypes.ArrayType(t)(FIRETRAY_WINDOW_COUNT_MAX);
+  this.indexLast = -1;
+  this.freedCells = [];         // indices of freed cells
+  this.count = 0;               // count of actually stored things
+  this.map = {};                // map key -> index
+};
+
+ctypesMap.prototype.get = function(key) {
+  if (!this.map.hasOwnProperty(key))
+      throw new RangeError('Unknown key: '+key);
+
+  return this.array[this.map[key]];
+};
+
+ctypesMap.prototype.insert = function(key, item) {
+  if (this.map.hasOwnProperty(key)) { // replace
+    LOG("REPLACE");
+    this.array[this.map[key]] = item;
+
+  } else if (this.freedCells.length) {
+    LOG("USE FREE CELL");
+    let idx = this.freedCells.shift();
+    this.array[idx] = item;
+    this.map[key] = idx;
+    this.count += 1;
+
+  } else {
+    let indexNext = this.indexLast + 1;
+    if (indexNext >= FIRETRAY_WINDOW_COUNT_MAX)
+      throw new RangeError('Array overflow');
+
+    this.indexLast = indexNext;
+    this.array[this.indexLast] = item;
+    this.map[key] = this.indexLast;
+    this.count += 1;
+  }
+};
+
+ctypesMap.prototype.remove = function(key) {
+  if (!this.map.hasOwnProperty(key))
+      throw new RangeError('Unknown key: '+key);
+  LOG("FREE CELL");
+
+  let idx = this.map[key];
+  if (!delete this.map[key])
+    throw new DeleteError();
+  this.freedCells.unshift(idx);
+  this.count -= 1;
+};
+
diff --git a/src/modules/gtk2/FiretrayStatusIcon.jsm b/src/modules/gtk2/FiretrayStatusIcon.jsm
index 30f589d..2428891 100644
--- a/src/modules/gtk2/FiretrayStatusIcon.jsm
+++ b/src/modules/gtk2/FiretrayStatusIcon.jsm
@@ -112,6 +112,7 @@ firetray.StatusIcon = {
 
 }; // firetray.StatusIcon
 
+
 firetray.Handler.setImage = function(filename) {
   if (!firetray.StatusIcon.trayIcon)
     return false;
diff --git a/src/modules/gtk2/FiretrayWindow.jsm b/src/modules/gtk2/FiretrayWindow.jsm
index 325e475..d3278a3 100644
--- a/src/modules/gtk2/FiretrayWindow.jsm
+++ b/src/modules/gtk2/FiretrayWindow.jsm
@@ -16,6 +16,7 @@ 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/ctypesMap.jsm");
 Cu.import("resource://firetray/gobject.jsm");
 Cu.import("resource://firetray/gdk.jsm");
 Cu.import("resource://firetray/gtk.jsm");
@@ -42,95 +43,6 @@ var _find_data_t = ctypes.StructType("_find_data_t", [
 ]);
 
 
-firetray.Handler.registerWindow = function(win) {
-  LOG("register window");
-  let that = this;
-
-  // register
-  let [gtkWin, gdkWin, xid] = firetray.Window.getWindowsFromChromeWindow(win);
-  this.windows[xid] = {};
-  this.windows[xid].win = win;
-  this.windows[xid].gtkWin = gtkWin;
-  this.windows[xid].gdkWin = gdkWin;
-  LOG("window "+xid+" registered");
-  /* NOTE: it should not be necessary to gtk_widget_add_events(gtkWin,
-   gdk.GDK_ALL_EVENTS_MASK); */
-
-  try {
-    /* NOTE: we could try to catch the "delete-event" here and block
-       delete_event_cb (in gtk2/nsWindow.cpp), but we prefer to use the
-       provided "close" JS event */
-
-    /* we'll catch minimize events with Gtk:
-     http://stackoverflow.com/questions/8018328/what-is-the-gtk-event-called-when-a-window-minimizes */
-    this.windows[xid].windowStateCb = gtk.GCallbackWindowStateEvent_t(firetray.Window.windowState);
-    this.windows[xid].windowStateCbId = gobject.g_signal_connect(gtkWin, "window-state-event", this.windows[xid].windowStateCb, null);
-    LOG("g_connect window-state-event="+this.windows[xid].windowStateCbId);
-
-  } catch (x) {
-    this._unregisterWindowByXID(xid);
-    ERROR(x);
-    return false;
-  }
-
-  return true;
-};
-
-firetray.Handler.unregisterWindow = function(win) {
-  LOG("unregister window");
-
-  try {
-    let xid = firetray.Window.getXIDFromChromeWindow(win);
-    return this._unregisterWindowByXID(xid);
-  } catch (x) {
-    ERROR(x);
-  }
-  return false;
-};
-
-firetray.Handler._unregisterWindowByXID = function(xid) {
-  try {
-    if (this.windows.hasOwnProperty(xid))
-      delete this.windows[xid];
-    else {
-      ERROR("can't unregister unknown window "+xid);
-      return false;
-    }
-  } catch (x) {
-    ERROR(x);
-    return false;
-  }
-  LOG("window "+xid+" unregistered");
-  return true;
-};
-
-firetray.Handler.showSingleWindow = function(xid) {
-    try {
-      // keep z-order - and try to restore previous state
-      LOG("gdkWin="+firetray.Handler.windows[xid].gdkWin);
-      gdk.gdk_window_show_unraised(firetray.Handler.windows[xid].gdkWin);
-      // need to restore *after* showing for correction
-      // firetray.Window._restoreWindowPositionSizeState(xid);
-    } catch (x) {
-      ERROR(x);
-    }
-};
-
-firetray.Handler.showHideAllWindows = function(gtkStatusIcon, userData) {
-  LOG("showHideAllWindows: "+userData);
-
-  // NOTE: showHideAllWindows being a callback, we need to use 'firetray.Handler'
-  // explicitely instead of 'this'
-  for (let xid in firetray.Handler.windows) {
-    LOG("show xid="+xid);
-    firetray.Handler.showSingleWindow(xid);
-  }
-
-  let stopPropagation = true;
-  return stopPropagation;
-};
-
-
 firetray.Window = {
 
   /**
@@ -143,9 +55,9 @@ firetray.Window = {
    */
   getGtkWindowHandle: function(window) {
     let baseWindow = window
-      .QueryInterface(Ci.nsIInterfaceRequestor)
-      .getInterface(Ci.nsIWebNavigation)
-      .QueryInterface(Ci.nsIBaseWindow);
+          .QueryInterface(Ci.nsIInterfaceRequestor)
+          .getInterface(Ci.nsIWebNavigation)
+          .QueryInterface(Ci.nsIBaseWindow);
 
     // Tag the base window
     let oldTitle = baseWindow.title;
@@ -194,14 +106,10 @@ firetray.Window = {
     let gtkWin = ctypes.cast(gtkWidget, gtk.GtkWindow.ptr);
     let winTitle = gtk.gtk_window_get_title(gtkWin);
 
-    try {
-      if (!winTitle.isNull()) {
-        LOG(inTitle+" = "+winTitle);
-        if (libc.strcmp(inTitle, winTitle) == 0)
-          data.contents.outWindow = gtkWin;
-      }
-    } catch (x) {
-      ERROR(x);
+    if (!winTitle.isNull()) {
+      LOG(inTitle+" = "+winTitle);
+      if (libc.strcmp(inTitle, winTitle) == 0)
+        data.contents.outWindow = gtkWin;
     }
   },
 
@@ -232,9 +140,7 @@ firetray.Window = {
   /** consider using getXIDFromChromeWindow() if you only need the XID */
   getWindowsFromChromeWindow: function(win) {
     let gtkWin = firetray.Window.getGtkWindowHandle(win);
-    LOG("gtkWin="+gtkWin);
     let gdkWin = firetray.Window.getGdkWindowFromGtkWindow(gtkWin);
-    LOG("gdkWin="+gdkWin);
     let xid = firetray.Window.getXIDFromGdkWindow(gdkWin);
     LOG("XID="+xid);
     return [gtkWin, gdkWin, xid];
@@ -248,33 +154,17 @@ firetray.Window = {
     return null;
   },
 
-  hideWindow: function(win) {
-    LOG("hideWindow");
-    let xid = this.getXIDFromChromeWindow(win);
-    LOG("found xid="+xid);
-    try {
-      firetray.Window._saveWindowPositionSizeState(xid);
-
-      // hide window - NOTE: we don't use BaseWindow.visibility to have full
-      // control
-      gdk.gdk_window_hide(firetray.Handler.windows[xid].gdkWin);
-    } catch (x) {
-      ERROR(x);
-    }
-  },
-
-  _saveWindowPositionSizeState: function(xid) {
-    let gdkWin = firetray.Handler.windows[xid].gdkWin;
+  saveWindowPositionSizeState: function(xid) {
+    let gtkWin = firetray.Handler.gtkWindows.get(xid);
+    let gdkWin = firetray.Handler.gdkWindows.get(xid);
 
     try {
       let gx = new gobject.gint; let gy = new gobject.gint;
-      // gtk.gtk_window_get_position(gtkWin, gx.address(), gy.address());
-      gdk.gdk_window_get_position(gdkWin, gx.address(), gy.address());
+      gtk.gtk_window_get_position(gtkWin, gx.address(), gy.address());
       let gwidth = new gobject.gint; let gheight = new gobject.gint;
-      // gtk.gtk_window_get_size(gtkWin, gwidth.address(), gheight.address());
-      gdk.gdk_drawable_get_size(ctypes.cast(gdkWin, gdk.GdkDrawable.ptr), gwidth.address(), gheight.address());
-      let windowState  = gdk.gdk_window_get_state(firetray.Handler.windows[xid].gdkWin);
-      LOG("gx="+gx+", gy="+gy+", gwidth="+gwidth+", gheight="+gheight+", windowState="+windowState);
+      gtk.gtk_window_get_size(gtkWin, gwidth.address(), gheight.address());
+      let windowState  = gdk.gdk_window_get_state(gdkWin);
+      LOG("save: gx="+gx+", gy="+gy+", gwidth="+gwidth+", gheight="+gheight+", windowState="+windowState);
       firetray.Handler.windows[xid].savedX = gx;
       firetray.Handler.windows[xid].savedY = gy;
       firetray.Handler.windows[xid].savedWidth = gwidth;
@@ -286,25 +176,29 @@ firetray.Window = {
 
   },
 
-  _restoreWindowPositionSizeState: function(xid) {
-    let gdkWin = firetray.Handler.windows[xid].gdkWin;
+  restoreWindowPositionSizeState: function(xid) {
     if (!firetray.Handler.windows[xid].savedX)
       return; // windows[xid].saved* may not be initialized
 
-    LOG("restore gdkWin: "+gdkWin+", x="+firetray.Handler.windows[xid].savedX+", y="+firetray.Handler.windows[xid].savedY+", w="+firetray.Handler.windows[xid].savedWidth+", h="+firetray.Handler.windows[xid].savedHeight);
+    let gtkWin = firetray.Handler.gtkWindows.get(xid);
+    let gdkWin = firetray.Handler.gdkWindows.get(xid);
+
+    LOG("restore: x="+firetray.Handler.windows[xid].savedX+", y="+firetray.Handler.windows[xid].savedY+", w="+firetray.Handler.windows[xid].savedWidth+", h="+firetray.Handler.windows[xid].savedHeight);
+    // NOTE: unfortunately, this is the best way I found *inside GTK* to
+    // restore position and size: gdk.gdk_window_move_resize doesn't work
+    // well. And unfortunately, we need to show the window before restoring
+    // position and size :-( TODO: Might be worth trying with x11 or
+    // BaseWindow.visibility ?
     try {
-      gdk.gdk_window_move_resize(gdkWin,
-                                 firetray.Handler.windows[xid].savedX,
-                                 firetray.Handler.windows[xid].savedY,
-                                 firetray.Handler.windows[xid].savedWidth,
-                                 firetray.Handler.windows[xid].savedHeight);
+      gtk.gtk_window_move(gtkWin, firetray.Handler.windows[xid].savedX, firetray.Handler.windows[xid].savedY);
+      gtk.gtk_window_resize(gtkWin, firetray.Handler.windows[xid].savedWidth, firetray.Handler.windows[xid].savedHeight);
       // firetray.Handler.windows[xid].savedState
     } catch (x) {
       ERROR(x);
     }
   },
 
-  windowState: function(gtkWidget, gdkEventState, userData){
+  onWindowState: function(gtkWidget, gdkEventState, userData){
     // LOG("window-state-event");
     // if(event->new_window_state & GDK_WINDOW_STATE_ICONIFIED){
     let stopPropagation = true;
@@ -312,3 +206,132 @@ firetray.Window = {
   }
 
 }; // 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),
+
+/** debug facility */
+firetray.Handler.dumpWindows = function() {
+  LOG(firetray.Handler.windowsCount);
+  for (let winId in firetray.Handler.windows)
+    LOG(winId+"="+firetray.Handler.gtkWindows.get(winId));
+};
+
+firetray.Handler.registerWindow = function(win) {
+  LOG("register window");
+
+  // register
+  let [gtkWin, gdkWin, xid] = firetray.Window.getWindowsFromChromeWindow(win);
+  this.windows[xid] = {};
+  this.windows[xid].win = win;
+  this.gtkWindows.insert(xid, gtkWin);
+  this.gdkWindows.insert(xid, gdkWin);
+  this.windowsCount += 1;
+  this.visibleWindowsCount += 1;
+  this.windows[xid].visibility = true;
+  LOG("window "+xid+" registered");
+  /* NOTE: it should not be necessary to gtk_widget_add_events(gtkWin,
+   gdk.GDK_ALL_EVENTS_MASK); */
+
+  try {
+    /* NOTE: we could try to catch the "delete-event" here and block
+       delete_event_cb (in gtk2/nsWindow.cpp), but we prefer to use the
+       provided 'close' JS event */
+
+    /* we'll catch minimize events with Gtk:
+     http://stackoverflow.com/questions/8018328/what-is-the-gtk-event-called-when-a-window-minimizes */
+    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);
+
+  } catch (x) {
+    this._unregisterWindowByXID(xid);
+    ERROR(x);
+    return false;
+  }
+
+  LOG("AFTER"); firetray.Handler.dumpWindows();
+
+  return true;
+};
+
+firetray.Handler._unregisterWindowByXID = function(xid) {
+  this.windowsCount -= 1;
+  if (this.windows[xid].visibility) this.visibleWindowsCount -= 1;
+  if (this.windows.hasOwnProperty(xid)) {
+    if (!delete this.windows[xid])
+      throw new DeleteError();
+    this.gtkWindows.remove(xid);
+    this.gdkWindows.remove(xid);
+  } else {
+    ERROR("can't unregister unknown window "+xid);
+    return false;
+  }
+  LOG("window "+xid+" unregistered");
+  return true;
+};
+
+firetray.Handler.unregisterWindow = function(win) {
+  LOG("unregister window");
+
+  try {
+    let xid = firetray.Window.getXIDFromChromeWindow(win);
+    return this._unregisterWindowByXID(xid);
+  } catch (x) {
+    ERROR(x);
+  }
+  return false;
+};
+
+firetray.Handler.getWindowIdFromChromeWindow = firetray.Window.getXIDFromChromeWindow;
+
+firetray.Handler.showSingleWindow = function(xid) {
+  LOG("show xid="+xid);
+  try {
+    // try to restore previous state. TODO: z-order respected ?
+    gdk.gdk_window_show_unraised(firetray.Handler.gdkWindows.get(xid));
+    // need to restore *after* showing for correctness
+    firetray.Window.restoreWindowPositionSizeState(xid);
+  } catch (x) {
+    ERROR(x);
+  }
+  firetray.Handler.windows[xid].visibility = true;
+  firetray.Handler.visibleWindowsCount += 1;
+};
+
+firetray.Handler.hideSingleWindow = function(xid) {
+  LOG("hideSingleWindow");
+  try {
+    firetray.Window.saveWindowPositionSizeState(xid);
+    // NOTE: we don't use BaseWindow.visibility to have full control
+    gdk.gdk_window_hide(firetray.Handler.gdkWindows.get(xid));
+  } catch (x) {
+    ERROR(x);
+  }
+  firetray.Handler.windows[xid].visibility = false;
+  firetray.Handler.visibleWindowsCount -= 1;
+};
+
+firetray.Handler.showHideAllWindows = function(gtkStatusIcon, userData) {
+  LOG("showHideAllWindows: "+userData);
+  // NOTE: showHideAllWindows being a callback, we need to use
+  // 'firetray.Handler' explicitely instead of 'this'
+
+  LOG("visibleWindowsCount="+firetray.Handler.visibleWindowsCount);
+  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
+    firetray.Handler.showAllWindows();
+
+  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