From bd3f894a15f3961217e741fb30060e829b341141 Mon Sep 17 00:00:00 2001 From: foudfou Date: Sun, 9 Nov 2014 20:28:16 +0100 Subject: [PATCH 1/2] Winnt: fix start_hidden when startup minimized or maximized. --- src/modules/ctypes/winnt/kernel32.jsm | 24 +++++++++++++ src/modules/ctypes/winnt/user32.jsm | 17 +++++++++ src/modules/ctypes/winnt/win32.jsm | 1 + src/modules/winnt/FiretrayWindow.jsm | 50 ++++++++++++++++++++++----- 4 files changed, 84 insertions(+), 8 deletions(-) diff --git a/src/modules/ctypes/winnt/kernel32.jsm b/src/modules/ctypes/winnt/kernel32.jsm index f6c6b02..70daa2b 100644 --- a/src/modules/ctypes/winnt/kernel32.jsm +++ b/src/modules/ctypes/winnt/kernel32.jsm @@ -35,6 +35,30 @@ function kernel32_defines(lib) { lib.lazy_bind("GetProcAddress", win32.FARPROC, win32.HMODULE, win32.LPCSTR); lib.lazy_bind("GetCurrentThreadId", win32.DWORD); + this.STARTUPINFO = ctypes.StructType("STARTUPINFO", [ + { "cb": win32.DWORD }, + { "lpReserved": win32.LPTSTR }, + { "lpDesktop": win32.LPTSTR }, + { "lpTitle": win32.LPTSTR }, + { "dwX": win32.DWORD }, + { "dwY": win32.DWORD }, + { "dwXSize": win32.DWORD }, + { "dwYSize": win32.DWORD }, + { "dwXCountChars": win32.DWORD }, + { "dwYCountChars": win32.DWORD }, + { "dwFillAttribute": win32.DWORD }, + { "dwFlags": win32.DWORD }, + { "wShowWindow": win32.WORD }, + { "cbReserved2": win32.WORD }, + { "lpReserved2": win32.LPBYTE }, + { "hStdInput": win32.HANDLE }, + { "hStdOutput": win32.HANDLE }, + { "hStdError": win32.HANDLE } + ]); + this.LPSTARTUPINFO = ctypes.PointerType(this.STARTUPINFO); + + lib.lazy_bind("GetStartupInfoW", ctypes.void_t, this.LPSTARTUPINFO); + } new ctypes_library(KERNEL32_LIBNAME, KERNEL32_ABIS, kernel32_defines, this); diff --git a/src/modules/ctypes/winnt/user32.jsm b/src/modules/ctypes/winnt/user32.jsm index d29022e..e5f6ad4 100644 --- a/src/modules/ctypes/winnt/user32.jsm +++ b/src/modules/ctypes/winnt/user32.jsm @@ -372,6 +372,22 @@ function user32_defines(lib) { lib.lazy_bind("GetCursorPos", win32.BOOL, win32.LPPOINT); lib.lazy_bind("GetMessagePos", win32.DWORD); + this.WINDOWINFO = ctypes.StructType("WINDOWINFO", [ + { "cbSize": win32.DWORD }, + { "rcWindow": win32.RECT }, + { "rcClient": win32.RECT }, + { "dwStyle": win32.DWORD }, + { "dwExStyle": win32.DWORD }, + { "dwWindowStatus": win32.DWORD }, + { "cxWindowBorders": win32.UINT }, + { "cyWindowBorders": win32.UINT }, + { "atomWindowType": win32.ATOM }, + { "wCreatorVersion": win32.WORD } + ]); + this.PWINDOWINFO = this.LPWINDOWINFO = this.WINDOWINFO.ptr; + + lib.lazy_bind("GetWindowInfo", win32.BOOL, win32.HWND, this.WINDOWINFO.ptr); + this.WINDOWPLACEMENT = ctypes.StructType("WINDOWPLACEMENT", [ { "length": win32.UINT }, { "flags": win32.UINT }, @@ -411,6 +427,7 @@ function user32_defines(lib) { this.SWP_NOREPOSITION = this.SWP_NOOWNERZORDER; this.SWP_DEFERERASE = 0x2000; this.SWP_ASYNCWINDOWPOS = 0x4000; + this.SWP_STATECHANGED = 0x8000; /* Undocumented */ lib.lazy_bind("GetSysColor", win32.DWORD, ctypes.int); this.COLOR_MENU = 4; diff --git a/src/modules/ctypes/winnt/win32.jsm b/src/modules/ctypes/winnt/win32.jsm index ca5e17b..8f269a1 100644 --- a/src/modules/ctypes/winnt/win32.jsm +++ b/src/modules/ctypes/winnt/win32.jsm @@ -21,6 +21,7 @@ var win32 = new function() { this.BOOL = ctypes.bool; this.BYTE = ctypes.unsigned_char; + this.LPBYTE = this.BYTE.ptr; this.INT_PTR = is64bit ? ctypes.int64_t : ctypes.int; this.UINT = ctypes.unsigned_int; this.UINT_PTR = is64bit ? ctypes.uint64_t : ctypes.unsigned_int; diff --git a/src/modules/winnt/FiretrayWindow.jsm b/src/modules/winnt/FiretrayWindow.jsm index 931e3b0..331e9d5 100644 --- a/src/modules/winnt/FiretrayWindow.jsm +++ b/src/modules/winnt/FiretrayWindow.jsm @@ -70,7 +70,8 @@ firetray.Window.wndProc = function(hWnd, uMsg, wParam, lParam) { // filterWindow } let procPrev = firetray.Handler.wndProcsOrig.get(wid); - return user32.CallWindowProcW(user32.WNDPROC(procPrev), hWnd, uMsg, wParam, lParam); // or DefWindowProcW + return user32.CallWindowProcW( + user32.WNDPROC(procPrev), hWnd, uMsg, wParam, lParam); // or DefWindowProcW }; /* @@ -81,22 +82,39 @@ firetray.Window.wndProc = function(hWnd, uMsg, wParam, lParam) { // filterWindow * - 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); if (uMsg === win32.WM_WINDOWPOSCHANGING) { - let posStruct = ctypes.cast(win32.LPARAM(lParam), user32.WINDOWPOS.ptr).contents; + let posStruct = ctypes.cast(win32.LPARAM(lParam), + user32.WINDOWPOS.ptr).contents; + + // let stateChanged = ((posStruct.flags & user32.SWP_STATECHANGED) != 0); + // if (!firetray.Window.startup.minimized && stateChanged) { // run minimized/maximized + // Cu.reportError(" stateChanged"); + // let info = new user32.WINDOWINFO; + // let ret = user32.GetWindowInfo(hWnd, info.address()); + // Cu.reportError(" hWnd="+hWnd+" uMsg="+uMsg+" dwStyle="+info.dwStyle); + // firetray.Window.startup.minimized = ((info.dwStyle & user32.WS_MINIMIZE) != 0); + // Cu.reportError(" minimized="+firetray.Window.startup.minimized); + // posStruct.flags &= user32.SWP_NOSIZE|user32.SWP_NOMOVE; + // // return 1; + // } + let isShowing = ((posStruct.flags & user32.SWP_SHOWWINDOW) != 0); if (isShowing) { log.debug("wndProcStartup CALLED with WM_WINDOWPOSCHANGING/SWP_SHOWWINDOW"); - firetray.Window.startupShowCount += 1; + firetray.Window.startup.showCount += 1; - if (firetray.Window.startupShowCount < 2) { // hide + if (firetray.Window.startup.showCount < 2) { // hide log.debug("start_hidden"); - // Modifying a JS posStruct field does really modify the WINDOWPOS C - // struct behind lParam ! - posStruct.flags &= ~user32.SWP_SHOWWINDOW; + // Modifying posStruct is modifying lParam, which is passed onwards! + if (firetray.Window.startup.showSpecial) { + posStruct.flags &= user32.SWP_NOSIZE|user32.SWP_NOMOVE; + } + else { + posStruct.flags &= ~user32.SWP_SHOWWINDOW; + } let force = true; firetray.Handler.addPopupMenuWindowItemAndSeparatorMaybe(wid, force); } @@ -108,7 +126,16 @@ firetray.Window.wndProcStartup = function(hWnd, uMsg, wParam, lParam) { mapBak: null }); firetray.Handler.wndProcsStartup.remove(wid); + + if (firetray.Window.startup.showSpecial) { + let placement = new user32.WINDOWPLACEMENT; + let ret = user32.GetWindowPlacement(hWnd, placement.address()); + firetray.js.assert(ret, "GetWindowPlacement failed."); + placement.showCmd = firetray.Window.startup.showSpecial; + user32.SetWindowPlacement(hWnd, placement.address()); + } } + } } @@ -197,6 +224,13 @@ firetray.Handler.registerWindow = function(win) { let proc, map; if (!firetray.Handler.appStarted && firetray.Utils.prefService.getBoolPref('start_hidden')) { + let startupInfo = new kernel32.STARTUPINFO; + kernel32.GetStartupInfoW(startupInfo.address()); + let showSpecial = ([ + user32.SW_SHOWMINNOACTIVE, user32.SW_SHOWMINIMIZED, + user32.SW_SHOWMAXIMIZED + ].indexOf(startupInfo.wShowWindow) > -1) ? startupInfo.wShowWindow : 0; + firetray.Window.startup = {showCount: 0, showSpecial: showSpecial}; proc = firetray.Window.wndProcStartup; map = firetray.Handler.wndProcsStartup; } else { proc = firetray.Window.wndProc; map = firetray.Handler.wndProcs; From 4beb428492a1aa3dae528293b9711595483c273f Mon Sep 17 00:00:00 2001 From: foudfou Date: Sun, 9 Nov 2014 20:32:07 +0100 Subject: [PATCH 2/2] Cleaning. --- src/modules/winnt/FiretrayWindow.jsm | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/modules/winnt/FiretrayWindow.jsm b/src/modules/winnt/FiretrayWindow.jsm index 331e9d5..3d63355 100644 --- a/src/modules/winnt/FiretrayWindow.jsm +++ b/src/modules/winnt/FiretrayWindow.jsm @@ -89,18 +89,6 @@ firetray.Window.wndProcStartup = function(hWnd, uMsg, wParam, lParam) { let posStruct = ctypes.cast(win32.LPARAM(lParam), user32.WINDOWPOS.ptr).contents; - // let stateChanged = ((posStruct.flags & user32.SWP_STATECHANGED) != 0); - // if (!firetray.Window.startup.minimized && stateChanged) { // run minimized/maximized - // Cu.reportError(" stateChanged"); - // let info = new user32.WINDOWINFO; - // let ret = user32.GetWindowInfo(hWnd, info.address()); - // Cu.reportError(" hWnd="+hWnd+" uMsg="+uMsg+" dwStyle="+info.dwStyle); - // firetray.Window.startup.minimized = ((info.dwStyle & user32.WS_MINIMIZE) != 0); - // Cu.reportError(" minimized="+firetray.Window.startup.minimized); - // posStruct.flags &= user32.SWP_NOSIZE|user32.SWP_NOMOVE; - // // return 1; - // } - let isShowing = ((posStruct.flags & user32.SWP_SHOWWINDOW) != 0); if (isShowing) { log.debug("wndProcStartup CALLED with WM_WINDOWPOSCHANGING/SWP_SHOWWINDOW"); @@ -135,8 +123,8 @@ firetray.Window.wndProcStartup = function(hWnd, uMsg, wParam, lParam) { user32.SetWindowPlacement(hWnd, placement.address()); } } - } + } let procPrev = firetray.Handler.wndProcsOrig.get(wid);