[Pkg-mozext-commits] [firetray] 12/84: * refactoring * attempt to set our WndProc on Moz windows * store window Id as a string

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 2e234064bb929279fcbfd79fc3923ade47a217ee
Author: foudfou <foudil.newbie+git at gmail.com>
Date:   Sun Dec 1 18:26:36 2013 +0100

    * refactoring
    * attempt to set our WndProc on Moz windows
    * store window Id as a string
    
    Calling CallWindowProc or ctypes.FuncType from a WNDPROC added to a Firefox
    window crashes. See
    https://bugzilla.mozilla.org/show_bug.cgi?id=598679
    https://bugzilla.mozilla.org/show_bug.cgi?id=671266
    
    The problem does not seem to occur on non-Firefox windows (for ex. a a hidden
    window that we created).
    
    We'll try to test Hooks instead of WndProcs.
---
 src/modules/FiretrayHandler.jsm          |   1 -
 src/modules/FiretrayWindow.jsm           |   7 ++
 src/modules/ctypes/winnt/user32.jsm      |   8 +-
 src/modules/ctypes/winnt/win32.jsm       | 130 ++++++++++++++---------------
 src/modules/linux/FiretrayWindow.jsm     |  20 ++---
 src/modules/winnt/FiretrayStatusIcon.jsm |  47 ++++++-----
 src/modules/winnt/FiretrayWin32.jsm      |  10 ++-
 src/modules/winnt/FiretrayWindow.jsm     | 139 ++++++++++++++++++++++---------
 8 files changed, 216 insertions(+), 146 deletions(-)

diff --git a/src/modules/FiretrayHandler.jsm b/src/modules/FiretrayHandler.jsm
index 162254b..993c8d9 100644
--- a/src/modules/FiretrayHandler.jsm
+++ b/src/modules/FiretrayHandler.jsm
@@ -327,7 +327,6 @@ firetray.Handler = {
   setIconVisibility: function(visible) {},
   registerWindow: function(win) {},
   unregisterWindow: function(win) {},
-  getWindowIdFromChromeWindow: function(win) {},
   hideWindow: function(winId) {},
   showWindow: function(winId) {},
   showHideAllWindows: function() {},
diff --git a/src/modules/FiretrayWindow.jsm b/src/modules/FiretrayWindow.jsm
index 98bb1a5..4312267 100644
--- a/src/modules/FiretrayWindow.jsm
+++ b/src/modules/FiretrayWindow.jsm
@@ -29,4 +29,11 @@ FiretrayWindow.prototype = {
     win.visible = visibility; // nsIBaseWin.visibility always true :-(
   },
 
+  getRegisteredWinIdFromChromeWindow: function(win) {
+    for (let wid in firetray.Handler.windows)
+      if (firetray.Handler.windows[wid].chromeWin === win) return wid;
+    log.error("unknown window while lookup");
+    return null;
+  },
+
 };
