[Pkg-mozext-commits] [firetray] 47/84: Add 'start_hidden' capability for winnt.
David Prévot
taffit at moszumanska.debian.org
Sun Jul 20 01:42:45 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 f1c5c02c8fc2d22d4ee0f208c66e99722f04879c
Author: foudfou <foudil.newbie+git at gmail.com>
Date: Sat Apr 12 15:16:09 2014 +0200
Add 'start_hidden' capability for winnt.
---
src/chrome/content/options.js | 4 +-
src/chrome/content/overlay.js | 1 -
src/modules/FiretrayHandler.jsm | 4 +-
src/modules/ctypes/winnt/user32.jsm | 13 ++++
src/modules/ctypes/winnt/win32.jsm | 15 ++++
src/modules/linux/FiretrayWindow.jsm | 3 +
src/modules/winnt/FiretrayStatusIcon.jsm | 5 +-
src/modules/winnt/FiretrayWin32.jsm | 3 +-
src/modules/winnt/FiretrayWindow.jsm | 120 +++++++++++++++++++++++--------
9 files changed, 128 insertions(+), 40 deletions(-)
diff --git a/src/chrome/content/options.js b/src/chrome/content/options.js
index ffe619e..eca0060 100644
--- a/src/chrome/content/options.js
+++ b/src/chrome/content/options.js
@@ -68,8 +68,8 @@ var firetrayUIOptions = {
hideUnsupportedOptions: function() { // full_feat
// windows prefs
- ['ui_hides_last_only', 'ui_start_hidden', 'ui_show_activates',
- 'ui_remember_desktop'].forEach(function(id){
+ ['ui_hides_last_only', 'ui_show_activates', 'ui_remember_desktop']
+ .forEach(function(id){
document.getElementById(id).hidden = true;
});
diff --git a/src/chrome/content/overlay.js b/src/chrome/content/overlay.js
index f65306e..7f92236 100644
--- a/src/chrome/content/overlay.js
+++ b/src/chrome/content/overlay.js
@@ -143,7 +143,6 @@ var firetrayChrome = { // each new window gets a new firetrayChrome !
}
}
-
};
// should be sufficient for a delayed Startup (no need for window.setTimeout())
diff --git a/src/modules/FiretrayHandler.jsm b/src/modules/FiretrayHandler.jsm
index 88c4541..06fdf31 100644
--- a/src/modules/FiretrayHandler.jsm
+++ b/src/modules/FiretrayHandler.jsm
@@ -319,7 +319,7 @@ firetray.Handler = {
} else {
for (let winId in firetray.Handler.windows) {
firetray.Chat.detachSelectListeners(firetray.Handler.windows[winId].chromeWin);
- firetray.ChatStatusIcon.detachOnFocusInCallback(winId);
+ firetray.ChatStatusIcon.detachOnFocusInCallback(winId); // FIXME: to be removed
}
firetray.Chat.shutdown();
}
@@ -709,7 +709,7 @@ firetray.VersionChangeHandler = {
"hide_show_mm_key", "accounts_to_exclude" ];
let v0_4_0b2_Opts = [ 'mail_notification' ];
let v0_5_0b1_Opts = [ 'mail_urgency_hint', 'app_icon_filename', 'custom_mail_icon' ];
- let oldOpt = v0_3_Opts.concat(v0_4_0b2_Opts).concat(v0_5_0b1_Opts);
+ let oldOpts = v0_3_Opts.concat(v0_4_0b2_Opts).concat(v0_5_0b1_Opts);
for (let i = 0, length = oldOpts.length; i<length; ++i) {
try {
diff --git a/src/modules/ctypes/winnt/user32.jsm b/src/modules/ctypes/winnt/user32.jsm
index 8f4c783..103a68f 100644
--- a/src/modules/ctypes/winnt/user32.jsm
+++ b/src/modules/ctypes/winnt/user32.jsm
@@ -362,6 +362,19 @@ function user32_defines(lib) {
lib.lazy_bind("GetCursorPos", win32.BOOL, win32.LPPOINT);
lib.lazy_bind("GetMessagePos", win32.DWORD);
+ this.WINDOWPLACEMENT = ctypes.StructType("WINDOWPLACEMENT", [
+ { "length": win32.UINT },
+ { "flags": win32.UINT },
+ { "showCmd": win32.UINT },
+ { "ptMinPosition": win32.POINT },
+ { "ptMaxPosition": win32.POINT },
+ { "rcNormalPosition": win32.RECT }
+ ]);
+ this.PWINDOWPLACEMENT = this.LPWINDOWPLACEMENT = 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);
+
}
new ctypes_library(USER32_LIBNAME, USER32_ABIS, user32_defines, this);
diff --git a/src/modules/ctypes/winnt/win32.jsm b/src/modules/ctypes/winnt/win32.jsm
index 00be95f..15b57d6 100644
--- a/src/modules/ctypes/winnt/win32.jsm
+++ b/src/modules/ctypes/winnt/win32.jsm
@@ -121,6 +121,15 @@ var win32 = new function() {
this.WM_SHOWWINDOW = 0x0018;
this.WM_WININICHANGE = 0x001A;
this.WM_SETTINGCHANGE = this.WM_WININICHANGE;
+ this.WM_DEVMODECHANGE = 0x001B;
+ this.WM_ACTIVATEAPP = 0x001C;
+ this.WM_FONTCHANGE = 0x001D;
+ this.WM_TIMECHANGE = 0x001E;
+ this.WM_CANCELMODE = 0x001F;
+ this.WM_SETCURSOR = 0x0020;
+ this.WM_MOUSEACTIVATE = 0x0021;
+ this.WM_CHILDACTIVATE = 0x0022;
+ this.WM_QUEUESYNC = 0x0023;
this.WM_COMMAND = 0x0111;
this.WM_SYSCOMMAND = 0x0112;
this.WM_HSCROLL = 0x0114;
@@ -153,6 +162,12 @@ var win32 = new function() {
this.SC_MINIMIZE = 0xF020;
this.SC_CLOSE = 0xF060;
+ this.SIZE_RESTORED = 0;
+ this.SIZE_MINIMIZED = 1;
+ this.SIZE_MAXIMIZED = 2;
+ this.SIZE_MAXSHOW = 3;
+ this.SIZE_MAXHIDE = 4;
+
this.BITMAP = ctypes.StructType("BITMAP", [
{ "bmType": this.LONG },
{ "bmWidth": this.LONG },
diff --git a/src/modules/linux/FiretrayWindow.jsm b/src/modules/linux/FiretrayWindow.jsm
index 040c9f0..796ca8f 100644
--- a/src/modules/linux/FiretrayWindow.jsm
+++ b/src/modules/linux/FiretrayWindow.jsm
@@ -563,6 +563,9 @@ firetray.Window.startupFilter = function(xev, gdkEv, data) {
let xany = ctypes.cast(xev, x11.XAnyEvent.ptr);
let xid = xany.contents.window;
+ // MapRequest already taken by window manager. Not sure we could be notified
+ // *before* the window is actually mapped, in order to minimize it before
+ // it's shown.
if (xany.contents.type === x11.MapNotify) {
gdk.gdk_window_remove_filter(firetray.Handler.gdkWindows.get(xid),
firetray.Handler.windows[xid].startupFilterCb, null);
diff --git a/src/modules/winnt/FiretrayStatusIcon.jsm b/src/modules/winnt/FiretrayStatusIcon.jsm
index f2fb13b..c901243 100644
--- a/src/modules/winnt/FiretrayStatusIcon.jsm
+++ b/src/modules/winnt/FiretrayStatusIcon.jsm
@@ -228,12 +228,11 @@ firetray.StatusIcon = {
proxyWndProc: function(hWnd, uMsg, wParam, lParam) {
// log.debug("ProxyWindowProc CALLED: hWnd="+hWnd+", uMsg="+uMsg+", wParam="+wParam+", lParam="+lParam);
+ // FIXME: WM_TASKBARCREATED is needed in case of explorer crash
+ // http://twigstechtips.blogspot.fr/2011/02/c-detect-when-windows-explorer-has.html
if (uMsg === firetray.Win32.WM_TASKBARCREATED) {
log.info("____________TASKBARCREATED");
- } else if (uMsg === firetray.Win32.WM_TRAYMESSAGEFWD) {
- log.debug("ProxyWindowProc WM_TRAYMESSAGEFWD reached!");
-
} else if (uMsg === firetray.Win32.WM_TRAYMESSAGE) {
switch (win32.LOWORD(lParam)) {
diff --git a/src/modules/winnt/FiretrayWin32.jsm b/src/modules/winnt/FiretrayWin32.jsm
index 0d7c279..ea03459 100644
--- a/src/modules/winnt/FiretrayWin32.jsm
+++ b/src/modules/winnt/FiretrayWin32.jsm
@@ -16,11 +16,11 @@ firetray.Handler.subscribeLibsForClosing([kernel32, user32]);
let log = firetray.Logging.getLogger("firetray.Win32");
const kMessageTray = "_FIRETRAY_Tray";
-const kMessageTrayFwd = "_FIRETRAY_TrayFwd";
if ("undefined" == typeof(firetray.Handler))
log.error("This module MUST be imported from/after FiretrayHandler !");
+
function Win32Env() {
this.hInstance = kernel32.GetModuleHandleW("xul"); // ordinary windows are created from xul.dll
@@ -29,7 +29,6 @@ function Win32Env() {
// we use our own messages because we create a different window class than Moz
this.WM_TASKBARCREATED = user32.RegisterWindowMessageW("TaskbarCreated");
this.WM_TRAYMESSAGE = user32.RegisterWindowMessageW(kMessageTray);
- this.WM_TRAYMESSAGEFWD = user32.RegisterWindowMessageW(kMessageTrayFwd);
log.debug("WM_*="+this.WM_TASKBARCREATED+" "+this.WM_TRAYMESSAGE+" "+this.WM_TRAYCALLBACK);
/* if Administrator, accept messages from applications running in a lower
diff --git a/src/modules/winnt/FiretrayWindow.jsm b/src/modules/winnt/FiretrayWindow.jsm
index 7750dab..d4999c7 100644
--- a/src/modules/winnt/FiretrayWindow.jsm
+++ b/src/modules/winnt/FiretrayWindow.jsm
@@ -8,12 +8,13 @@ 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/ctypes/winnt/win32.jsm");
Cu.import("resource://firetray/winnt/FiretrayWin32.jsm");
Cu.import("resource://firetray/FiretrayWindow.jsm");
Cu.import("resource://firetray/commons.js");
-firetray.Handler.subscribeLibsForClosing([user32]);
+firetray.Handler.subscribeLibsForClosing([user32, kernel32]);
let log = firetray.Logging.getLogger("firetray.Window");
@@ -25,8 +26,10 @@ const FIRETRAY_XWINDOW_MAXIMIZED = 1 << 1;
// 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.Handler.wndProcs = new ctypesMap(user32.WNDPROC);
+firetray.Handler.wndProcsOrig = new ctypesMap(user32.WNDPROC);
+firetray.Handler.procHooks = new ctypesMap(win32.HHOOK);
+firetray.Handler.procHooksRegistred = new ctypesMap(win32.HHOOK);
firetray.Window = new FiretrayWindow();
@@ -54,23 +57,10 @@ firetray.Window.setVisibility = function(wid, visible) {
};
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=0x"+uMsg.toString(16)+", wParam="+wParam+", lParam="+lParam);
let wid = firetray.Win32.hwndToHexStr(hWnd);
- if (uMsg === firetray.Win32.WM_TRAYMESSAGE) {
- log.debug("wndProc CALLED with WM_TRAYMESSAGE");
-
- } else if (uMsg === firetray.Win32.WM_TRAYMESSAGEFWD) {
- log.debug("wndProc CALLED with WM_TRAYMESSAGEFWD");
-
- } else if (uMsg === win32.WM_USER) {
- log.debug("wndProc CALLED with WM_USER");
-
- } else if (uMsg === win32.WM_CLOSE) {
- log.debug("wndProc CALLED with WM_CLOSE");
-
- } else if (uMsg === win32.WM_SYSCOMMAND) {
- // FIXME: not work with window.minimize() (menubar hidden)
+ if (uMsg === win32.WM_SYSCOMMAND) {
log.debug("wndProc CALLED with WM_SYSCOMMAND wParam="+wParam);
if (wParam === win32.SC_MINIMIZE) {
log.debug("GOT ICONIFIED");
@@ -78,19 +68,65 @@ firetray.Window.wndProc = function(hWnd, uMsg, wParam, lParam) { // filterWindow
return 0; // processed => preventDefault
}
}
+ }
- } else if (uMsg === win32.WM_DESTROY) {
- log.debug("wndProc CALLED with WM_DESTROY "+wid);
+ let procPrev = firetray.Handler.wndProcsOrig.get(wid);
+ return user32.CallWindowProcW(procPrev, hWnd, uMsg, wParam, lParam); // or DefWindowProcW
+};
- } else if (uMsg === win32.WM_MOVE) {
- log.debug("wndProc CALLED with WM_MOVE "+wid);
+// We could chain wndProcs, but adding a hook looks simpler.
+firetray.Window.showCount = 0;
+firetray.Window.startupHook = function(nCode, wParam, lParam) { // WH_CALLWNDPROC, WH_GETMESSAGE
+ // log.debug("startupHook CALLED: nCode="+nCode+", wParam="+wParam+", lParam="+lParam);
+ if (nCode < 0) return user32.CallNextHookEx(null, nCode, wParam, lParam); // user32.HC_ACTION
+
+ let cwpstruct = ctypes.cast(win32.LPARAM(lParam), user32.CWPSTRUCT.ptr).contents;
+ let uMsg = cwpstruct.message;
+ let hwnd = cwpstruct.hwnd;
+ let wid = firetray.Win32.hwndToHexStr(hwnd);
+ let wparam = cwpstruct.wParam;
+ let lparam = cwpstruct.lParam;
+
+ if (uMsg === win32.WM_SHOWWINDOW && wparam == 1 && lparam == 0) { // shown and ShowWindow called
+ log.debug("startupHook CALLED with WM_SHOWWINDOW wparam="+wparam+" lparam="+lparam);
+ firetray.Window.showCount += 1;
+
+ if (firetray.Utils.prefService.getBoolPref('start_hidden')) {
+ log.debug("start_hidden");
+
+ /* Compared to ShowWindow, SetWindowPlacement seems to bypass window
+ animations. http://stackoverflow.com/a/6087214 */
+ let placement = new user32.WINDOWPLACEMENT;
+ let ret = user32.GetWindowPlacement(hwnd, placement.address());
+ log.debug(" GetWindowPlacement="+ret+" winLastError="+ctypes.winLastError);
+ log.debug(" PLACEMENT="+placement);
+
+ if (firetray.Window.showCount < 2) {
+ // we can't prevent ShowWindow, so we mitigate the effect by minimizing
+ // 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);
+ }
- } else if (uMsg === win32.WM_ACTIVATE) {
- log.debug("wndProc CALLED with WM_ACTIVATE "+wid);
}
- let procPrev = firetray.Handler.wndProcsOrig.get(wid);
- return user32.CallWindowProcW(procPrev, hWnd, uMsg, wParam, lParam); // or DefWindowProcW
+ return user32.CallNextHookEx(null, nCode, wParam, lParam);
};
firetray.Window.attachWndProc = function(wid, hwnd) {
@@ -103,8 +139,8 @@ firetray.Window.attachWndProc = function(wid, hwnd) {
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.
+ /* we can't store WNDPROC callbacks (JS ctypes objects) with SetPropW(), as
+ we need long-living refs. */
firetray.Handler.wndProcsOrig.insert(wid, procPrev);
} catch (x) {
@@ -135,6 +171,28 @@ firetray.Window.detachWndProc = function(wid) {
firetray.Handler.wndProcsOrig.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);
+};
+
///////////////////////// firetray.Handler overriding /////////////////////////
@@ -170,10 +228,12 @@ firetray.Handler.registerWindow = function(win) {
Object.defineProperties(this.windows[wid], {
"visible": { get: function(){return firetray.Window.getVisibility(wid);} }
});
-
log.debug("window "+wid+" registered");
firetray.Window.attachWndProc(wid, hwnd);
+ if (!firetray.Handler.appStarted) {
+ firetray.Window.attachHook(wid);
+ }
firetray.Win32.acceptAllMessages(hwnd);
--
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