1
0
mirror of https://github.com/moparisthebest/FireTray synced 2025-01-07 19:48:03 -05:00

* 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 ?
This commit is contained in:
foudfou 2014-05-29 23:14:49 +02:00
parent 7aca24c88a
commit 0dd01042cc
5 changed files with 191 additions and 159 deletions

View File

@ -50,6 +50,7 @@ const WinABI = is64bit ? ctypes.default_abi : ctypes.winapi_abi;
const WinCbABI = is64bit ? ctypes.default_abi : ctypes.stdcall_abi; const WinCbABI = is64bit ? ctypes.default_abi : ctypes.stdcall_abi;
let log = firetray.Logging.getLogger("firetray.ctypes-utils"); 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 * Loads a library using ctypes and exports an object on to the specified

View File

@ -32,6 +32,7 @@ function user32_defines(lib) {
lib.lazy_bind("GetWindowTextW", ctypes.int, win32.HWND, win32.LPTSTR, ctypes.int); 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("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); lib.lazy_bind("SendMessageW", win32.LRESULT, win32.HWND, win32.UINT, win32.WPARAM, win32.LPARAM);
this.WM_GETICON = 0x007F; this.WM_GETICON = 0x007F;
this.WM_SETICON = 0x0080; this.WM_SETICON = 0x0080;
@ -95,8 +96,7 @@ function user32_defines(lib) {
WinCbABI, win32.LRESULT, WinCbABI, win32.LRESULT,
[win32.HWND, win32.UINT, win32.WPARAM, win32.LPARAM]).ptr; [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); lib.lazy_bind("DefWindowProcW", win32.LRESULT, win32.HWND, win32.UINT, win32.WPARAM, win32.LPARAM);
this.WNDCLASSEXW = ctypes.StructType("WNDCLASSEXW", [ this.WNDCLASSEXW = ctypes.StructType("WNDCLASSEXW", [
@ -186,6 +186,16 @@ function user32_defines(lib) {
{ "hwnd": win32.HWND } { "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( this.HOOKPROC = ctypes.FunctionType(
WinCbABI, win32.LRESULT, WinCbABI, win32.LRESULT,
[ctypes.int, win32.WPARAM, win32.LPARAM]).ptr; [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("GetWindowPlacement", win32.BOOL, win32.HWND, this.WINDOWPLACEMENT.ptr);
lib.lazy_bind("SetWindowPlacement", 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); new ctypes_library(USER32_LIBNAME, USER32_ABIS, user32_defines, this);

View File

@ -97,67 +97,70 @@ var win32 = new function() {
this.ERROR_RESOURCE_TYPE_NOT_FOUND = 1813; this.ERROR_RESOURCE_TYPE_NOT_FOUND = 1813;
// WinUser.h // WinUser.h
this.WM_NULL = 0x0000; this.WM_NULL = 0x0000;
this.WM_CREATE = 0x0001; this.WM_CREATE = 0x0001;
this.WM_DESTROY = 0x0002; this.WM_DESTROY = 0x0002;
this.WM_MOVE = 0x0003; this.WM_MOVE = 0x0003;
this.WM_SIZE = 0x0005; this.WM_SIZE = 0x0005;
this.WM_ACTIVATE = 0x0006; this.WM_ACTIVATE = 0x0006;
this.WA_INACTIVE = 0; this.WA_INACTIVE = 0;
this.WA_ACTIVE = 1; this.WA_ACTIVE = 1;
this.WA_CLICKACTIVE = 2; this.WA_CLICKACTIVE = 2;
this.WM_SETFOCUS = 0x0007; this.WM_SETFOCUS = 0x0007;
this.WM_KILLFOCUS = 0x0008; this.WM_KILLFOCUS = 0x0008;
this.WM_ENABLE = 0x000A; this.WM_ENABLE = 0x000A;
this.WM_SETREDRAW = 0x000B; this.WM_SETREDRAW = 0x000B;
this.WM_SETTEXT = 0x000C; this.WM_SETTEXT = 0x000C;
this.WM_GETTEXT = 0x000D; this.WM_GETTEXT = 0x000D;
this.WM_GETTEXTLENGTH = 0x000E; this.WM_GETTEXTLENGTH = 0x000E;
this.WM_PAINT = 0x000F; this.WM_PAINT = 0x000F;
this.WM_CLOSE = 0x0010; this.WM_CLOSE = 0x0010;
this.WM_QUIT = 0x0012; this.WM_QUIT = 0x0012;
this.WM_ERASEBKGND = 0x0014; this.WM_ERASEBKGND = 0x0014;
this.WM_SYSCOLORCHANGE = 0x0015; this.WM_SYSCOLORCHANGE = 0x0015;
this.WM_SHOWWINDOW = 0x0018; this.WM_SHOWWINDOW = 0x0018;
this.WM_WININICHANGE = 0x001A; this.WM_WININICHANGE = 0x001A;
this.WM_SETTINGCHANGE = this.WM_WININICHANGE; this.WM_SETTINGCHANGE = this.WM_WININICHANGE;
this.WM_DEVMODECHANGE = 0x001B; this.WM_DEVMODECHANGE = 0x001B;
this.WM_ACTIVATEAPP = 0x001C; this.WM_ACTIVATEAPP = 0x001C;
this.WM_FONTCHANGE = 0x001D; this.WM_FONTCHANGE = 0x001D;
this.WM_TIMECHANGE = 0x001E; this.WM_TIMECHANGE = 0x001E;
this.WM_CANCELMODE = 0x001F; this.WM_CANCELMODE = 0x001F;
this.WM_SETCURSOR = 0x0020; this.WM_SETCURSOR = 0x0020;
this.WM_MOUSEACTIVATE = 0x0021; this.WM_MOUSEACTIVATE = 0x0021;
this.WM_CHILDACTIVATE = 0x0022; this.WM_CHILDACTIVATE = 0x0022;
this.WM_QUEUESYNC = 0x0023; this.WM_QUEUESYNC = 0x0023;
this.WM_COMMAND = 0x0111; this.WM_WINDOWPOSCHANGING = 0x0046;
this.WM_SYSCOMMAND = 0x0112; this.WM_WINDOWPOSCHANGED = 0x0047;
this.WM_HSCROLL = 0x0114; this.WM_INITDIALOG = 0x0110;
this.WM_VSCROLL = 0x0115; this.WM_COMMAND = 0x0111;
this.WM_MOUSEWHEEL = 0x020A; this.WM_SYSCOMMAND = 0x0112;
this.WM_HSCROLL = 0x0114;
this.WM_VSCROLL = 0x0115;
this.WM_MOUSEWHEEL = 0x020A;
this.WM_USER = 0x0400; this.WM_USER = 0x0400;
this.WM_APP = 0x8000; this.WM_APP = 0x8000;
this.WM_CONTEXTMENU = 0x007B; this.WM_CONTEXTMENU = 0x007B;
this.WM_MOUSEFIRST = 0x0200; this.WM_MOUSEFIRST = 0x0200;
this.WM_MOUSEMOVE = 0x0200; this.WM_MOUSEMOVE = 0x0200;
this.WM_LBUTTONDOWN = 0x0201; this.WM_LBUTTONDOWN = 0x0201;
this.WM_LBUTTONUP = 0x0202; this.WM_LBUTTONUP = 0x0202;
this.WM_LBUTTONDBLCLK = 0x0203; this.WM_LBUTTONDBLCLK = 0x0203;
this.WM_RBUTTONDOWN = 0x0204; this.WM_RBUTTONDOWN = 0x0204;
this.WM_RBUTTONUP = 0x0205; this.WM_RBUTTONUP = 0x0205;
this.WM_RBUTTONDBLCLK = 0x0206; this.WM_RBUTTONDBLCLK = 0x0206;
this.WM_MBUTTONDOWN = 0x0207; this.WM_MBUTTONDOWN = 0x0207;
this.WM_MBUTTONUP = 0x0208; this.WM_MBUTTONUP = 0x0208;
this.WM_MBUTTONDBLCLK = 0x0209; this.WM_MBUTTONDBLCLK = 0x0209;
this.WM_MOUSEWHEEL = 0x020A; this.WM_MOUSEWHEEL = 0x020A;
this.WM_XBUTTONDOWN = 0x020B; this.WM_XBUTTONDOWN = 0x020B;
this.WM_XBUTTONUP = 0x020C; this.WM_XBUTTONUP = 0x020C;
this.WM_XBUTTONDBLCLK = 0x020D; this.WM_XBUTTONDBLCLK = 0x020D;
this.WM_MOUSELAST = 0x020D; this.WM_MOUSELAST = 0x020D;
this.WM_MOUSELAST = 0x020A; this.WM_MOUSELAST = 0x020A;
this.SC_MINIMIZE = 0xF020; this.SC_MINIMIZE = 0xF020;
this.SC_CLOSE = 0xF060; this.SC_CLOSE = 0xF060;

View File

@ -104,9 +104,12 @@ firetray.PopupMenu = {
0, null); 0, null);
}, },
// FIXME: need to handle hides_single_window=false /**
addWindowItemAndSeparatorMaybe: function(wid) { * @param force: useful to start_hidden, when window is not shown
if (firetray.Handler.visibleWindowsCount === firetray.Handler.windowsCount) */
addWindowItemAndSeparatorMaybe: function(wid, force) {
if (typeof force === "undefined") force = false;
if (force || firetray.Handler.visibleWindowsCount === firetray.Handler.windowsCount)
this.insertSeparator(); this.insertSeparator();
this.addWindowItem(wid); this.addWindowItem(wid);
}, },

View File

@ -26,10 +26,9 @@ const FIRETRAY_XWINDOW_MAXIMIZED = 1 << 1;
// We need to keep long-living references to wndProcs callbacks. As they also // 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. // happen to be ctypes pointers, we store them into real ctypes arrays.
firetray.Handler.wndProcs = new ctypesMap(user32.WNDPROC); firetray.Handler.wndProcs = new ctypesMap(win32.LONG_PTR);
firetray.Handler.wndProcsOrig = new ctypesMap(user32.WNDPROC); firetray.Handler.wndProcsOrig = new ctypesMap(win32.LONG_PTR);
firetray.Handler.procHooks = new ctypesMap(win32.HHOOK); firetray.Handler.wndProcsStartup = new ctypesMap(win32.LONG_PTR);
firetray.Handler.procHooksRegistred = new ctypesMap(win32.HHOOK);
firetray.Window = new FiretrayWindow(); 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); log.debug("wndProc CALLED with WM_SYSCOMMAND wParam="+wParam);
if (wParam === win32.SC_MINIMIZE) { if (wParam === win32.SC_MINIMIZE) {
log.debug("GOT ICONIFIED"); log.debug("GOT ICONIFIED");
if (firetray.Handler.hideOnMinimizeMaybe(wid)) { if (firetray.Handler.onMinimize(wid)) {
return 0; // processed => preventDefault return 0; // processed => preventDefault
} }
} }
} }
let procPrev = firetray.Handler.wndProcsOrig.get(wid); 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; * We get the best effect by intercepting WM_WINDOWPOSCHANGING/SWP_SHOWWINDOW.
firetray.Window.startupHook = function(nCode, wParam, lParam) { // WH_CALLWNDPROC, WH_GETMESSAGE * Here, we subclass only once either with a startup wndProc, if
// log.debug("startupHook CALLED: nCode="+nCode+", wParam="+wParam+", lParam="+lParam); * start_hidden, or just our default wndProc. None of the following works:
if (nCode < 0) return user32.CallNextHookEx(null, nCode, wParam, lParam); // user32.HC_ACTION * - 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; if (uMsg === win32.WM_WINDOWPOSCHANGING) {
let uMsg = cwpstruct.message; let posStruct = ctypes.cast(win32.LPARAM(lParam), user32.WINDOWPOS.ptr).contents;
let hwnd = cwpstruct.hwnd; let isShowing = ((posStruct.flags & user32.SWP_SHOWWINDOW) != 0);
let wid = firetray.Win32.hwndToHexStr(hwnd); if (isShowing) {
let wparam = cwpstruct.wParam; log.debug("wndProcStartup CALLED with WM_WINDOWPOSCHANGING/SWP_SHOWWINDOW");
let lparam = cwpstruct.lParam; firetray.Window.startupShowCount += 1;
if (uMsg === win32.WM_SHOWWINDOW && wparam == 1 && lparam == 0) { // shown and ShowWindow called if (firetray.Window.startupShowCount < 2) { // hide
log.debug("startupHook CALLED with WM_SHOWWINDOW wparam="+wparam+" lparam="+lparam); log.debug("start_hidden");
firetray.Window.showCount += 1; // Modifying a JS posStruct field does really modify the WINDOWPOS C
// struct behind lParam !
if (firetray.Utils.prefService.getBoolPref('start_hidden')) { posStruct.flags &= ~user32.SWP_SHOWWINDOW;
log.debug("start_hidden"); let force = true;
firetray.Handler.addPopupMenuWindowItemAndSeparatorMaybe(wid, force);
/* Compared to ShowWindow, SetWindowPlacement seems to bypass window }
animations. http://stackoverflow.com/a/6087214 */ else { // restore
let placement = new user32.WINDOWPLACEMENT; firetray.Window.attachWndProc({
let ret = user32.GetWindowPlacement(hwnd, placement.address()); wid: wid, hwnd: hWnd,
log.debug(" GetWindowPlacement="+ret+" winLastError="+ctypes.winLastError); jsProc: firetray.Window.wndProc,
log.debug(" PLACEMENT="+placement); mapNew: firetray.Handler.wndProcs,
mapBak: null
if (firetray.Window.showCount < 2) { });
// we can't prevent ShowWindow, so we mitigate the effect by minimizing firetray.Handler.wndProcsStartup.remove(wid);
// 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());
} }
} 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 { try {
let wndProc = user32.WNDPROC(firetray.Window.wndProc); let wndProc = ctypes.cast(user32.WNDPROC(procInfo.jsProc), win32.LONG_PTR);
log.debug("proc="+wndProc); log.debug("proc="+wndProc);
firetray.Handler.wndProcs.insert(wid, wndProc); procInfo.mapNew.insert(procInfo.wid, wndProc);
let procPrev = user32.WNDPROC( let procPrev = user32.SetWindowLongW(procInfo.hwnd, user32.GWLP_WNDPROC, wndProc);
user32.SetWindowLongW(hwnd, user32.GWLP_WNDPROC,
ctypes.cast(wndProc, win32.LONG_PTR))
);
log.debug("procPrev="+procPrev+" winLastError="+ctypes.winLastError); log.debug("procPrev="+procPrev+" winLastError="+ctypes.winLastError);
/* we can't store WNDPROC callbacks (JS ctypes objects) with SetPropW(), as /* we can't store WNDPROC callbacks (JS ctypes objects) with SetPropW(), as
we need long-living refs. */ we need long-living refs. */
firetray.Handler.wndProcsOrig.insert(wid, procPrev); if (procInfo.mapBak) procInfo.mapBak.insert(procInfo.wid, procPrev);
} catch (x) { } catch (x) {
if (x.name === "RangeError") { // instanceof not working :-( if (x.name === "RangeError") { // instanceof not working :-(
@ -157,40 +141,17 @@ firetray.Window.attachWndProc = function(wid, hwnd) {
} }
}; };
firetray.Window.detachWndProc = function(wid) { // procInfo = {wid, mapNew, mapBak}
let procPrev = firetray.Handler.wndProcsOrig.get(wid); firetray.Window.detachWndProc = function(procInfo) {
let wid = procInfo.wid;
let procPrev = procInfo.mapBak.get(wid);
let hwnd = firetray.Win32.hexStrToHwnd(wid); let hwnd = firetray.Win32.hexStrToHwnd(wid);
log.debug("hwnd="+hwnd); log.debug("hwnd="+hwnd);
let proc = user32.WNDPROC( let proc = user32.SetWindowLongW(hwnd, user32.GWLP_WNDPROC, procPrev);
user32.SetWindowLongW(hwnd, user32.GWLP_WNDPROC, firetray.js.assert(firetray.js.strEquals(proc, procInfo.mapNew.get(wid)),
ctypes.cast(procPrev, win32.LONG_PTR))
);
firetray.js.assert(firetray.js.strEquals(proc, firetray.Handler.wndProcs.get(wid)),
"Wrong WndProc replaced."); "Wrong WndProc replaced.");
firetray.Handler.wndProcs.remove(wid); procInfo.mapNew.remove(wid);
firetray.Handler.wndProcsOrig.remove(wid); procInfo.mapBak.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);
}; };
@ -230,10 +191,19 @@ firetray.Handler.registerWindow = function(win) {
}); });
log.debug("window "+wid+" registered"); log.debug("window "+wid+" registered");
firetray.Window.attachWndProc(wid, hwnd); let proc, map;
if (!firetray.Handler.appStarted) { if (!firetray.Handler.appStarted &&
firetray.Window.attachHook(wid); 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); firetray.Win32.acceptAllMessages(hwnd);
@ -250,7 +220,25 @@ firetray.Handler.unregisterWindow = function(win) {
return false; 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]) if (!delete firetray.Handler.windows[wid])
throw new DeleteError(); throw new DeleteError();