[Pkg-mozext-commits] [firetray] 66/84: * Improve start_hidden on winnt: window not shown at all. * Fix minimize on WM_SYSCOMMAND.

David Prévot taffit at moszumanska.debian.org
Sun Jul 20 01:42:47 UTC 2014


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository firetray.

commit 0dd01042ccf298f5dd507c5151923d605ab5319e
Author: foudfou <foudil.newbie+git at gmail.com>
Date:   Thu May 29 23:14:49 2014 +0200

    * Improve start_hidden on winnt: window not shown at all.
    * Fix minimize on WM_SYSCOMMAND.
    
    Before this improvement, we noticed windows showed at startup despite
    start_hidden, shortly after XP boot up. Was this due to the use of hooks ?
---
 src/modules/ctypes/ctypes-utils.jsm     |   1 +
 src/modules/ctypes/winnt/user32.jsm     |  41 ++++++-
 src/modules/ctypes/winnt/win32.jsm      | 125 +++++++++++-----------
 src/modules/winnt/FiretrayPopupMenu.jsm |   9 +-
 src/modules/winnt/FiretrayWindow.jsm    | 182 +++++++++++++++-----------------
 5 files changed, 195 insertions(+), 163 deletions(-)

diff --git a/src/modules/ctypes/ctypes-utils.jsm b/src/modules/ctypes/ctypes-utils.jsm
index b9a8c66..4142aaf 100644
--- a/src/modules/ctypes/ctypes-utils.jsm
+++ b/src/modules/ctypes/ctypes-utils.jsm
@@ -50,6 +50,7 @@ const WinABI   = is64bit ? ctypes.default_abi : ctypes.winapi_abi;
 const WinCbABI = is64bit ? ctypes.default_abi : ctypes.stdcall_abi;
 
 let log = firetray.Logging.getLogger("firetray.ctypes-utils");
