mirror of
https://github.com/moparisthebest/FireTray
synced 2025-01-08 12:08:05 -05:00
* 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.
This commit is contained in:
parent
d52245cc87
commit
2e234064bb
@ -327,7 +327,6 @@ firetray.Handler = {
|
|||||||
setIconVisibility: function(visible) {},
|
setIconVisibility: function(visible) {},
|
||||||
registerWindow: function(win) {},
|
registerWindow: function(win) {},
|
||||||
unregisterWindow: function(win) {},
|
unregisterWindow: function(win) {},
|
||||||
getWindowIdFromChromeWindow: function(win) {},
|
|
||||||
hideWindow: function(winId) {},
|
hideWindow: function(winId) {},
|
||||||
showWindow: function(winId) {},
|
showWindow: function(winId) {},
|
||||||
showHideAllWindows: function() {},
|
showHideAllWindows: function() {},
|
||||||
|
@ -29,4 +29,11 @@ FiretrayWindow.prototype = {
|
|||||||
win.visible = visibility; // nsIBaseWin.visibility always true :-(
|
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;
|
||||||
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -57,6 +57,11 @@ function user32_defines(lib) {
|
|||||||
this.LR_SHARED = 0x00008000;
|
this.LR_SHARED = 0x00008000;
|
||||||
this.LR_VGACOLOR = 0x00000080;
|
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
|
// SetWindowLongPtrW aliases SetWindowLongW with the correct signature thank
|
||||||
// win32.LONG_PTR
|
// win32.LONG_PTR
|
||||||
lib.lazy_bind("SetWindowLongW", win32.LONG_PTR , win32.HWND, ctypes.int, 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,
|
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", [
|
||||||
|
@ -5,97 +5,95 @@ const Cu = Components.utils;
|
|||||||
Cu.import("resource://gre/modules/ctypes.jsm");
|
Cu.import("resource://gre/modules/ctypes.jsm");
|
||||||
Cu.import("resource://firetray/ctypes/ctypes-utils.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
|
'8': 62, // 2012
|
||||||
'7': 61, // 2009
|
'7': 61, // 2009
|
||||||
'Vista': 60, // 2007
|
'Vista': 60, // 2007
|
||||||
'XP': 51, // 2001
|
'XP': 51, // 2001
|
||||||
'2K': 50, // 2000
|
'2K': 50, // 2000
|
||||||
},
|
};
|
||||||
WINVER: null, // initialized in kernel32.jsm
|
this.WINVER = null; // initialized in kernel32.jsm
|
||||||
|
|
||||||
BOOL: ctypes.bool,
|
this.BOOL = ctypes.bool;
|
||||||
BYTE: ctypes.unsigned_char,
|
this.BYTE = ctypes.unsigned_char;
|
||||||
UINT: ctypes.unsigned_int,
|
this.INT_PTR = is64bit ? ctypes.int64_t : ctypes.int;
|
||||||
WORD: WORD_T,
|
this.UINT = ctypes.unsigned_int;
|
||||||
DWORD: ctypes.unsigned_long,
|
this.UINT_PTR = is64bit ? ctypes.uint64_t : ctypes.unsigned_int;
|
||||||
PVOID: ctypes.voidptr_t,
|
this.WORD = ctypes.unsigned_short;
|
||||||
LPVOID: ctypes.voidptr_t,
|
this.DWORD = ctypes.unsigned_long;
|
||||||
LONG: ctypes.long,
|
this.PVOID = ctypes.voidptr_t;
|
||||||
LONG_PTR: LONG_PTR_T,
|
this.LPVOID = ctypes.voidptr_t;
|
||||||
ULONG_PTR: ULONG_PTR_T,
|
this.LONG = ctypes.long;
|
||||||
SIZE_T: ULONG_PTR_T,
|
this.LONG_PTR = is64bit ? ctypes.int64_t : ctypes.long;
|
||||||
ATOM: WORD_T,
|
this.ULONG_PTR = is64bit ? ctypes.uint64_t : ctypes.unsigned_long;
|
||||||
HWND: HANDLE_T,
|
this.SIZE_T = this.ULONG_PTR;
|
||||||
HICON: HANDLE_T,
|
this.ATOM = this.WORD;
|
||||||
HINSTANCE: HANDLE_T,
|
this.HANDLE = ctypes.voidptr_t;
|
||||||
HMODULE: HANDLE_T,
|
this.HWND = this.HANDLE;
|
||||||
HMENU: HANDLE_T,
|
this.HICON = this.HANDLE;
|
||||||
HBRUSH: HANDLE_T, // HICON
|
this.HINSTANCE = this.HANDLE;
|
||||||
HCURSOR: HANDLE_T,
|
this.HMODULE = this.HANDLE;
|
||||||
TCHAR: ctypes.jschar, // Mozilla compiled with UNICODE/_UNICODE macros and wchar_t: jschar
|
this.HMENU = this.HANDLE;
|
||||||
LPSTR: ctypes.char.ptr,
|
this.HBRUSH = this.HICON;
|
||||||
LPCSTR: ctypes.char.ptr,
|
this.HCURSOR = this.HANDLE;
|
||||||
LPTSTR: ctypes.jschar.ptr, // UNICODE
|
this.TCHAR = ctypes.jschar, // Mozilla compiled with UNICODE/_UNICODE macros and wchar_t = jschar
|
||||||
LPCTSTR: ctypes.jschar.ptr,
|
this.LPSTR = ctypes.char.ptr;
|
||||||
LPCWSTR: ctypes.jschar.ptr,
|
this.LPCSTR = ctypes.char.ptr;
|
||||||
LPWSTR: ctypes.jschar.ptr, // WCHAR
|
this.LPTSTR = ctypes.jschar.ptr; // UNICODE
|
||||||
LRESULT: LONG_PTR_T,
|
this.LPCTSTR = ctypes.jschar.ptr;
|
||||||
WPARAM: UINT_PTR_T,
|
this.LPCWSTR = ctypes.jschar.ptr;
|
||||||
LPARAM: LONG_PTR_T,
|
this.LPWSTR = ctypes.jschar.ptr; // WCHAR
|
||||||
FARPROC: ctypes.voidptr_t, // typedef INT_PTR (FAR WINAPI *FARPROC)();
|
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 },
|
{ "Data1": ctypes.unsigned_long },
|
||||||
{ "Data2": ctypes.unsigned_short },
|
{ "Data2": ctypes.unsigned_short },
|
||||||
{ "Data3": ctypes.unsigned_short },
|
{ "Data3": ctypes.unsigned_short },
|
||||||
{ "Data4": ctypes.char.array(8) }
|
{ "Data4": ctypes.char.array(8) }
|
||||||
]),
|
]);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #define MAKEINTRESOURCEA(i) ((LPSTR)((ULONG_PTR)((WORD)(i))))
|
* #define MAKEINTRESOURCEA(i) ((LPSTR)((ULONG_PTR)((WORD)(i))))
|
||||||
* #define MAKEINTRESOURCEW(i) ((LPWSTR)((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);
|
return ctypes.jschar.array()(str);
|
||||||
},
|
};
|
||||||
|
|
||||||
ERROR_INVALID_WINDOW_HANDLE: 1400,
|
this.ERROR_INVALID_WINDOW_HANDLE = 1400;
|
||||||
ERROR_RESOURCE_TYPE_NOT_FOUND: 1813,
|
this.ERROR_RESOURCE_TYPE_NOT_FOUND = 1813;
|
||||||
|
|
||||||
// WinUser.h
|
// WinUser.h
|
||||||
WM_USER: 0x0400,
|
this.WM_USER = 0x0400;
|
||||||
|
this.WM_APP = 0x8000;
|
||||||
|
|
||||||
WM_CONTEXTMENU: 0x007B,
|
this.WM_CONTEXTMENU = 0x007B;
|
||||||
|
|
||||||
WM_MOUSEFIRST: 0x0200,
|
this.WM_MOUSEFIRST = 0x0200;
|
||||||
WM_MOUSEMOVE: 0x0200,
|
this.WM_MOUSEMOVE = 0x0200;
|
||||||
WM_LBUTTONDOWN: 0x0201,
|
this.WM_LBUTTONDOWN = 0x0201;
|
||||||
WM_LBUTTONUP: 0x0202,
|
this.WM_LBUTTONUP = 0x0202;
|
||||||
WM_LBUTTONDBLCLK: 0x0203,
|
this.WM_LBUTTONDBLCLK = 0x0203;
|
||||||
WM_RBUTTONDOWN: 0x0204,
|
this.WM_RBUTTONDOWN = 0x0204;
|
||||||
WM_RBUTTONUP: 0x0205,
|
this.WM_RBUTTONUP = 0x0205;
|
||||||
WM_RBUTTONDBLCLK: 0x0206,
|
this.WM_RBUTTONDBLCLK = 0x0206;
|
||||||
WM_MBUTTONDOWN: 0x0207,
|
this.WM_MBUTTONDOWN = 0x0207;
|
||||||
WM_MBUTTONUP: 0x0208,
|
this.WM_MBUTTONUP = 0x0208;
|
||||||
WM_MBUTTONDBLCLK: 0x0209,
|
this.WM_MBUTTONDBLCLK = 0x0209;
|
||||||
WM_MOUSEWHEEL: 0x020A,
|
this.WM_MOUSEWHEEL = 0x020A;
|
||||||
WM_XBUTTONDOWN: 0x020B,
|
this.WM_XBUTTONDOWN = 0x020B;
|
||||||
WM_XBUTTONUP: 0x020C,
|
this.WM_XBUTTONUP = 0x020C;
|
||||||
WM_XBUTTONDBLCLK: 0x020D,
|
this.WM_XBUTTONDBLCLK = 0x020D;
|
||||||
WM_MOUSELAST: 0x020D,
|
this.WM_MOUSELAST = 0x020D;
|
||||||
WM_MOUSELAST: 0x020A,
|
this.WM_MOUSELAST = 0x020A;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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
|
// 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
|
// "evolving" after a while (maybe due to back and forth conversion). So we
|
||||||
// need to store them into a real ctypes array !
|
// need to store them into a real ctypes array !
|
||||||
firetray.Handler.gtkWindows = new ctypesMap(gtk.GtkWindow.ptr),
|
firetray.Handler.gtkWindows = new ctypesMap(gtk.GtkWindow.ptr);
|
||||||
firetray.Handler.gdkWindows = new ctypesMap(gdk.GdkWindow.ptr),
|
firetray.Handler.gdkWindows = new ctypesMap(gdk.GdkWindow.ptr);
|
||||||
firetray.Handler.gtkPopupMenuWindowItems = new ctypesMap(gtk.GtkImageMenuItem.ptr),
|
firetray.Handler.gtkPopupMenuWindowItems = new ctypesMap(gtk.GtkImageMenuItem.ptr);
|
||||||
|
|
||||||
|
|
||||||
firetray.Window = new FiretrayWindow();
|
firetray.Window = new FiretrayWindow();
|
||||||
|
|
||||||
firetray.Window.signals = {'focus-in': {callback: {}, handler: {}}};
|
firetray.Window.signals = {'focus-in': {callback: {}, handler: {}}};
|
||||||
|
|
||||||
firetray.Window.init = function() {
|
firetray.Window.init = function() {
|
||||||
@ -187,7 +186,7 @@ firetray.Window.getGtkWindowFromGdkWindow = function(gdkWin) {
|
|||||||
return gtkw;
|
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) {
|
firetray.Window.getWindowsFromChromeWindow = function(win) {
|
||||||
let baseWin = firetray.Handler.getWindowInterface(win, "nsIBaseWindow");
|
let baseWin = firetray.Handler.getWindowInterface(win, "nsIBaseWindow");
|
||||||
let nativeHandle = baseWin.nativeHandle; // Moz' private pointer to the GdkWindow
|
let nativeHandle = baseWin.nativeHandle; // Moz' private pointer to the GdkWindow
|
||||||
@ -205,13 +204,6 @@ firetray.Window.getWindowsFromChromeWindow = function(win) {
|
|||||||
return [baseWin, gtkWin, gdkWin, xid];
|
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) {
|
firetray.Window.unregisterWindowByXID = function(xid) {
|
||||||
if (!firetray.Handler.windows.hasOwnProperty(xid)) {
|
if (!firetray.Handler.windows.hasOwnProperty(xid)) {
|
||||||
log.error("can't unregister unknown window "+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));
|
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) {
|
firetray.Handler.registerWindow = function(win) {
|
||||||
log.debug("register window");
|
log.debug("register window");
|
||||||
|
|
||||||
@ -713,7 +703,7 @@ firetray.Handler.registerWindow = function(win) {
|
|||||||
|
|
||||||
firetray.Handler.unregisterWindow = function(win) {
|
firetray.Handler.unregisterWindow = function(win) {
|
||||||
log.debug("unregister window");
|
log.debug("unregister window");
|
||||||
let xid = firetray.Window.getXIDFromChromeWindow(win);
|
let xid = firetray.Window.getRegisteredWinIdFromChromeWindow(win);
|
||||||
return firetray.Window.unregisterWindowByXID(xid);
|
return firetray.Window.unregisterWindowByXID(xid);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -20,9 +20,6 @@ Cu.import("resource://firetray/winnt/FiretrayWin32.jsm");
|
|||||||
Cu.import("resource://firetray/commons.js");
|
Cu.import("resource://firetray/commons.js");
|
||||||
firetray.Handler.subscribeLibsForClosing([kernel32, shell32, user32]);
|
firetray.Handler.subscribeLibsForClosing([kernel32, shell32, user32]);
|
||||||
|
|
||||||
const kMessageTray = "_FIRETRAY_TrayMessage";
|
|
||||||
const kMessageCallback = "_FIRETRAY_TrayCallback";
|
|
||||||
|
|
||||||
let log = firetray.Logging.getLogger("firetray.StatusIcon");
|
let log = firetray.Logging.getLogger("firetray.StatusIcon");
|
||||||
|
|
||||||
if ("undefined" == typeof(firetray.Handler))
|
if ("undefined" == typeof(firetray.Handler))
|
||||||
@ -33,7 +30,6 @@ firetray.StatusIcon = {
|
|||||||
initialized: false,
|
initialized: false,
|
||||||
callbacks: {}, // pointers to JS functions. MUST LIVE DURING ALL THE EXECUTION
|
callbacks: {}, // pointers to JS functions. MUST LIVE DURING ALL THE EXECUTION
|
||||||
notifyIconData: null,
|
notifyIconData: null,
|
||||||
msg: {WM_TASKBARCREATED:null, WM_TRAYMESSAGE:null, WM_TRAYCALLBACK:null},
|
|
||||||
hwndProxy: null,
|
hwndProxy: null,
|
||||||
WNDCLASS_NAME: "FireTrayHiddenWindowClass",
|
WNDCLASS_NAME: "FireTrayHiddenWindowClass",
|
||||||
WNDCLASS_ATOM: null,
|
WNDCLASS_ATOM: null,
|
||||||
@ -42,7 +38,6 @@ firetray.StatusIcon = {
|
|||||||
this.FILENAME_BLANK = firetray.Utils.chromeToPath(
|
this.FILENAME_BLANK = firetray.Utils.chromeToPath(
|
||||||
"chrome://firetray/skin/blank-icon.png");
|
"chrome://firetray/skin/blank-icon.png");
|
||||||
|
|
||||||
this.registerMessages();
|
|
||||||
this.create();
|
this.create();
|
||||||
|
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
@ -57,17 +52,6 @@ firetray.StatusIcon = {
|
|||||||
this.initialized = false;
|
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() {
|
create: function() {
|
||||||
let hwnd_hidden = this.createProxyWindow();
|
let hwnd_hidden = this.createProxyWindow();
|
||||||
|
|
||||||
@ -81,7 +65,7 @@ firetray.StatusIcon = {
|
|||||||
nid.szTip = firetray.Handler.appName;
|
nid.szTip = firetray.Handler.appName;
|
||||||
nid.hIcon = this.getIconFromWindow(hwnd_hidden_moz);
|
nid.hIcon = this.getIconFromWindow(hwnd_hidden_moz);
|
||||||
nid.hWnd = hwnd_hidden;
|
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.uFlags = shell32.NIF_ICON | shell32.NIF_MESSAGE | shell32.NIF_TIP;
|
||||||
nid.uVersion = shell32.NOTIFYICON_VERSION_4;
|
nid.uVersion = shell32.NOTIFYICON_VERSION_4;
|
||||||
|
|
||||||
@ -98,8 +82,6 @@ firetray.StatusIcon = {
|
|||||||
createProxyWindow: function() {
|
createProxyWindow: function() {
|
||||||
this.registerWindowClass();
|
this.registerWindowClass();
|
||||||
|
|
||||||
this.callbacks.hiddenWinProc = user32.WNDPROC(firetray.StatusIcon.proxyWindowProc);
|
|
||||||
|
|
||||||
let hwnd_hidden = user32.CreateWindowExW(
|
let hwnd_hidden = user32.CreateWindowExW(
|
||||||
0, win32.LPCTSTR(this.WNDCLASS_ATOM), // lpClassName can also be _T(WNDCLASS_NAME)
|
0, win32.LPCTSTR(this.WNDCLASS_ATOM), // lpClassName can also be _T(WNDCLASS_NAME)
|
||||||
"Firetray Message Window", 0,
|
"Firetray Message Window", 0,
|
||||||
@ -107,8 +89,18 @@ firetray.StatusIcon = {
|
|||||||
null, null, firetray.Win32.hInstance, null);
|
null, null, firetray.Win32.hInstance, null);
|
||||||
log.debug("CreateWindow="+!hwnd_hidden.isNull()+" winLastError="+ctypes.winLastError);
|
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,
|
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);
|
log.debug("procPrev="+procPrev+" winLastError="+ctypes.winLastError);
|
||||||
|
|
||||||
firetray.Win32.acceptAllMessages(hwnd_hidden);
|
firetray.Win32.acceptAllMessages(hwnd_hidden);
|
||||||
@ -126,13 +118,13 @@ firetray.StatusIcon = {
|
|||||||
log.debug("WNDCLASS_ATOM="+this.WNDCLASS_ATOM);
|
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);
|
// 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");
|
log.info("____________TASKBARCREATED");
|
||||||
|
|
||||||
} else if (uMsg === firetray.StatusIcon.msg.WM_TRAYMESSAGE) {
|
} else if (uMsg === firetray.Win32.WM_TRAYMESSAGE) {
|
||||||
|
|
||||||
switch (+lParam) {
|
switch (+lParam) {
|
||||||
case win32.WM_LBUTTONUP:
|
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);
|
return user32.DefWindowProcW(hWnd, uMsg, wParam, lParam);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -15,6 +15,9 @@ firetray.Handler.subscribeLibsForClosing([kernel32, user32]);
|
|||||||
|
|
||||||
let log = firetray.Logging.getLogger("firetray.Win32");
|
let log = firetray.Logging.getLogger("firetray.Win32");
|
||||||
|
|
||||||
|
const kMessageTray = "_FIRETRAY_TrayMessage";
|
||||||
|
const kMessageCallback = "_FIRETRAY_TrayCallback";
|
||||||
|
|
||||||
if ("undefined" == typeof(firetray.Handler))
|
if ("undefined" == typeof(firetray.Handler))
|
||||||
log.error("This module MUST be imported from/after FiretrayHandler !");
|
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
|
this.hInstance = kernel32.GetModuleHandleW("xul"); // ordinary windows are created from xul.dll
|
||||||
log.debug("hInstance="+this.hInstance);
|
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
|
/* if Administrator, accept messages from applications running in a lower
|
||||||
privilege level */
|
privilege level */
|
||||||
this.acceptAllMessages = function(hwnd) {
|
this.acceptAllMessages = function(hwnd) {
|
||||||
let rv = null;
|
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"]) {
|
if (win32.WINVER >= win32.WIN_VERSIONS["7"]) {
|
||||||
rv = user32.ChangeWindowMessageFilterEx(hwnd, firetray.Win32.WM_TASKBARCREATED, user32.MSGFLT_ALLOW, null);
|
rv = user32.ChangeWindowMessageFilterEx(hwnd, firetray.Win32.WM_TASKBARCREATED, user32.MSGFLT_ALLOW, null);
|
||||||
log.debug("ChangeWindowMessageFilterEx res="+rv+" winLastError="+ctypes.winLastError);
|
log.debug("ChangeWindowMessageFilterEx res="+rv+" winLastError="+ctypes.winLastError);
|
||||||
|
@ -6,8 +6,6 @@ const Cc = Components.classes;
|
|||||||
const Ci = Components.interfaces;
|
const Ci = Components.interfaces;
|
||||||
const Cu = Components.utils;
|
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://gre/modules/ctypes.jsm");
|
||||||
Cu.import("resource://firetray/ctypes/ctypesMap.jsm");
|
Cu.import("resource://firetray/ctypes/ctypesMap.jsm");
|
||||||
Cu.import("resource://firetray/ctypes/winnt/win32.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))
|
if ("undefined" == typeof(firetray.Handler))
|
||||||
log.error("This module MUST be imported from/after FiretrayHandler !");
|
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_HIDDEN = 1 << 0; // when minimized also
|
||||||
const FIRETRAY_XWINDOW_MAXIMIZED = 1 << 1;
|
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();
|
firetray.Window = new FiretrayWindow();
|
||||||
|
|
||||||
@ -59,6 +57,50 @@ firetray.Window.startupHide = function(xid) {
|
|||||||
firetray.Window.setVisibility = function(xid, visibility) {
|
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 /////////////////////////
|
///////////////////////// firetray.Handler overriding /////////////////////////
|
||||||
|
|
||||||
@ -66,13 +108,11 @@ firetray.Window.setVisibility = function(xid, visibility) {
|
|||||||
firetray.Handler.dumpWindows = function() {
|
firetray.Handler.dumpWindows = function() {
|
||||||
let dumpStr = ""+firetray.Handler.windowsCount;
|
let dumpStr = ""+firetray.Handler.windowsCount;
|
||||||
for (let wid in firetray.Handler.windows) {
|
for (let wid in firetray.Handler.windows) {
|
||||||
dumpStr += " 0x"+wid;
|
dumpStr += " "+wid;
|
||||||
}
|
}
|
||||||
log.info(dumpStr);
|
log.info(dumpStr);
|
||||||
};
|
};
|
||||||
|
|
||||||
firetray.Handler.getWindowIdFromChromeWindow = firetray.Window.getXIDFromChromeWindow;
|
|
||||||
|
|
||||||
firetray.Handler.registerWindow = function(win) {
|
firetray.Handler.registerWindow = function(win) {
|
||||||
log.debug("register window");
|
log.debug("register window");
|
||||||
|
|
||||||
@ -81,8 +121,7 @@ firetray.Handler.registerWindow = function(win) {
|
|||||||
let hwnd = nativeHandle ?
|
let hwnd = nativeHandle ?
|
||||||
new ctypes.voidptr_t(ctypes.UInt64(nativeHandle)) :
|
new ctypes.voidptr_t(ctypes.UInt64(nativeHandle)) :
|
||||||
user32.FindWindowW("MozillaWindowClass", win.document.title);
|
user32.FindWindowW("MozillaWindowClass", win.document.title);
|
||||||
// wid will be used as a string most of the time (through f.Handler.windows mainly)
|
let wid = firetray.Window.hwndToHexStr(hwnd);
|
||||||
let wid = ctypes.cast(hwnd, ctypes.uintptr_t).value.toString(16);
|
|
||||||
log.debug("=== hwnd="+hwnd+" wid="+wid+" win.document.title: "+win.document.title);
|
log.debug("=== hwnd="+hwnd+" wid="+wid+" win.document.title: "+win.document.title);
|
||||||
|
|
||||||
if (this.windows.hasOwnProperty(wid)) {
|
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
|
// NOTE: no need to check for window state to set visibility because all
|
||||||
// windows *are* shown at startup
|
// windows *are* shown at startup
|
||||||
firetray.Window.updateVisibility(wid, true);
|
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);
|
// NOTE: shouldn't be necessary to gtk_widget_add_events(gtkWin, gdk.GDK_ALL_EVENTS_MASK);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
try {
|
// try {
|
||||||
// NOTE: we could try to catch the "delete-event" here and block
|
try {
|
||||||
// delete_event_cb (in gtk2/nsWindow.cpp), but we prefer to use the
|
let wndProc = user32.WNDPROC(firetray.Window.wndProc);
|
||||||
// provided 'close' JS event
|
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)
|
||||||
|
|
||||||
this.windows[xid].filterWindowCb = gdk.GdkFilterFunc_t(firetray.Window.filterWindow);
|
procPrev = ctypes.cast(procPrev, win32.HANDLE);
|
||||||
gdk.gdk_window_add_filter(gdkWin, this.windows[xid].filterWindowCb, null);
|
user32.SetPropW(hwnd, win32._T(kPropProcPrev), procPrev);
|
||||||
if (!firetray.Handler.appStarted) {
|
log.debug("SetPropW: "+procPrev+" winLastError="+ctypes.winLastError);
|
||||||
this.windows[xid].startupFilterCb = gdk.GdkFilterFunc_t(firetray.Window.startupFilter);
|
} catch(error) {
|
||||||
gdk.gdk_window_add_filter(gdkWin, this.windows[xid].startupFilterCb, null);
|
log.error(error);
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
// 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();
|
log.debug("AFTER"); firetray.Handler.dumpWindows();
|
||||||
return wid;
|
return wid;
|
||||||
@ -138,8 +184,23 @@ firetray.Handler.registerWindow = function(win) {
|
|||||||
|
|
||||||
firetray.Handler.unregisterWindow = function(win) {
|
firetray.Handler.unregisterWindow = function(win) {
|
||||||
log.debug("unregister window");
|
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;
|
firetray.Handler.showWindow = firetray.Window.show;
|
||||||
|
Loading…
Reference in New Issue
Block a user