diff --git a/src/modules/ctypes/winnt/user32.jsm b/src/modules/ctypes/winnt/user32.jsm
index 1a1d9c9..1f90dc8 100644
--- a/src/modules/ctypes/winnt/user32.jsm
+++ b/src/modules/ctypes/winnt/user32.jsm
@@ -57,6 +57,11 @@ function user32_defines(lib) {
   this.LR_SHARED           = 0x00008000;
   this.LR_VGACOLOR         = 0x00000080;
 
+  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("GetWindowLongW", win32.LONG_PTR, win32.HWND, ctypes.int);
+  lib.lazy_bind("SetWindowLongW", win32.LONG_PTR , win32.HWND, ctypes.int, win32.LONG_PTR);
   // SetWindowLongPtrW aliases SetWindowLongW with the correct signature thank
   // win32.LONG_PTR
   lib.lazy_bind("SetWindowLongW", win32.LONG_PTR , win32.HWND, ctypes.int, win32.LONG_PTR);
@@ -71,7 +76,8 @@ 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, 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("DefWindowProcW", win32.LRESULT, win32.HWND, win32.UINT, win32.WPARAM, win32.LPARAM);
 
   this.WNDCLASSEXW = ctypes.StructType("WNDCLASSEXW", [
diff --git a/src/modules/ctypes/winnt/win32.jsm b/src/modules/ctypes/winnt/win32.jsm
index 790ab23..af33350 100644
--- a/src/modules/ctypes/winnt/win32.jsm
+++ b/src/modules/ctypes/winnt/win32.jsm
@@ -5,97 +5,95 @@ const Cu = Components.utils;
 Cu.import("resource://gre/modules/ctypes.jsm");
 Cu.import("resource://firetray/ctypes/ctypes-utils.jsm");
 
-const INT_PTR_T   = is64bit ? ctypes.int64_t  : ctypes.int;
-const UINT_PTR_T  = is64bit ? ctypes.uint64_t : ctypes.unsigned_int;
-const LONG_PTR_T  = is64bit ? ctypes.int64_t  : ctypes.long;
-const ULONG_PTR_T = is64bit ? ctypes.uint64_t : ctypes.unsigned_long;
-const HANDLE_T    = ctypes.voidptr_t; // oder ctypes.intptr_t, ctypes.size_t, ctypes.int32_t ?
-const WORD_T      = ctypes.unsigned_short;
 
-var win32 = {
+var win32 = new function() {
 
-  WIN_VERSIONS: { // maj*10 + min
+  this.WIN_VERSIONS = { // maj*10 + min
     '8':     62,    // 2012
     '7':     61,    // 2009
     'Vista': 60,    // 2007
     'XP':    51,    // 2001
     '2K':    50,    // 2000
-  },
-  WINVER: null,                 // initialized in kernel32.jsm
+  };
+  this.WINVER = null;                 // initialized in kernel32.jsm
 
-  BOOL: ctypes.bool,
-  BYTE: ctypes.unsigned_char,
-  UINT: ctypes.unsigned_int,
-  WORD: WORD_T,
-  DWORD: ctypes.unsigned_long,
-  PVOID: ctypes.voidptr_t,
-  LPVOID: ctypes.voidptr_t,
-  LONG: ctypes.long,
-  LONG_PTR: LONG_PTR_T,
-  ULONG_PTR: ULONG_PTR_T,
-  SIZE_T: ULONG_PTR_T,
-  ATOM: WORD_T,
-  HWND: HANDLE_T,
-  HICON: HANDLE_T,
-  HINSTANCE: HANDLE_T,
-  HMODULE: HANDLE_T,
-  HMENU: HANDLE_T,
-  HBRUSH: HANDLE_T,             // HICON
-  HCURSOR: HANDLE_T,
-  TCHAR: ctypes.jschar, // Mozilla compiled with UNICODE/_UNICODE macros and wchar_t: jschar
-  LPSTR: ctypes.char.ptr,
-  LPCSTR: ctypes.char.ptr,
-  LPTSTR: ctypes.jschar.ptr,    // UNICODE
-  LPCTSTR: ctypes.jschar.ptr,
-  LPCWSTR: ctypes.jschar.ptr,
-  LPWSTR: ctypes.jschar.ptr,      // WCHAR
-  LRESULT: LONG_PTR_T,
-  WPARAM: UINT_PTR_T,
-  LPARAM: LONG_PTR_T,
-  FARPROC: ctypes.voidptr_t,    // typedef INT_PTR (FAR WINAPI *FARPROC)();
+  this.BOOL      = ctypes.bool;
+  this.BYTE      = ctypes.unsigned_char;
+  this.INT_PTR   = is64bit ? ctypes.int64_t  : ctypes.int;
+  this.UINT      = ctypes.unsigned_int;
+  this.UINT_PTR  = is64bit ? ctypes.uint64_t : ctypes.unsigned_int;
+  this.WORD      = ctypes.unsigned_short;
+  this.DWORD     = ctypes.unsigned_long;
+  this.PVOID     = ctypes.voidptr_t;
+  this.LPVOID    = ctypes.voidptr_t;
+  this.LONG      = ctypes.long;
+  this.LONG_PTR  = is64bit ? ctypes.int64_t  : ctypes.long;
+  this.ULONG_PTR = is64bit ? ctypes.uint64_t : ctypes.unsigned_long;
+  this.SIZE_T    = this.ULONG_PTR;
+  this.ATOM      = this.WORD;
+  this.HANDLE    = ctypes.voidptr_t;
+  this.HWND      = this.HANDLE;
+  this.HICON     = this.HANDLE;
+  this.HINSTANCE = this.HANDLE;
+  this.HMODULE   = this.HANDLE;
+  this.HMENU     = this.HANDLE;
+  this.HBRUSH    = this.HICON;
+  this.HCURSOR   = this.HANDLE;
+  this.TCHAR     = ctypes.jschar, // Mozilla compiled with UNICODE/_UNICODE macros and wchar_t = jschar
+  this.LPSTR     = ctypes.char.ptr;
+  this.LPCSTR    = ctypes.char.ptr;
+  this.LPTSTR    = ctypes.jschar.ptr; // UNICODE
+  this.LPCTSTR   = ctypes.jschar.ptr;
+  this.LPCWSTR   = ctypes.jschar.ptr;
+  this.LPWSTR    = ctypes.jschar.ptr; // WCHAR
+  this.LRESULT   = this.LONG_PTR;
+  this.WPARAM    = this.UINT_PTR;
+  this.LPARAM    = this.LONG_PTR;
+  this.FARPROC   = ctypes.voidptr_t; // typedef INT_PTR (FAR WINAPI *FARPROC)();
 
-  GUID: ctypes.StructType("GUID", [
+  this.GUID = ctypes.StructType("GUID", [
     { "Data1": ctypes.unsigned_long },
     { "Data2": ctypes.unsigned_short },
     { "Data3": ctypes.unsigned_short },
     { "Data4": ctypes.char.array(8) }
-  ]),
+  ]);
 
   /*
    * #define MAKEINTRESOURCEA(i) ((LPSTR)((ULONG_PTR)((WORD)(i))))
    * #define MAKEINTRESOURCEW(i) ((LPWSTR)((ULONG_PTR)((WORD)(i))))
    */
-  MAKEINTRESOURCE: function(i) {return this.LPWSTR(i); },
+  this.MAKEINTRESOURCE = function(i) {return this.LPWSTR(i);};
 
-  _T: function(str) {
+  this._T = function(str) {
     return ctypes.jschar.array()(str);
-  },
+  };
 
-  ERROR_INVALID_WINDOW_HANDLE: 1400,
-  ERROR_RESOURCE_TYPE_NOT_FOUND: 1813,
+  this.ERROR_INVALID_WINDOW_HANDLE   = 1400;
+  this.ERROR_RESOURCE_TYPE_NOT_FOUND = 1813;
 
   // WinUser.h
-  WM_USER:           0x0400,
+  this.WM_USER          = 0x0400;
+  this.WM_APP           = 0x8000;
 
-  WM_CONTEXTMENU:    0x007B,
+  this.WM_CONTEXTMENU   = 0x007B;
 
-  WM_MOUSEFIRST:     0x0200,
-  WM_MOUSEMOVE:      0x0200,
-  WM_LBUTTONDOWN:    0x0201,
-  WM_LBUTTONUP:      0x0202,
-  WM_LBUTTONDBLCLK:  0x0203,
-  WM_RBUTTONDOWN:    0x0204,
-  WM_RBUTTONUP:      0x0205,
-  WM_RBUTTONDBLCLK:  0x0206,
-  WM_MBUTTONDOWN:    0x0207,
-  WM_MBUTTONUP:      0x0208,
-  WM_MBUTTONDBLCLK:  0x0209,
-  WM_MOUSEWHEEL:     0x020A,
-  WM_XBUTTONDOWN:    0x020B,
-  WM_XBUTTONUP:      0x020C,
-  WM_XBUTTONDBLCLK:  0x020D,
-  WM_MOUSELAST:      0x020D,
-  WM_MOUSELAST:      0x020A,
+  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;
 
 };
 
diff --git a/src/modules/linux/FiretrayWindow.jsm b/src/modules/linux/FiretrayWindow.jsm
index 1986776..3ff7ec5 100644
--- a/src/modules/linux/FiretrayWindow.jsm
+++ b/src/modules/linux/FiretrayWindow.jsm
@@ -53,13 +53,12 @@ var _find_data_t = ctypes.StructType("_find_data_t", [
 // 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),
-firetray.Handler.gtkPopupMenuWindowItems = new ctypesMap(gtk.GtkImageMenuItem.ptr),
+firetray.Handler.gtkWindows              = new ctypesMap(gtk.GtkWindow.ptr);
+firetray.Handler.gdkWindows              = new ctypesMap(gdk.GdkWindow.ptr);
+firetray.Handler.gtkPopupMenuWindowItems = new ctypesMap(gtk.GtkImageMenuItem.ptr);
 
 
 firetray.Window = new FiretrayWindow();
-
 firetray.Window.signals = {'focus-in': {callback: {}, handler: {}}};
 
 firetray.Window.init = function() {
@@ -187,7 +186,7 @@ firetray.Window.getGtkWindowFromGdkWindow = function(gdkWin) {
   return gtkw;
 };
 
-/* consider using getXIDFromChromeWindow() if you only need the XID */
+/* consider using getRegisteredWinIdFromChromeWindow() if you only need the XID */
 firetray.Window.getWindowsFromChromeWindow = function(win) {
   let baseWin = firetray.Handler.getWindowInterface(win, "nsIBaseWindow");
   let nativeHandle = baseWin.nativeHandle; // Moz' private pointer to the GdkWindow
@@ -205,13 +204,6 @@ firetray.Window.getWindowsFromChromeWindow = function(win) {
   return [baseWin, gtkWin, gdkWin, xid];
 };
 
-firetray.Window.getXIDFromChromeWindow = function(win) {
-  for (let xid in firetray.Handler.windows)
-    if (firetray.Handler.windows[xid].chromeWin === win) return xid;
-  log.error("unknown window while lookup");
-  return null;
-};
-
 firetray.Window.unregisterWindowByXID = function(xid) {
   if (!firetray.Handler.windows.hasOwnProperty(xid)) {
     log.error("can't unregister unknown window "+xid);
@@ -656,8 +648,6 @@ firetray.Handler.dumpWindows = function() {
   for (let winId in firetray.Handler.windows) log.info(winId+"="+firetray.Handler.gtkWindows.get(winId));
 };
 
-firetray.Handler.getWindowIdFromChromeWindow = firetray.Window.getXIDFromChromeWindow;
-
 firetray.Handler.registerWindow = function(win) {
   log.debug("register window");
 
@@ -713,7 +703,7 @@ firetray.Handler.registerWindow = function(win) {
 
 firetray.Handler.unregisterWindow = function(win) {
   log.debug("unregister window");
-  let xid = firetray.Window.getXIDFromChromeWindow(win);
+  let xid = firetray.Window.getRegisteredWinIdFromChromeWindow(win);
   return firetray.Window.unregisterWindowByXID(xid);
 };
 
diff --git a/src/modules/winnt/FiretrayStatusIcon.jsm b/src/modules/winnt/FiretrayStatusIcon.jsm
index 53055b5..8c64283 100644
--- a/src/modules/winnt/FiretrayStatusIcon.jsm
+++ b/src/modules/winnt/FiretrayStatusIcon.jsm
@@ -20,9 +20,6 @@ Cu.import("resource://firetray/winnt/FiretrayWin32.jsm");
 Cu.import("resource://firetray/commons.js");
 firetray.Handler.subscribeLibsForClosing([kernel32, shell32, user32]);
 
-const kMessageTray     = "_FIRETRAY_TrayMessage";
-const kMessageCallback = "_FIRETRAY_TrayCallback";
-
 let log = firetray.Logging.getLogger("firetray.StatusIcon");
 
 if ("undefined" == typeof(firetray.Handler))
@@ -33,7 +30,6 @@ firetray.StatusIcon = {
   initialized: false,
   callbacks: {}, // pointers to JS functions. MUST LIVE DURING ALL THE EXECUTION
   notifyIconData: null,
-  msg: {WM_TASKBARCREATED:null, WM_TRAYMESSAGE:null, WM_TRAYCALLBACK:null},
   hwndProxy: null,
   WNDCLASS_NAME: "FireTrayHiddenWindowClass",
   WNDCLASS_ATOM: null,
@@ -42,7 +38,6 @@ firetray.StatusIcon = {
     this.FILENAME_BLANK = firetray.Utils.chromeToPath(
       "chrome://firetray/skin/blank-icon.png");
 
-    this.registerMessages();
     this.create();
 
     this.initialized = true;
@@ -57,17 +52,6 @@ firetray.StatusIcon = {
     this.initialized = false;
   },
 
-  registerMessages: function() {
-    this.msg.WM_TASKBARCREATED = user32.RegisterWindowMessageW("TaskbarCreated");
-    this.msg.WM_TRAYMESSAGE  = user32.RegisterWindowMessageW(kMessageTray);
-    this.msg.WM_TRAYCALLBACK = user32.RegisterWindowMessageW(kMessageCallback);
-    log.debug("WM_*="+this.msg.WM_TASKBARCREATED+" "+this.msg.WM_TRAYMESSAGE+" "+this.msg.WM_TRAYCALLBACK);
-  },
-
-  unregisterMessages: function() {
-    // FIXME: TODO:
-  },
-
   create: function() {
     let hwnd_hidden = this.createProxyWindow();
 
@@ -81,7 +65,7 @@ firetray.StatusIcon = {
     nid.szTip = firetray.Handler.appName;
     nid.hIcon = this.getIconFromWindow(hwnd_hidden_moz);
     nid.hWnd = hwnd_hidden;
-    nid.uCallbackMessage = this.msg.WM_TRAYMESSAGE;
+    nid.uCallbackMessage = firetray.Win32.WM_TRAYMESSAGE;
     nid.uFlags = shell32.NIF_ICON | shell32.NIF_MESSAGE | shell32.NIF_TIP;
     nid.uVersion = shell32.NOTIFYICON_VERSION_4;
 
@@ -98,8 +82,6 @@ firetray.StatusIcon = {
   createProxyWindow: function() {
     this.registerWindowClass();
 
-    this.callbacks.hiddenWinProc = user32.WNDPROC(firetray.StatusIcon.proxyWindowProc);
-
     let hwnd_hidden = user32.CreateWindowExW(
       0, win32.LPCTSTR(this.WNDCLASS_ATOM), // lpClassName can also be _T(WNDCLASS_NAME)
       "Firetray Message Window", 0,
@@ -107,8 +89,18 @@ firetray.StatusIcon = {
       null, null, firetray.Win32.hInstance, null);
     log.debug("CreateWindow="+!hwnd_hidden.isNull()+" winLastError="+ctypes.winLastError);
 
+    this.callbacks.proxyWndProc = user32.WNDPROC(firetray.StatusIcon.proxyWndProc);
+/*
+    // TESTING
+    let proc = user32.GetWindowLongW(hwnd_hidden, user32.GWLP_WNDPROC);
+    log.debug("  proc="+proc.toString(16)+" winLastError="+ctypes.winLastError);
+    this.callbacks.procPrev = user32.WNDPROC(
+      user32.SetWindowLongW(hwnd_hidden, user32.GWLP_WNDPROC,
+        ctypes.cast(this.callbacks.proxyWndProc, win32.LONG_PTR))
+    );
+*/
     let procPrev = user32.SetWindowLongW(hwnd_hidden, user32.GWLP_WNDPROC,
-      ctypes.cast(this.callbacks.hiddenWinProc, win32.LONG_PTR));
+      ctypes.cast(this.callbacks.proxyWndProc, win32.LONG_PTR));
     log.debug("procPrev="+procPrev+" winLastError="+ctypes.winLastError);
 
     firetray.Win32.acceptAllMessages(hwnd_hidden);
@@ -126,13 +118,13 @@ firetray.StatusIcon = {
     log.debug("WNDCLASS_ATOM="+this.WNDCLASS_ATOM);
   },
 
-  proxyWindowProc: function(hWnd, uMsg, wParam, lParam) {
+  proxyWndProc: function(hWnd, uMsg, wParam, lParam) {
     // log.debug("ProxyWindowProc CALLED: hWnd="+hWnd+", uMsg="+uMsg+", wParam="+wParam+", lParam="+lParam);
 
-    if (uMsg === firetray.StatusIcon.msg.WM_TASKBARCREATED) {
+    if (uMsg === firetray.Win32.WM_TASKBARCREATED) {
       log.info("____________TASKBARCREATED");
 
-    } else if (uMsg === firetray.StatusIcon.msg.WM_TRAYMESSAGE) {
+    } else if (uMsg === firetray.Win32.WM_TRAYMESSAGE) {
 
       switch (+lParam) {
       case win32.WM_LBUTTONUP:
@@ -152,6 +144,15 @@ firetray.StatusIcon = {
 
     }
 
+/*
+    // CallWindowProcW() on a non-moz window works fine
+    let procPrev = firetray.StatusIcon.callbacks.procPrev;
+    log.debug("  procPrev="+procPrev);
+    let rv = user32.CallWindowProcW(procPrev, hWnd, uMsg, wParam, lParam);
+    log.debug("  CallWindowProc="+rv);
+    return rv;
+*/
+
     return user32.DefWindowProcW(hWnd, uMsg, wParam, lParam);
   },
 
diff --git a/src/modules/winnt/FiretrayWin32.jsm b/src/modules/winnt/FiretrayWin32.jsm
index 07b24ab..74d8c72 100644
--- a/src/modules/winnt/FiretrayWin32.jsm
+++ b/src/modules/winnt/FiretrayWin32.jsm
@@ -15,6 +15,9 @@ firetray.Handler.subscribeLibsForClosing([kernel32, user32]);
 
 let log = firetray.Logging.getLogger("firetray.Win32");
 
+const kMessageTray     = "_FIRETRAY_TrayMessage";
+const kMessageCallback = "_FIRETRAY_TrayCallback";
+
 if ("undefined" == typeof(firetray.Handler))
   log.error("This module MUST be imported from/after FiretrayHandler !");
 
@@ -23,11 +26,16 @@ function Win32Env() {
   this.hInstance = kernel32.GetModuleHandleW("xul"); // ordinary windows are created from xul.dll
   log.debug("hInstance="+this.hInstance);
 
+  this.WM_TASKBARCREATED = user32.RegisterWindowMessageW("TaskbarCreated");
+  this.WM_TRAYMESSAGE  = user32.RegisterWindowMessageW(kMessageTray);
+  this.WM_TRAYCALLBACK = user32.RegisterWindowMessageW(kMessageCallback);
+  log.debug("WM_*="+this.WM_TASKBARCREATED+" "+this.WM_TRAYMESSAGE+" "+this.WM_TRAYCALLBACK);
+
   /* if Administrator, accept messages from applications running in a lower
    privilege level */
   this.acceptAllMessages = function(hwnd) {
     let rv = null;
-    log.info(win32.WINVER+" >= "+win32.WIN_VERSIONS["7"]);
+    log.debug(win32.WINVER+" >= "+win32.WIN_VERSIONS["7"]);
     if (win32.WINVER >= win32.WIN_VERSIONS["7"]) {
       rv = user32.ChangeWindowMessageFilterEx(hwnd, firetray.Win32.WM_TASKBARCREATED, user32.MSGFLT_ALLOW, null);
       log.debug("ChangeWindowMessageFilterEx res="+rv+" winLastError="+ctypes.winLastError);
diff --git a/src/modules/winnt/FiretrayWindow.jsm b/src/modules/winnt/FiretrayWindow.jsm
index fe712d5..aeee4ba 100644
--- a/src/modules/winnt/FiretrayWindow.jsm
+++ b/src/modules/winnt/FiretrayWindow.jsm
@@ -6,8 +6,6 @@ const Cc = Components.classes;
 const Ci = Components.interfaces;
 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/ctypes/ctypesMap.jsm");
 Cu.import("resource://firetray/ctypes/winnt/win32.jsm");
@@ -22,17 +20,17 @@ let log = firetray.Logging.getLogger("firetray.Window");
 if ("undefined" == typeof(firetray.Handler))
   log.error("This module MUST be imported from/after FiretrayHandler !");
 
-const Services2 = {};
-XPCOMUtils.defineLazyServiceGetter(
-  Services2,
-  "uuid",
-  "@mozilla.org/uuid-generator;1",
-  "nsIUUIDGenerator"
-);
-
 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.wndProcs     = new ctypesMap(user32.WNDPROC);
+firetray.Handler.wndProcsOrig = new ctypesMap(user32.WNDPROC);
+
 
 firetray.Window = new FiretrayWindow();
 
@@ -59,6 +57,50 @@ firetray.Window.startupHide = function(xid) {
 firetray.Window.setVisibility = function(xid, visibility) {
 };
 
+// wid will be used as a string most of the time (through f.Handler.windows mainly)
+firetray.Window.hwndToHexStr = function(hWnd) {
+  return "0x" + ctypes.cast(hWnd, ctypes.uintptr_t).value.toString(16);
+};
+
+firetray.Window.wndProc = function(hWnd, uMsg, wParam, lParam) { // filterWindow
+  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);
+
+try {
+
+  let wid = firetray.Window.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);
+
+  /*
+   * https://bugzilla.mozilla.org/show_bug.cgi?id=598679
+   * https://bugzilla.mozilla.org/show_bug.cgi?id=671266
+   */
+  // 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);
+  }
+
+  // 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);
+};
+
+
 
 ///////////////////////// firetray.Handler overriding /////////////////////////
 
@@ -66,13 +108,11 @@ firetray.Window.setVisibility = function(xid, visibility) {
 firetray.Handler.dumpWindows = function() {
   let dumpStr = ""+firetray.Handler.windowsCount;
   for (let wid in firetray.Handler.windows) {
-    dumpStr += " 0x"+wid;
+    dumpStr += " "+wid;
   }
   log.info(dumpStr);
 };
 
-firetray.Handler.getWindowIdFromChromeWindow = firetray.Window.getXIDFromChromeWindow;
-
 firetray.Handler.registerWindow = function(win) {
   log.debug("register window");
 
@@ -81,8 +121,7 @@ firetray.Handler.registerWindow = function(win) {
   let hwnd = nativeHandle ?
         new ctypes.voidptr_t(ctypes.UInt64(nativeHandle)) :
         user32.FindWindowW("MozillaWindowClass", win.document.title);
-  // wid will be used as a string most of the time (through f.Handler.windows mainly)
-  let wid = ctypes.cast(hwnd, ctypes.uintptr_t).value.toString(16);
+  let wid = firetray.Window.hwndToHexStr(hwnd);
   log.debug("=== hwnd="+hwnd+" wid="+wid+" win.document.title: "+win.document.title);
 
   if (this.windows.hasOwnProperty(wid)) {
@@ -104,33 +143,40 @@ firetray.Handler.registerWindow = function(win) {
   // 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 0x"+wid+" registered");
+  log.debug("window "+wid+" registered");
   // NOTE: shouldn't 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
-
-    this.windows[xid].filterWindowCb = gdk.GdkFilterFunc_t(firetray.Window.filterWindow);
-    gdk.gdk_window_add_filter(gdkWin, this.windows[xid].filterWindowCb, null);
-    if (!firetray.Handler.appStarted) {
-      this.windows[xid].startupFilterCb = gdk.GdkFilterFunc_t(firetray.Window.startupFilter);
-      gdk.gdk_window_add_filter(gdkWin, this.windows[xid].startupFilterCb, null);
-    }
-
-    firetray.Window.attachOnFocusInCallback(xid);
-    if (firetray.Handler.isChatEnabled() && firetray.Chat.initialized) {
-      firetray.Chat.attachSelectListeners(win);
-    }
-
-  } catch (x) {
-    firetray.Window.unregisterWindowByXID(xid);
-    log.error(x);
-    return null;
+  // try {
+try {
+    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);
+    this.wndProcsOrig.insert(wid, procPrev); // could be set as a window prop (SetPropW)
+
+    procPrev = ctypes.cast(procPrev, win32.HANDLE);
+    user32.SetPropW(hwnd, win32._T(kPropProcPrev), procPrev);
+    log.debug("SetPropW: "+procPrev+" winLastError="+ctypes.winLastError);
+  } catch(error) {
+log.error(error);
   }
 */
+    // firetray.Win32.acceptAllMessages(hwnd);
+
+  // } catch (x) {
+  //   if (x.name === "RangeError") // instanceof not working :-(
+  //     win.alert(x+"\n\nYou seem to have more than "+FIRETRAY_WINDOW_COUNT_MAX
+  //               +" windows open. This breaks FireTray and most probably "
+  //               +firetray.Handler.appName+".");
+  //   else win.alert(x);
+  // }
+
+  // TODO: check wndproc chaining http://stackoverflow.com/a/8835843/421846 if
+  // needed for startupFilter
 
   log.debug("AFTER"); firetray.Handler.dumpWindows();
   return wid;
@@ -138,8 +184,23 @@ firetray.Handler.registerWindow = function(win) {
 
 firetray.Handler.unregisterWindow = function(win) {
   log.debug("unregister window");
-  let xid = firetray.Window.getXIDFromChromeWindow(win);
-  return firetray.Window.unregisterWindowByXID(xid);
+
+  let wid = firetray.Window.getWIDFromChromeWindow(win);
+
+  if (!firetray.Handler.windows.hasOwnProperty(wid)) {
+    log.error("can't unregister unknown window "+wid);
+    return false;
+  }
+
+  if (!delete firetray.Handler.windows[wid])
+    throw new DeleteError();
+  // firetray.Handler.wndProcs.remove(wid);
+  // firetray.Handler.wndProcsOrig.remove(wid);
+  firetray.Handler.windowsCount -= 1;
+  firetray.Handler.visibleWindowsCount -= 1;
+
+  log.debug("window "+wid+" unregistered");
+  return true;
 };
 
 firetray.Handler.showWindow = firetray.Window.show;

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