+log.info("is64bit="+is64bit);
 
 /**
  * Loads a library using ctypes and exports an object on to the specified
diff --git a/src/modules/ctypes/winnt/user32.jsm b/src/modules/ctypes/winnt/user32.jsm
index 103a68f..054f262 100644
--- a/src/modules/ctypes/winnt/user32.jsm
+++ b/src/modules/ctypes/winnt/user32.jsm
@@ -32,6 +32,7 @@ function user32_defines(lib) {
   lib.lazy_bind("GetWindowTextW", ctypes.int, win32.HWND, win32.LPTSTR, ctypes.int);
   lib.lazy_bind("FindWindowW", win32.HWND, win32.LPCTSTR, win32.LPCTSTR);
 
+  lib.lazy_bind("PostMessageW", win32.BOOL, win32.HWND, win32.UINT, win32.WPARAM, win32.LPARAM);
   lib.lazy_bind("SendMessageW", win32.LRESULT, win32.HWND, win32.UINT, win32.WPARAM, win32.LPARAM);
   this.WM_GETICON = 0x007F;
   this.WM_SETICON = 0x0080;
@@ -95,8 +96,7 @@ function user32_defines(lib) {
     WinCbABI, win32.LRESULT,
     [win32.HWND, win32.UINT, win32.WPARAM, win32.LPARAM]).ptr;
 
-  // lib.lazy_bind("CallWindowProcW", win32.LRESULT, this.WNDPROC, win32.HWND, win32.UINT, win32.WPARAM, win32.LPARAM);
-  lib.lazy_bind("CallWindowProcW", win32.LRESULT, ctypes.voidptr_t, win32.HWND, win32.UINT, win32.WPARAM, win32.LPARAM);
+  lib.lazy_bind("CallWindowProcW", win32.LRESULT, this.WNDPROC, win32.HWND, win32.UINT, win32.WPARAM, win32.LPARAM);
   lib.lazy_bind("DefWindowProcW", win32.LRESULT, win32.HWND, win32.UINT, win32.WPARAM, win32.LPARAM);
 
   this.WNDCLASSEXW = ctypes.StructType("WNDCLASSEXW", [
@@ -186,6 +186,16 @@ function user32_defines(lib) {
     { "hwnd": win32.HWND }
   ]);
 
+  this.MSG = ctypes.StructType("MSG", [
+   { "hwnd": win32.HWND },
+   { "message": win32.UINT },
+   { "wParam": win32.WPARAM },
+   { "lParam": win32.LPARAM },
+   { "time": win32.DWORD },
+   { "pt": win32.POINT }
+  ]);
+  this.PMSG = this.MSG.ptr;
+
   this.HOOKPROC = ctypes.FunctionType(
     WinCbABI, win32.LRESULT,
     [ctypes.int, win32.WPARAM, win32.LPARAM]).ptr;
@@ -375,6 +385,33 @@ function user32_defines(lib) {
   lib.lazy_bind("GetWindowPlacement", win32.BOOL, win32.HWND, this.WINDOWPLACEMENT.ptr);
   lib.lazy_bind("SetWindowPlacement", win32.BOOL, win32.HWND, this.WINDOWPLACEMENT.ptr);
 
+  this.WINDOWPOS = ctypes.StructType("WINDOWPOS", [
+   { "hwnd": win32.HWND },
+   { "hwndInsertAfter": win32.HWND },
+   { "x": ctypes.int },
+   { "y": ctypes.int },
+   { "cx": ctypes.int },
+   { "cy": ctypes.int },
+   { "flags": win32.UINT }
+  ]);
+  this.PWINDOWPOS = this.WINDOWPOS;
+
+  this.SWP_NOSIZE         = 0x0001;
+  this.SWP_NOMOVE         = 0x0002;
+  this.SWP_NOZORDER       = 0x0004;
+  this.SWP_NOREDRAW       = 0x0008;
+  this.SWP_NOACTIVATE     = 0x0010;
+  this.SWP_FRAMECHANGED   = 0x0020;  /* The frame changed: send WM_NCCALCSIZ= */
+  this.SWP_SHOWWINDOW     = 0x0040;
+  this.SWP_HIDEWINDOW     = 0x0080;
+  this.SWP_NOCOPYBITS     = 0x0100;
+  this.SWP_NOOWNERZORDER  = 0x0200;  /* Don't do owner Z orderin= */
+  this.SWP_NOSENDCHANGING = 0x0400;  /* Don't send WM_WINDOWPOSCHANGIN= */
+  this.SWP_DRAWFRAME      = this.SWP_FRAMECHANGED;
+  this.SWP_NOREPOSITION   = this.SWP_NOOWNERZORDER;
+  this.SWP_DEFERERASE     = 0x2000;
+  this.SWP_ASYNCWINDOWPOS = 0x4000;
+
 }
 
 new ctypes_library(USER32_LIBNAME, USER32_ABIS, user32_defines, this);
