1
0
mirror of https://github.com/moparisthebest/FireTray synced 2025-01-08 12:08:05 -05:00

* un-/register windows (begin) => refactoring

* filter icon events (begin)
This commit is contained in:
foudfou 2013-11-24 14:25:27 +01:00
parent 5eaf647633
commit d52245cc87
6 changed files with 711 additions and 637 deletions

View File

@ -0,0 +1,32 @@
/* -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
// https://developer.mozilla.org/en/Code_snippets/Preferences
var EXPORTED_SYMBOLS = [ "FiretrayWindow" ];
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://firetray/commons.js");
let log = firetray.Logging.getLogger("firetray.FiretrayWindow");
if ("undefined" == typeof(firetray.Handler))
log.error("This module MUST be imported from/after FiretrayHandler !");
function FiretrayWindow () {}
FiretrayWindow.prototype = {
updateVisibility: function(winId, visibility) {
let win = firetray.Handler.windows[winId];
if (win.visible === visibility)
log.warn("window (winId="+winId+") was already visible="+win.visible);
firetray.Handler.visibleWindowsCount = visibility ?
firetray.Handler.visibleWindowsCount + 1 :
firetray.Handler.visibleWindowsCount - 1 ;
win.visible = visibility; // nsIBaseWin.visibility always true :-(
},
};

View File

@ -74,4 +74,33 @@ var win32 = {
ERROR_INVALID_WINDOW_HANDLE: 1400,
ERROR_RESOURCE_TYPE_NOT_FOUND: 1813,
// WinUser.h
WM_USER: 0x0400,
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,
};
// ShellAPI.h
let nin_select = win32.WM_USER + 0;
win32.NIN_SELECT = nin_select;
win32.NINF_KEY = 0x1;
win32.NIN_KEYSELECT = (win32.NIN_SELECT | win32.NINF_KEY);

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,8 @@
/* -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* The tray icon for the main app. We need a hidden proxy window as (1) we want
a unique icon, (2) the icon sends notifications to a single window. */
var EXPORTED_SYMBOLS = [ "firetray" ];
const Cc = Components.classes;
@ -17,6 +20,9 @@ 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))
@ -27,7 +33,8 @@ firetray.StatusIcon = {
initialized: false,
callbacks: {}, // pointers to JS functions. MUST LIVE DURING ALL THE EXECUTION
notifyIconData: null,
hwndHidden: null,
msg: {WM_TASKBARCREATED:null, WM_TRAYMESSAGE:null, WM_TRAYCALLBACK:null},
hwndProxy: null,
WNDCLASS_NAME: "FireTrayHiddenWindowClass",
WNDCLASS_ATOM: null,
@ -35,6 +42,7 @@ firetray.StatusIcon = {
this.FILENAME_BLANK = firetray.Utils.chromeToPath(
"chrome://firetray/skin/blank-icon.png");
this.registerMessages();
this.create();
this.initialized = true;
@ -49,8 +57,19 @@ 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.createHiddenWindow();
let hwnd_hidden = this.createProxyWindow();
// the Mozilla hidden window has the default Mozilla icon
let hwnd_hidden_moz = user32.FindWindowW("MozillaHiddenWindowClass", null);
@ -62,7 +81,7 @@ firetray.StatusIcon = {
nid.szTip = firetray.Handler.appName;
nid.hIcon = this.getIconFromWindow(hwnd_hidden_moz);
nid.hWnd = hwnd_hidden;
nid.uCallbackMessage = firetray.Win32.WM_TRAYMESSAGE;
nid.uCallbackMessage = this.msg.WM_TRAYMESSAGE;
nid.uFlags = shell32.NIF_ICON | shell32.NIF_MESSAGE | shell32.NIF_TIP;
nid.uVersion = shell32.NOTIFYICON_VERSION_4;
@ -73,13 +92,13 @@ firetray.StatusIcon = {
log.debug("Shell_NotifyIcon SETVERSION="+rv+" winLastError="+ctypes.winLastError);
this.notifyIconData = nid;
this.hwndHidden = hwnd_hidden;
this.hwndProxy = hwnd_hidden;
},
createHiddenWindow: function() {
createProxyWindow: function() {
this.registerWindowClass();
this.callbacks.hiddenWinProc = user32.WNDPROC(firetray.StatusIcon.hiddenWindowProc);
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)
@ -107,9 +126,31 @@ firetray.StatusIcon = {
log.debug("WNDCLASS_ATOM="+this.WNDCLASS_ATOM);
},
hiddenWindowProc: function(hWnd, uMsg, wParam, lParam) {
log.debug("HiddenWindowProc CALLED: hWnd="+hWnd+", uMsg="+uMsg+", wParam="+wParam+", lParam="+lParam);
// ... do something smart with this event!
proxyWindowProc: function(hWnd, uMsg, wParam, lParam) {
// log.debug("ProxyWindowProc CALLED: hWnd="+hWnd+", uMsg="+uMsg+", wParam="+wParam+", lParam="+lParam);
if (uMsg === firetray.StatusIcon.msg.WM_TASKBARCREATED) {
log.info("____________TASKBARCREATED");
} else if (uMsg === firetray.StatusIcon.msg.WM_TRAYMESSAGE) {
switch (+lParam) {
case win32.WM_LBUTTONUP:
log.debug("WM_LBUTTONUP");
break;
case win32.WM_RBUTTONUP:
log.debug("WM_RBUTTONUP");
break;
case win32.WM_CONTEXTMENU:
log.debug("WM_CONTEXTMENU");
break;
case win32.NIN_KEYSELECT:
log.debug("NIN_KEYSELECT");
break;
default:
}
}
return user32.DefWindowProcW(hWnd, uMsg, wParam, lParam);
},
@ -138,8 +179,8 @@ firetray.StatusIcon = {
return icon;
},
destroyHiddenWindow: function() {
let rv = user32.DestroyWindow(this.hwndHidden);
destroyProxyWindow: function() {
let rv = user32.DestroyWindow(this.hwndProxy);
rv = this.unregisterWindowClass();
log.debug("Hidden window removed");
@ -152,7 +193,7 @@ firetray.StatusIcon = {
destroy: function() {
let rv = shell32.Shell_NotifyIconW(shell32.NIM_DELETE, this.notifyIconData.address());
log.debug("Shell_NotifyIcon DELETE="+rv+" winLastError="+ctypes.winLastError);
this.destroyHiddenWindow();
this.destroyProxyWindow();
}
}; // firetray.StatusIcon

View File

@ -18,16 +18,7 @@ let log = firetray.Logging.getLogger("firetray.Win32");
if ("undefined" == typeof(firetray.Handler))
log.error("This module MUST be imported from/after FiretrayHandler !");
const kMessageTray = "_FIRETRAY_TrayMessage";
const kMessageCallback = "_FIRETRAY_TrayCallback";
function Win32Env() {
this.WM_TASKBARCREATED = user32.RegisterWindowMessageW("TaskbarCreated");
// We register this as well, as we cannot know which WM_USER values are
// already taken
this.WM_TRAYMESSAGE = user32.RegisterWindowMessageW(kMessageTray);
this.WM_TRAYCALLBACK = user32.RegisterWindowMessageW(kMessageCallback);
log.debug("WM_*="+this.WM_TASKBARCREATED+" "+this.WM_TRAYMESSAGE+" "+this.WM_TRAYCALLBACK);
this.hInstance = kernel32.GetModuleHandleW("xul"); // ordinary windows are created from xul.dll
log.debug("hInstance="+this.hInstance);

View File

@ -13,6 +13,7 @@ Cu.import("resource://firetray/ctypes/ctypesMap.jsm");
Cu.import("resource://firetray/ctypes/winnt/win32.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([user32]);
@ -32,47 +33,42 @@ XPCOMUtils.defineLazyServiceGetter(
const FIRETRAY_XWINDOW_HIDDEN = 1 << 0; // when minimized also
const FIRETRAY_XWINDOW_MAXIMIZED = 1 << 1;
// // 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.Window = new FiretrayWindow();
firetray.Window = {
signals: {'focus-in': {callback: {}, handler: {}}},
init: function() {
firetray.Window.init = function() {
this.initialized = true;
},
};
shutdown: function() {
this.initialized = false;
},
firetray.Window.shutdown = function() {
this.initialized = false;
};
show: function(xid) {
log.debug("show xid="+xid);
},
firetray.Window.show = function(xid) {
log.debug("show xid="+xid);
};
hide: function(xid) {
log.debug("hide");
},
firetray.Window.hide = function(xid) {
log.debug("hide");
};
startupHide: function(xid) {
log.debug('startupHide: '+xid);
},
firetray.Window.startupHide = function(xid) {
log.debug('startupHide: '+xid);
};
setVisibility: function(xid, visibility) {
},
}; // firetray.Window
firetray.Window.setVisibility = function(xid, visibility) {
};
///////////////////////// firetray.Handler overriding /////////////////////////
/** debug facility */
firetray.Handler.dumpWindows = function() {
log.debug(firetray.Handler.windowsCount);
for (let winId in firetray.Handler.windows) log.info(winId+"="+firetray.Handler.gtkWindows.get(winId));
let dumpStr = ""+firetray.Handler.windowsCount;
for (let wid in firetray.Handler.windows) {
dumpStr += " 0x"+wid;
}
log.info(dumpStr);
};
firetray.Handler.getWindowIdFromChromeWindow = firetray.Window.getXIDFromChromeWindow;
@ -85,38 +81,33 @@ firetray.Handler.registerWindow = function(win) {
let hwnd = nativeHandle ?
new ctypes.voidptr_t(ctypes.UInt64(nativeHandle)) :
user32.FindWindowW("MozillaWindowClass", win.document.title);
log.debug("=== hwnd="+hwnd);
// 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);
log.debug("=== hwnd="+hwnd+" wid="+wid+" win.document.title: "+win.document.title);
if (this.windows.hasOwnProperty(wid)) {
let msg = "Window ("+wid+") already registered.";
log.error(msg);
Cu.reportError(msg);
return false;
}
this.windows[wid] = {};
this.windows[wid].chromeWin = win;
this.windows[wid].baseWin = baseWin;
// SetupWnd(hwnd);
// ::SetPropW(hwnd, kIconData, reinterpret_cast<HANDLE>(iconData));
// ::SetPropW(hwnd, kIconMouseEventProc, reinterpret_cast<HANDLE>(callback));
// ::SetPropW(hwnd, kIcon, reinterpret_cast<HANDLE>(0x1));
return;
// register
let [whndbaseWin, gtkWin, gdkWin, xid] = firetray.Window.getWindowsFromChromeWindow(win);
this.windows[xid] = {};
this.windows[xid].chromeWin = win;
this.windows[xid].baseWin = baseWin;
firetray.Window.checkSubscribedEventMasks(xid);
try {
this.gtkWindows.insert(xid, gtkWin);
this.gdkWindows.insert(xid, gdkWin);
firetray.PopupMenu.addWindowItem(xid);
} 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+".");
}
this.windowsCount += 1;
// NOTE: no need to check for window state to set visibility because all
// windows *are* shown at startup
firetray.Window.updateVisibility(xid, true);
log.debug("window "+xid+" registered");
firetray.Window.updateVisibility(wid, true);
log.debug("window 0x"+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
@ -139,9 +130,10 @@ firetray.Handler.registerWindow = function(win) {
log.error(x);
return null;
}
*/
log.debug("AFTER"); firetray.Handler.dumpWindows();
return xid;
return wid;
};
firetray.Handler.unregisterWindow = function(win) {