[Pkg-mozext-commits] [firetray] 15/84: * actually use a WndProc on moz windows * include winnt files to .xpi

David Prévot taffit at moszumanska.debian.org
Sun Jul 20 01:42:42 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 b453b4fa741227c0d1264ff3f9ccc30e038dbda6
Author: foudfou <foudil.newbie+git at gmail.com>
Date:   Sun Jan 19 23:02:23 2014 +0100

    * actually use a WndProc on moz windows
    * include winnt files to .xpi
    
    WndProc crashes, mentioned in bugs 598679 and 671266, were recently fixed by
    915613 (thx bholley!).
---
 src/Makefile                         |   4 +-
 src/modules/commons.js               |   6 ++
 src/modules/ctypes/winnt/user32.jsm  |   1 +
 src/modules/winnt/FiretrayWindow.jsm | 132 +++++++++++++----------------------
 4 files changed, 60 insertions(+), 83 deletions(-)

diff --git a/src/Makefile b/src/Makefile
index 968aa76..6742dc5 100755
--- a/src/Makefile
+++ b/src/Makefile
@@ -111,7 +111,9 @@ modules_sources := $(wildcard $(modules_dir)/*.js)		\
 		$(wildcard $(modules_dir)/*.jsm)		\
 		$(wildcard $(modules_dir)/ctypes/*.jsm)		\
 		$(wildcard $(modules_dir)/ctypes/linux/*.jsm)	\
-		$(wildcard $(modules_dir)/linux/*.jsm)
+		$(wildcard $(modules_dir)/ctypes/winnt/*.jsm)	\
+		$(wildcard $(modules_dir)/linux/*.jsm)		\
+		$(wildcard $(modules_dir)/winnt/*.jsm)
 
 # The components (JSM) dir.
 components_dir := components
diff --git a/src/modules/commons.js b/src/modules/commons.js
index eb6e0c4..cf8697a 100644
--- a/src/modules/commons.js
+++ b/src/modules/commons.js
@@ -291,6 +291,12 @@ firetray.js = {
   // https://developer.mozilla.org/en/js-ctypes/Using_js-ctypes/Working_with_data#Quirks_in_equality
   strEquals: function(obj1, obj2) {
     return obj1.toString() === obj2.toString();
+  },
+
+  assert: function(condition, message) {
+    if (!condition) {
+      throw message || "Assertion failed";
+    }
   }
 };
 
diff --git a/src/modules/ctypes/winnt/user32.jsm b/src/modules/ctypes/winnt/user32.jsm
index f894413..579618b 100644
--- a/src/modules/ctypes/winnt/user32.jsm
+++ b/src/modules/ctypes/winnt/user32.jsm
@@ -59,6 +59,7 @@ function user32_defines(lib) {
 
   lib.lazy_bind("GetPropW", win32.HANDLE, win32.HWND, win32.LPCTSTR);
   lib.lazy_bind("SetPropW", win32.BOOL, win32.HWND, win32.LPCTSTR, win32.HANDLE);
+  lib.lazy_bind("RemovePropW", win32.HANDLE, win32.HWND, win32.LPCTSTR);
 
   lib.lazy_bind("GetWindowLongW", win32.LONG_PTR, win32.HWND, ctypes.int);
   lib.lazy_bind("SetWindowLongW", win32.LONG_PTR , win32.HWND, ctypes.int, win32.LONG_PTR);
diff --git a/src/modules/winnt/FiretrayWindow.jsm b/src/modules/winnt/FiretrayWindow.jsm
index ad6e98d..b84eaab 100644
--- a/src/modules/winnt/FiretrayWindow.jsm
+++ b/src/modules/winnt/FiretrayWindow.jsm
@@ -9,12 +9,11 @@ const Cu = Components.utils;
 Cu.import("resource://gre/modules/ctypes.jsm");
 Cu.import("resource://firetray/ctypes/ctypesMap.jsm");
 Cu.import("resource://firetray/ctypes/winnt/win32.jsm");
-Cu.import("resource://firetray/ctypes/winnt/kernel32.jsm");
 Cu.import("resource://firetray/ctypes/winnt/user32.jsm");
 Cu.import("resource://firetray/winnt/FiretrayWin32.jsm");
 Cu.import("resource://firetray/FiretrayWindow.jsm");
 Cu.import("resource://firetray/commons.js");
-firetray.Handler.subscribeLibsForClosing([kernel32, user32]);
+firetray.Handler.subscribeLibsForClosing([user32]);
 
 let log = firetray.Logging.getLogger("firetray.Window");
 
@@ -24,12 +23,10 @@ if ("undefined" == typeof(firetray.Handler))
 const FIRETRAY_XWINDOW_HIDDEN    = 1 << 0; // when minimized also
 const FIRETRAY_XWINDOW_MAXIMIZED = 1 << 1;
 
-const kPropProcPrev = "_FIRETRAY_OLD_PROC";
-
-// 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.callProcHooks     = new ctypesMap(win32.HHOOK);
+// 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.Window = new FiretrayWindow();
@@ -58,69 +55,38 @@ firetray.Window.setVisibility = function(xid, visibility) {
 };
 
 firetray.Window.wndProc = function(hWnd, uMsg, wParam, lParam) { // filterWindow
-  log.debug("wndProc CALLED: hWnd="+hWnd+", uMsg="+uMsg+", wParam="+wParam+", lParam="+lParam);
+  // log.debug("wndProc CALLED: hWnd="+hWnd+", uMsg="+uMsg+", wParam="+wParam+", lParam="+lParam);
 
-  let proc = user32.GetWindowLongW(hWnd, user32.GWLP_WNDPROC);
-  log.debug("  proc="+proc.toString(16)+" winLastError="+ctypes.winLastError);
+  if (uMsg === firetray.Win32.WM_TRAYMESSAGE) {
+    log.debug("wndProc CALLED with WM_TRAYMESSAGE");
 
-try {
+  } else if (uMsg === firetray.Win32.WM_TRAYMESSAGEFWD) {
+    log.debug("wndProc CALLED with WM_TRAYMESSAGEFWD");
 
-  let wid = firetray.Win32.hwndToHexStr(hWnd);
-  // let procPrev = firetray.Handler.wndProcsOrig.get(wid);
-  // let procPrev = ctypes.cast(user32.GetPropW(hWnd, win32._T(kPropProcPrev)), user32.WNDPROC);
-  // let procPrev = user32.GetPropW(hWnd, win32._T(kPropProcPrev));
-  log.debug("  wid="+wid+" prev="+procPrev);
-
-  // let rv = user32.CallWindowProcW(procPrev, hWnd, uMsg, wParam, lParam);
-  let rv = procPrev(hWnd, uMsg, wParam, lParam);
-  log.debug("  CallWindowProc="+rv);
-  return rv;
-
-  } catch(error) {
-log.error(error);
+  } else if (uMsg === win32.WM_USER) {
+    log.debug("wndProc CALLED with WM_USER");
   }
 
-  // user32.SetWindowLongW(hWnd, user32.GWLP_WNDPROC, ctypes.cast(procPrev, win32.LONG_PTR));
-
-  // if (uMsg === win32.WM_USER) {
-  //   log.debug("wndProc CALLED: hWnd="+hWnd+", uMsg="+uMsg+", wParam="+wParam+", lParam="+lParam);
-
-  //   // return user32.DefWindowProcW(hWnd, uMsg, wParam, lParam);
-  // }
-
-  // return user32.DefWindowProcW(hWnd, uMsg, wParam, lParam);
+  let wid = firetray.Win32.hwndToHexStr(hWnd);
+  let procPrev = firetray.Handler.wndProcsOrig.get(wid);
+  return user32.CallWindowProcW(procPrev, hWnd, uMsg, wParam, lParam);
 };
 
-firetray.Window.callProcHook = function(nCode, wParam, lParam) { // WH_CALLWNDPROC, WH_GETMESSAGE
-  // log.debug("callProcHook CALLED: nCode="+nCode+", wParam="+wParam+", lParam="+lParam);
-  let cwpstruct = ctypes.cast(win32.LPARAM(lParam), user32.CWPSTRUCT.ptr).contents;
-  let uMsg = cwpstruct.message;
-
-  if (uMsg === firetray.Win32.WM_TRAYMESSAGEFWD) {
-    log.debug("WM_TRAYMESSAGEFWD received!");
-
-    if (wParam != 0) {
-      log.debug("message was sent by the current thread");
-    }
-
-    let hWnd = cwpstruct.hwnd;
-    log.debug("hWnd="+hWnd);
-    let wid = firetray.Win32.hwndToHexStr(hWnd);
-    log.debug("wid="+wid);
-
-    if (nCode === user32.HC_ACTION) {
-      log.warn("*** must process the message ***");
-    } else if (nCode < 0) {
-      log.warn("*** must pass the message to the CallNextHookEx function without further processing ***");
-    }
-
-  }
-
-  return user32.CallNextHookEx(null, nCode, wParam, lParam);
+firetray.Window.restoreWndProc = function(wid) {
+  let procPrev = firetray.Handler.wndProcsOrig.get(wid);
+  let hwnd = new win32.HWND(ctypes.UInt64(wid));
+  log.debug("hwnd="+hwnd);
+  let proc = user32.WNDPROC(
+    user32.SetWindowLongW(hwnd, user32.GWLP_WNDPROC,
+                          ctypes.cast(procPrev, win32.LONG_PTR))
+  );
+  firetray.js.assert(proc == firetray.Handler.wndProcs.get(wid),
+                     "Wrong WndProc replaced.");
+  firetray.Handler.wndProcs.remove(wid);
+  firetray.Handler.wndProcsOrig.remove(wid);
 };
 
 
-
 ///////////////////////// firetray.Handler overriding /////////////////////////
 
 /** debug facility */
@@ -138,7 +104,7 @@ firetray.Handler.registerWindow = function(win) {
   let baseWin = firetray.Handler.getWindowInterface(win, "nsIBaseWindow");
   let nativeHandle = baseWin.nativeHandle;
   let hwnd = nativeHandle ?
-        new ctypes.voidptr_t(ctypes.UInt64(nativeHandle)) :
+        new win32.HWND(ctypes.UInt64(nativeHandle)) :
         user32.FindWindowW("MozillaWindowClass", win.document.title);
   let wid = firetray.Win32.hwndToHexStr(hwnd);
   log.debug("=== hwnd="+hwnd+" wid="+wid+" win.document.title: "+win.document.title);
@@ -158,23 +124,24 @@ firetray.Handler.registerWindow = function(win) {
 //   ::SetPropW(hwnd, kIconMouseEventProc, reinterpret_cast<HANDLE>(callback));
 //   ::SetPropW(hwnd, kIcon, reinterpret_cast<HANDLE>(0x1));
 
-  this.windowsCount += 1;
-  // NOTE: no need to check for window state to set visibility because all
-  // windows *are* shown at startup
-  firetray.Window.updateVisibility(wid, true);
-  log.debug("window "+wid+" registered");
-
   try {
-    let callProcHook = user32.HOOKPROC(firetray.Window.callProcHook);
-    log.debug("callhk="+callProcHook);
-    // Global hooks must reside in a dll (hence hInst). This is important for
-    // the scope of variables.
-    let hhook = user32.SetWindowsHookExW(
-      user32.WH_CALLWNDPROC, callProcHook, null, kernel32.GetCurrentThreadId());
-    log.debug("  hhook="+hhook+" winLastError="+ctypes.winLastError);
-    this.callProcHooks.insert(wid, hhook);
-
-    firetray.Win32.acceptAllMessages(hwnd);
+    this.windowsCount += 1;
+    // NOTE: no need to check for window state to set visibility because all
+    // windows *are* shown at startup
+    firetray.Window.updateVisibility(wid, true);
+    log.debug("window "+wid+" registered");
+
+    let wndProc = user32.WNDPROC(firetray.Window.wndProc);
+    log.debug("proc="+wndProc);
+    this.wndProcs.insert(wid, wndProc);
+    let procPrev = user32.WNDPROC(
+      user32.SetWindowLongW(hwnd, user32.GWLP_WNDPROC,
+                            ctypes.cast(wndProc, win32.LONG_PTR))
+    );
+    log.debug("procPrev="+procPrev+" winLastError="+ctypes.winLastError);
+    // we can't store WNDPROC callbacks (JS ctypes objects) with SetPropW(), as
+    // we need long-living refs.
+    this.wndProcsOrig.insert(wid, procPrev);
 
   } catch (x) {
     if (x.name === "RangeError") // instanceof not working :-(
@@ -184,6 +151,8 @@ firetray.Handler.registerWindow = function(win) {
     else win.alert(x);
   }
 
+  firetray.Win32.acceptAllMessages(hwnd);
+
   log.debug("AFTER"); firetray.Handler.dumpWindows();
   return wid;
 };
@@ -191,17 +160,16 @@ firetray.Handler.registerWindow = function(win) {
 firetray.Handler.unregisterWindow = function(win) {
   log.debug("unregister window");
 
-  let wid = firetray.Window.getWIDFromChromeWindow(win);
-
+  let wid = firetray.Window.getRegisteredWinIdFromChromeWindow(win);
   if (!firetray.Handler.windows.hasOwnProperty(wid)) {
     log.error("can't unregister unknown window "+wid);
     return false;
   }
 
+  firetray.Window.restoreWndProc(wid);
+
   if (!delete firetray.Handler.windows[wid])
     throw new DeleteError();
-  user32.UnhookWindowsHookEx(firetray.Handler.callProcHooks.get(wid));
-  firetray.Handler.callProcHooks.remove(wid);
   firetray.Handler.windowsCount -= 1;
   firetray.Handler.visibleWindowsCount -= 1;
 

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