diff --git a/src/modules/ctypes/winnt/win32.jsm b/src/modules/ctypes/winnt/win32.jsm
index 15b57d6..ca5e17b 100644
--- a/src/modules/ctypes/winnt/win32.jsm
+++ b/src/modules/ctypes/winnt/win32.jsm
@@ -97,67 +97,70 @@ var win32 = new function() {
   this.ERROR_RESOURCE_TYPE_NOT_FOUND = 1813;
 
   // WinUser.h
-  this.WM_NULL           = 0x0000;
-  this.WM_CREATE         = 0x0001;
-  this.WM_DESTROY        = 0x0002;
-  this.WM_MOVE           = 0x0003;
-  this.WM_SIZE           = 0x0005;
-  this.WM_ACTIVATE       = 0x0006;
-  this.WA_INACTIVE       = 0;
-  this.WA_ACTIVE         = 1;
-  this.WA_CLICKACTIVE    = 2;
-  this.WM_SETFOCUS       = 0x0007;
-  this.WM_KILLFOCUS      = 0x0008;
-  this.WM_ENABLE         = 0x000A;
-  this.WM_SETREDRAW      = 0x000B;
-  this.WM_SETTEXT        = 0x000C;
-  this.WM_GETTEXT        = 0x000D;
-  this.WM_GETTEXTLENGTH  = 0x000E;
-  this.WM_PAINT          = 0x000F;
-  this.WM_CLOSE          = 0x0010;
-  this.WM_QUIT           = 0x0012;
-  this.WM_ERASEBKGND     = 0x0014;
-  this.WM_SYSCOLORCHANGE = 0x0015;
-  this.WM_SHOWWINDOW     = 0x0018;
-  this.WM_WININICHANGE   = 0x001A;
-  this.WM_SETTINGCHANGE  = this.WM_WININICHANGE;
-  this.WM_DEVMODECHANGE  = 0x001B;
-  this.WM_ACTIVATEAPP    = 0x001C;
-  this.WM_FONTCHANGE     = 0x001D;
-  this.WM_TIMECHANGE     = 0x001E;
-  this.WM_CANCELMODE     = 0x001F;
-  this.WM_SETCURSOR      = 0x0020;
-  this.WM_MOUSEACTIVATE  = 0x0021;
-  this.WM_CHILDACTIVATE  = 0x0022;
-  this.WM_QUEUESYNC      = 0x0023;
-  this.WM_COMMAND        = 0x0111;
-  this.WM_SYSCOMMAND     = 0x0112;
-  this.WM_HSCROLL        = 0x0114;
-  this.WM_VSCROLL        = 0x0115;
-  this.WM_MOUSEWHEEL     = 0x020A;
-
-  this.WM_USER           = 0x0400;
-  this.WM_APP            = 0x8000;
-
-  this.WM_CONTEXTMENU    = 0x007B;
-
-  this.WM_MOUSEFIRST     = 0x0200;
-  this.WM_MOUSEMOVE      = 0x0200;
-  this.WM_LBUTTONDOWN    = 0x0201;
-  this.WM_LBUTTONUP      = 0x0202;
-  this.WM_LBUTTONDBLCLK  = 0x0203;
-  this.WM_RBUTTONDOWN    = 0x0204;
-  this.WM_RBUTTONUP      = 0x0205;
-  this.WM_RBUTTONDBLCLK  = 0x0206;
-  this.WM_MBUTTONDOWN    = 0x0207;
-  this.WM_MBUTTONUP      = 0x0208;
-  this.WM_MBUTTONDBLCLK  = 0x0209;
-  this.WM_MOUSEWHEEL     = 0x020A;
-  this.WM_XBUTTONDOWN    = 0x020B;
-  this.WM_XBUTTONUP      = 0x020C;
-  this.WM_XBUTTONDBLCLK  = 0x020D;
-  this.WM_MOUSELAST      = 0x020D;
-  this.WM_MOUSELAST      = 0x020A;
+  this.WM_NULL              = 0x0000;
+  this.WM_CREATE            = 0x0001;
+  this.WM_DESTROY           = 0x0002;
+  this.WM_MOVE              = 0x0003;
+  this.WM_SIZE              = 0x0005;
+  this.WM_ACTIVATE          = 0x0006;
+  this.WA_INACTIVE          = 0;
+  this.WA_ACTIVE            = 1;
+  this.WA_CLICKACTIVE       = 2;
+  this.WM_SETFOCUS          = 0x0007;
+  this.WM_KILLFOCUS         = 0x0008;
+  this.WM_ENABLE            = 0x000A;
+  this.WM_SETREDRAW         = 0x000B;
+  this.WM_SETTEXT           = 0x000C;
+  this.WM_GETTEXT           = 0x000D;
+  this.WM_GETTEXTLENGTH     = 0x000E;
+  this.WM_PAINT             = 0x000F;
+  this.WM_CLOSE             = 0x0010;
+  this.WM_QUIT              = 0x0012;
+  this.WM_ERASEBKGND        = 0x0014;
+  this.WM_SYSCOLORCHANGE    = 0x0015;
+  this.WM_SHOWWINDOW        = 0x0018;
+  this.WM_WININICHANGE      = 0x001A;
+  this.WM_SETTINGCHANGE     = this.WM_WININICHANGE;
+  this.WM_DEVMODECHANGE     = 0x001B;
+  this.WM_ACTIVATEAPP       = 0x001C;
+  this.WM_FONTCHANGE        = 0x001D;
+  this.WM_TIMECHANGE        = 0x001E;
+  this.WM_CANCELMODE        = 0x001F;
+  this.WM_SETCURSOR         = 0x0020;
+  this.WM_MOUSEACTIVATE     = 0x0021;
+  this.WM_CHILDACTIVATE     = 0x0022;
+  this.WM_QUEUESYNC         = 0x0023;
+  this.WM_WINDOWPOSCHANGING = 0x0046;
+  this.WM_WINDOWPOSCHANGED  = 0x0047;
+  this.WM_INITDIALOG        = 0x0110;
+  this.WM_COMMAND           = 0x0111;
+  this.WM_SYSCOMMAND        = 0x0112;
+  this.WM_HSCROLL           = 0x0114;
+  this.WM_VSCROLL           = 0x0115;
+  this.WM_MOUSEWHEEL        = 0x020A;
+
+  this.WM_USER              = 0x0400;
+  this.WM_APP               = 0x8000;
+
+  this.WM_CONTEXTMENU       = 0x007B;
+
+  this.WM_MOUSEFIRST        = 0x0200;
+  this.WM_MOUSEMOVE         = 0x0200;
+  this.WM_LBUTTONDOWN       = 0x0201;
+  this.WM_LBUTTONUP         = 0x0202;
+  this.WM_LBUTTONDBLCLK     = 0x0203;
+  this.WM_RBUTTONDOWN       = 0x0204;
+  this.WM_RBUTTONUP         = 0x0205;
+  this.WM_RBUTTONDBLCLK     = 0x0206;
+  this.WM_MBUTTONDOWN       = 0x0207;
+  this.WM_MBUTTONUP         = 0x0208;
+  this.WM_MBUTTONDBLCLK     = 0x0209;
+  this.WM_MOUSEWHEEL        = 0x020A;
+  this.WM_XBUTTONDOWN       = 0x020B;
+  this.WM_XBUTTONUP         = 0x020C;
+  this.WM_XBUTTONDBLCLK     = 0x020D;
+  this.WM_MOUSELAST         = 0x020D;
+  this.WM_MOUSELAST         = 0x020A;
 
   this.SC_MINIMIZE = 0xF020;
   this.SC_CLOSE    = 0xF060;
diff --git a/src/modules/winnt/FiretrayPopupMenu.jsm b/src/modules/winnt/FiretrayPopupMenu.jsm
index 0b49b48..43113c4 100644
--- a/src/modules/winnt/FiretrayPopupMenu.jsm
+++ b/src/modules/winnt/FiretrayPopupMenu.jsm
@@ -104,9 +104,12 @@ firetray.PopupMenu = {
                        0, null);
   },
 
-  // FIXME: need to handle hides_single_window=false
-  addWindowItemAndSeparatorMaybe: function(wid) {
-    if (firetray.Handler.visibleWindowsCount === firetray.Handler.windowsCount)
+  /**
+   * @param force: useful to start_hidden, when window is not shown
+   */
+  addWindowItemAndSeparatorMaybe: function(wid, force) {
+    if (typeof force === "undefined") force = false;
+    if (force || firetray.Handler.visibleWindowsCount === firetray.Handler.windowsCount)
       this.insertSeparator();
     this.addWindowItem(wid);
   },
diff --git a/src/modules/winnt/FiretrayWindow.jsm b/src/modules/winnt/FiretrayWindow.jsm
index d4999c7..4ac20d4 100644
--- a/src/modules/winnt/FiretrayWindow.jsm
+++ b/src/modules/winnt/FiretrayWindow.jsm
@@ -26,10 +26,9 @@ const FIRETRAY_XWINDOW_MAXIMIZED = 1 << 1;
 
 // We need to keep long-living references to wndProcs callbacks. As they also
 // happen to be ctypes pointers, we store them into real ctypes arrays.
-firetray.Handler.wndProcs      = new ctypesMap(user32.WNDPROC);
-firetray.Handler.wndProcsOrig  = new ctypesMap(user32.WNDPROC);
-firetray.Handler.procHooks          = new ctypesMap(win32.HHOOK);
-firetray.Handler.procHooksRegistred = new ctypesMap(win32.HHOOK);
+firetray.Handler.wndProcs        = new ctypesMap(win32.LONG_PTR);
+firetray.Handler.wndProcsOrig    = new ctypesMap(win32.LONG_PTR);
+firetray.Handler.wndProcsStartup = new ctypesMap(win32.LONG_PTR);
 
 
 firetray.Window = new FiretrayWindow();
@@ -64,84 +63,69 @@ firetray.Window.wndProc = function(hWnd, uMsg, wParam, lParam) { // filterWindow
     log.debug("wndProc CALLED with WM_SYSCOMMAND wParam="+wParam);
     if (wParam === win32.SC_MINIMIZE) {
       log.debug("GOT ICONIFIED");
-      if (firetray.Handler.hideOnMinimizeMaybe(wid)) {
+      if (firetray.Handler.onMinimize(wid)) {
         return 0;               // processed => preventDefault
       }
     }
   }
 
   let procPrev = firetray.Handler.wndProcsOrig.get(wid);
-  return user32.CallWindowProcW(procPrev, hWnd, uMsg, wParam, lParam); // or DefWindowProcW
+  return user32.CallWindowProcW(user32.WNDPROC(procPrev), hWnd, uMsg, wParam, lParam); // or DefWindowProcW
 };
 
-// We could chain wndProcs, but adding a hook looks simpler.
-firetray.Window.showCount = 0;
-firetray.Window.startupHook = function(nCode, wParam, lParam) { // WH_CALLWNDPROC, WH_GETMESSAGE
-  // log.debug("startupHook CALLED: nCode="+nCode+", wParam="+wParam+", lParam="+lParam);
-  if (nCode < 0) return user32.CallNextHookEx(null, nCode, wParam, lParam); // user32.HC_ACTION
+/*
+ * We get the best effect by intercepting WM_WINDOWPOSCHANGING/SWP_SHOWWINDOW.
+ * Here, we subclass only once either with a startup wndProc, if
+ * start_hidden, or just our default wndProc. None of the following works:
+ * - a WH_CALLWNDPROC hook doesn't catch SWP_SHOWWINDOW
+ * - chaining WNDPROCs crashes the app (UserCallWinProcCheckWow or ffi_call)
+ */
+firetray.Window.startupShowCount = 0;
+firetray.Window.wndProcStartup = function(hWnd, uMsg, wParam, lParam) {
+  let wid = firetray.Win32.hwndToHexStr(hWnd);
 
-  let cwpstruct = ctypes.cast(win32.LPARAM(lParam), user32.CWPSTRUCT.ptr).contents;
-  let uMsg = cwpstruct.message;
-  let hwnd = cwpstruct.hwnd;
-  let wid = firetray.Win32.hwndToHexStr(hwnd);
-  let wparam = cwpstruct.wParam;
-  let lparam = cwpstruct.lParam;
-
-  if (uMsg === win32.WM_SHOWWINDOW && wparam == 1 && lparam == 0) { // shown and ShowWindow called
-    log.debug("startupHook CALLED with WM_SHOWWINDOW wparam="+wparam+" lparam="+lparam);
-    firetray.Window.showCount += 1;
-
-    if (firetray.Utils.prefService.getBoolPref('start_hidden')) {
-      log.debug("start_hidden");
-
-      /* Compared to ShowWindow, SetWindowPlacement seems to bypass window
-       animations. http://stackoverflow.com/a/6087214 */
-      let placement = new user32.WINDOWPLACEMENT;
-      let ret = user32.GetWindowPlacement(hwnd, placement.address());
-      log.debug("  GetWindowPlacement="+ret+" winLastError="+ctypes.winLastError);
-      log.debug("  PLACEMENT="+placement);
-
-      if (firetray.Window.showCount < 2) {
-        // we can't prevent ShowWindow, so we mitigate the effect by minimizing
-        // it before. This is why we'll have to restore it when unhidden.
-        placement.showCmd = user32.SW_SHOWMINNOACTIVE;
-        ret = user32.SetWindowPlacement(hwnd, placement.address());
-        log.debug("  SetWindowPlacement="+ret+" winLastError="+ctypes.winLastError);
-
-        firetray.Utils.timer(
-          FIRETRAY_DELAY_NOWAIT_MILLISECONDS,
-          Ci.nsITimer.TYPE_ONE_SHOT, function(){firetray.Handler.hideWindow(wid);}
-        ); // looks like CData (hwnd) cannot be closured
-
-      } else {                  // restore
-        firetray.Window.detachHook(wid);
-
-        placement.showCmd = user32.SW_RESTORE;
-        user32.SetWindowPlacement(hwnd, placement.address());
+  if (uMsg === win32.WM_WINDOWPOSCHANGING) {
+    let posStruct = ctypes.cast(win32.LPARAM(lParam), user32.WINDOWPOS.ptr).contents;
+    let isShowing = ((posStruct.flags & user32.SWP_SHOWWINDOW) != 0);
+    if (isShowing) {
+      log.debug("wndProcStartup CALLED with WM_WINDOWPOSCHANGING/SWP_SHOWWINDOW");
+      firetray.Window.startupShowCount += 1;
+
+      if (firetray.Window.startupShowCount < 2) {  // hide
+        log.debug("start_hidden");
+        // Modifying a JS posStruct field does really modify the WINDOWPOS C
+        // struct behind lParam !
+        posStruct.flags &= ~user32.SWP_SHOWWINDOW;
+        let force = true;
+        firetray.Handler.addPopupMenuWindowItemAndSeparatorMaybe(wid, force);
+      }
+      else {                    // restore
+        firetray.Window.attachWndProc({
+          wid: wid, hwnd: hWnd,
+          jsProc: firetray.Window.wndProc,
+          mapNew: firetray.Handler.wndProcs,
+          mapBak: null
+        });
+        firetray.Handler.wndProcsStartup.remove(wid);
       }
-
-    } else {
-      firetray.Window.detachHook(wid);
     }
-
   }
 
-  return user32.CallNextHookEx(null, nCode, wParam, lParam);
+  let procPrev = firetray.Handler.wndProcsOrig.get(wid);
+  return user32.CallWindowProcW(user32.WNDPROC(procPrev), hWnd, uMsg, wParam, lParam);
 };
 
-firetray.Window.attachWndProc = function(wid, hwnd) {
+// procInfo = {wid, hwnd, jsProc, mapNew, mapBak}
+firetray.Window.attachWndProc = function(procInfo) {
   try {
-    let wndProc = user32.WNDPROC(firetray.Window.wndProc);
+    let wndProc = ctypes.cast(user32.WNDPROC(procInfo.jsProc), win32.LONG_PTR);
     log.debug("proc="+wndProc);
-    firetray.Handler.wndProcs.insert(wid, wndProc);
-    let procPrev = user32.WNDPROC(
-      user32.SetWindowLongW(hwnd, user32.GWLP_WNDPROC,
-                            ctypes.cast(wndProc, win32.LONG_PTR))
-    );
+    procInfo.mapNew.insert(procInfo.wid, wndProc);
+    let procPrev = user32.SetWindowLongW(procInfo.hwnd, user32.GWLP_WNDPROC, wndProc);
     log.debug("procPrev="+procPrev+" winLastError="+ctypes.winLastError);
     /* we can't store WNDPROC callbacks (JS ctypes objects) with SetPropW(), as
      we need long-living refs. */
-    firetray.Handler.wndProcsOrig.insert(wid, procPrev);
+    if (procInfo.mapBak) procInfo.mapBak.insert(procInfo.wid, procPrev);
 
   } catch (x) {
     if (x.name === "RangeError") { // instanceof not working :-(
@@ -157,40 +141,17 @@ firetray.Window.attachWndProc = function(wid, hwnd) {
   }
 };
 
-firetray.Window.detachWndProc = function(wid) {
-  let procPrev = firetray.Handler.wndProcsOrig.get(wid);
+// procInfo = {wid, mapNew, mapBak}
+firetray.Window.detachWndProc = function(procInfo) {
+  let wid = procInfo.wid;
+  let procPrev = procInfo.mapBak.get(wid);
   let hwnd = firetray.Win32.hexStrToHwnd(wid);
   log.debug("hwnd="+hwnd);
-  let proc = user32.WNDPROC(
-    user32.SetWindowLongW(hwnd, user32.GWLP_WNDPROC,
-                          ctypes.cast(procPrev, win32.LONG_PTR))
-  );
-  firetray.js.assert(firetray.js.strEquals(proc, firetray.Handler.wndProcs.get(wid)),
+  let proc = user32.SetWindowLongW(hwnd, user32.GWLP_WNDPROC, procPrev);
+  firetray.js.assert(firetray.js.strEquals(proc, procInfo.mapNew.get(wid)),
                      "Wrong WndProc replaced.");
-  firetray.Handler.wndProcs.remove(wid);
-  firetray.Handler.wndProcsOrig.remove(wid);
-};
-
-firetray.Window.attachHook = function(wid) { // detaches itself alone
-    let startupHook = user32.HOOKPROC(firetray.Window.startupHook);
-    log.debug("callhk="+startupHook);
-    firetray.Handler.procHooks.insert(wid, startupHook);
-    // Global hooks must reside in a dll (hence hInst). This is important for
-    // the scope of variables.
-    let hhook = user32.SetWindowsHookExW(
-      user32.WH_CALLWNDPROC, startupHook, null, kernel32.GetCurrentThreadId());
-    log.debug("  hhook="+hhook+" winLastError="+ctypes.winLastError);
-    firetray.Handler.procHooksRegistred.insert(wid, hhook);
-};
-
-firetray.Window.detachHook = function(wid) { // detaches itself alone
-  let hook = firetray.Handler.procHooksRegistred.get(wid);
-  if (!user32.UnhookWindowsHookEx(hook)) {
-    log.error("UnhookWindowsHookEx for window "+wid+" failed: winLastError="+ctypes.winLastError);
-    return;
-  }
-  firetray.Handler.procHooks.remove(wid);
-  firetray.Handler.procHooksRegistred.remove(wid);
+  procInfo.mapNew.remove(wid);
+  procInfo.mapBak.remove(wid);
 };
 
 
@@ -230,10 +191,19 @@ firetray.Handler.registerWindow = function(win) {
   });
   log.debug("window "+wid+" registered");
 
-  firetray.Window.attachWndProc(wid, hwnd);
-  if (!firetray.Handler.appStarted) {
-    firetray.Window.attachHook(wid);
+  let proc, map;
+  if (!firetray.Handler.appStarted &&
+      firetray.Utils.prefService.getBoolPref('start_hidden')) {
+    proc = firetray.Window.wndProcStartup; map = firetray.Handler.wndProcsStartup;
+  } else {
+    proc = firetray.Window.wndProc; map = firetray.Handler.wndProcs;
   }
+  firetray.Window.attachWndProc({
+    wid: wid, hwnd: hwnd,
+    jsProc: proc,
+    mapNew: map,
+    mapBak: firetray.Handler.wndProcsOrig
+  });
 
   firetray.Win32.acceptAllMessages(hwnd);
 
@@ -250,7 +220,25 @@ firetray.Handler.unregisterWindow = function(win) {
     return false;
   }
 
-  firetray.Window.detachWndProc(wid);
+  try {
+    firetray.Window.detachWndProc({
+      wid: wid,
+      mapNew: firetray.Handler.wndProcsStartup,
+      mapBak: firetray.Handler.wndProcsOrig
+    });
+    log.debug("Window never shown.");
+  } catch (x) {
+    if (x.name === "RangeError") {
+      firetray.Window.detachWndProc({
+        wid: wid,
+        mapNew: firetray.Handler.wndProcs,
+        mapBak: firetray.Handler.wndProcsOrig
+      });
+    } else {
+      log.error(x);
+      Cu.reportError(x);
+    }
+  }
 
   if (!delete firetray.Handler.windows[wid])
     throw new DeleteError();

-- 
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