зеркало из https://github.com/mozilla/gecko-dev.git
Bug 548763 - Show download progress in OS X app dock icon. r=dao r=josh
--HG-- rename : widget/tests/taskbar_progress.xul => widget/tests/test_taskbar_progress.xul
This commit is contained in:
Родитель
092affd5c4
Коммит
107c52d281
|
@ -1486,14 +1486,9 @@ var gBrowserInit = {
|
||||||
// downloads will start right away, and getting the service again won't hurt.
|
// downloads will start right away, and getting the service again won't hurt.
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
Services.downloads;
|
Services.downloads;
|
||||||
|
let DownloadTaskbarProgress =
|
||||||
#ifdef XP_WIN
|
Cu.import("resource://gre/modules/DownloadTaskbarProgress.jsm", {}).DownloadTaskbarProgress;
|
||||||
if (Win7Features) {
|
DownloadTaskbarProgress.onBrowserWindowLoad(window);
|
||||||
let DownloadTaskbarProgress =
|
|
||||||
Cu.import("resource://gre/modules/DownloadTaskbarProgress.jsm", {}).DownloadTaskbarProgress;
|
|
||||||
DownloadTaskbarProgress.onBrowserWindowLoad(window);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}, 10000);
|
}, 10000);
|
||||||
|
|
||||||
// The object handling the downloads indicator is also initialized here in the
|
// The object handling the downloads indicator is also initialized here in the
|
||||||
|
|
|
@ -14,13 +14,21 @@ this.EXPORTED_SYMBOLS = [
|
||||||
const Cc = Components.classes;
|
const Cc = Components.classes;
|
||||||
const Ci = Components.interfaces;
|
const Ci = Components.interfaces;
|
||||||
|
|
||||||
const kTaskbarID = "@mozilla.org/windows-taskbar;1";
|
const kTaskbarIDWin = "@mozilla.org/windows-taskbar;1";
|
||||||
|
const kTaskbarIDMac = "@mozilla.org/widget/macdocksupport;1";
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//// DownloadTaskbarProgress Object
|
//// DownloadTaskbarProgress Object
|
||||||
|
|
||||||
this.DownloadTaskbarProgress =
|
this.DownloadTaskbarProgress =
|
||||||
{
|
{
|
||||||
|
init: function DTP_init()
|
||||||
|
{
|
||||||
|
if (DownloadTaskbarProgressUpdater) {
|
||||||
|
DownloadTaskbarProgressUpdater._init();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a browser window appears. This has an effect only when we
|
* Called when a browser window appears. This has an effect only when we
|
||||||
* don't already have an active window.
|
* don't already have an active window.
|
||||||
|
@ -31,6 +39,7 @@ this.DownloadTaskbarProgress =
|
||||||
*/
|
*/
|
||||||
onBrowserWindowLoad: function DTP_onBrowserWindowLoad(aWindow)
|
onBrowserWindowLoad: function DTP_onBrowserWindowLoad(aWindow)
|
||||||
{
|
{
|
||||||
|
this.init();
|
||||||
if (!DownloadTaskbarProgressUpdater) {
|
if (!DownloadTaskbarProgressUpdater) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -83,6 +92,9 @@ this.DownloadTaskbarProgress =
|
||||||
|
|
||||||
var DownloadTaskbarProgressUpdater =
|
var DownloadTaskbarProgressUpdater =
|
||||||
{
|
{
|
||||||
|
/// Whether the taskbar is initialized.
|
||||||
|
_initialized: false,
|
||||||
|
|
||||||
/// Reference to the taskbar.
|
/// Reference to the taskbar.
|
||||||
_taskbar: null,
|
_taskbar: null,
|
||||||
|
|
||||||
|
@ -94,18 +106,27 @@ var DownloadTaskbarProgressUpdater =
|
||||||
*/
|
*/
|
||||||
_init: function DTPU_init()
|
_init: function DTPU_init()
|
||||||
{
|
{
|
||||||
if (!(kTaskbarID in Cc)) {
|
if (this._initialized) {
|
||||||
// This means that the component isn't available
|
return; // Already initialized
|
||||||
|
}
|
||||||
|
this._initialized = true;
|
||||||
|
|
||||||
|
if (kTaskbarIDWin in Cc) {
|
||||||
|
this._taskbar = Cc[kTaskbarIDWin].getService(Ci.nsIWinTaskbar);
|
||||||
|
if (!this._taskbar.available) {
|
||||||
|
// The Windows version is probably too old
|
||||||
|
DownloadTaskbarProgressUpdater = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (kTaskbarIDMac in Cc) {
|
||||||
|
this._activeTaskbarProgress = Cc[kTaskbarIDMac].
|
||||||
|
getService(Ci.nsITaskbarProgress);
|
||||||
|
} else {
|
||||||
DownloadTaskbarProgressUpdater = null;
|
DownloadTaskbarProgressUpdater = null;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._taskbar = Cc[kTaskbarID].getService(Ci.nsIWinTaskbar);
|
this._taskbarState = Ci.nsITaskbarProgress.STATE_NO_PROGRESS;
|
||||||
if (!this._taskbar.available) {
|
|
||||||
// The Windows version is probably too old
|
|
||||||
DownloadTaskbarProgressUpdater = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._dm = Cc["@mozilla.org/download-manager;1"].
|
this._dm = Cc["@mozilla.org/download-manager;1"].
|
||||||
getService(Ci.nsIDownloadManager);
|
getService(Ci.nsIDownloadManager);
|
||||||
|
@ -126,6 +147,8 @@ var DownloadTaskbarProgressUpdater =
|
||||||
_uninit: function DTPU_uninit() {
|
_uninit: function DTPU_uninit() {
|
||||||
this._dm.removeListener(this);
|
this._dm.removeListener(this);
|
||||||
this._os.removeObserver(this, "quit-application-granted");
|
this._os.removeObserver(this, "quit-application-granted");
|
||||||
|
this._activeTaskbarProgress = null;
|
||||||
|
this._initialized = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -150,6 +173,7 @@ var DownloadTaskbarProgressUpdater =
|
||||||
*/
|
*/
|
||||||
_setActiveWindow: function DTPU_setActiveWindow(aWindow, aIsDownloadWindow)
|
_setActiveWindow: function DTPU_setActiveWindow(aWindow, aIsDownloadWindow)
|
||||||
{
|
{
|
||||||
|
#ifdef XP_WIN
|
||||||
// Clear out the taskbar for the old active window. (If there was no active
|
// Clear out the taskbar for the old active window. (If there was no active
|
||||||
// window, this is a no-op.)
|
// window, this is a no-op.)
|
||||||
this._clearTaskbar();
|
this._clearTaskbar();
|
||||||
|
@ -175,13 +199,27 @@ var DownloadTaskbarProgressUpdater =
|
||||||
else {
|
else {
|
||||||
this._activeTaskbarProgress = null;
|
this._activeTaskbarProgress = null;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Current state displayed on the active window's taskbar item
|
/// Current state displayed on the active window's taskbar item
|
||||||
_taskbarState: Ci.nsITaskbarProgress.STATE_NO_PROGRESS,
|
_taskbarState: null,
|
||||||
_totalSize: 0,
|
_totalSize: 0,
|
||||||
_totalTransferred: 0,
|
_totalTransferred: 0,
|
||||||
|
|
||||||
|
// If the active window is not the download manager window, set the state
|
||||||
|
// only if it is normal or indeterminate.
|
||||||
|
_shouldSetState: function DTPU_shouldSetState()
|
||||||
|
{
|
||||||
|
#ifdef XP_WIN
|
||||||
|
return this._activeWindowIsDownloadWindow ||
|
||||||
|
(this._taskbarState == Ci.nsITaskbarProgress.STATE_NORMAL ||
|
||||||
|
this._taskbarState == Ci.nsITaskbarProgress.STATE_INDETERMINATE);
|
||||||
|
#else
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the active window's taskbar indicator with the current state. There
|
* Update the active window's taskbar indicator with the current state. There
|
||||||
* are two cases here:
|
* are two cases here:
|
||||||
|
@ -198,11 +236,7 @@ var DownloadTaskbarProgressUpdater =
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the active window is not the download manager window, set the state
|
if (this._shouldSetState()) {
|
||||||
// only if it is normal or indeterminate.
|
|
||||||
if (this._activeWindowIsDownloadWindow ||
|
|
||||||
(this._taskbarState == Ci.nsITaskbarProgress.STATE_NORMAL ||
|
|
||||||
this._taskbarState == Ci.nsITaskbarProgress.STATE_INDETERMINATE)) {
|
|
||||||
this._activeTaskbarProgress.setProgressState(this._taskbarState,
|
this._activeTaskbarProgress.setProgressState(this._taskbarState,
|
||||||
this._totalTransferred,
|
this._totalTransferred,
|
||||||
this._totalSize);
|
this._totalSize);
|
||||||
|
@ -361,8 +395,3 @@ var DownloadTaskbarProgressUpdater =
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//// Initialization
|
|
||||||
|
|
||||||
DownloadTaskbarProgressUpdater._init();
|
|
||||||
|
|
|
@ -21,10 +21,6 @@ EXTRA_JS_MODULES = \
|
||||||
DownloadUtils.jsm \
|
DownloadUtils.jsm \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
ifeq ($(OS_ARCH),WINNT)
|
EXTRA_PP_JS_MODULES = DownloadTaskbarProgress.jsm
|
||||||
EXTRA_JS_MODULES += \
|
|
||||||
DownloadTaskbarProgress.jsm \
|
|
||||||
$(NULL)
|
|
||||||
endif
|
|
||||||
|
|
||||||
include $(topsrcdir)/config/rules.mk
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
|
|
@ -447,11 +447,9 @@ function Startup()
|
||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
#ifdef XP_WIN
|
let DownloadTaskbarProgress =
|
||||||
let tempScope = {};
|
Cu.import("resource://gre/modules/DownloadTaskbarProgress.jsm", {}).DownloadTaskbarProgress;
|
||||||
Cu.import("resource://gre/modules/DownloadTaskbarProgress.jsm", tempScope);
|
DownloadTaskbarProgress.onDownloadWindowLoad(window);
|
||||||
tempScope.DownloadTaskbarProgress.onDownloadWindowLoad(window);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function Shutdown()
|
function Shutdown()
|
||||||
|
|
|
@ -48,9 +48,13 @@ MOCHITEST_CHROME_FILES += \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(OS_ARCH),WINNT)
|
ifneq (,$(filter WINNT, $(OS_ARCH))$(filter cocoa, $(MOZ_WIDGET_TOOLKIT)))
|
||||||
MOCHITEST_CHROME_FILES += \
|
MOCHITEST_CHROME_FILES += \
|
||||||
test_taskbarprogress_downloadstates.xul \
|
test_taskbarprogress_downloadstates.xul \
|
||||||
|
$(NULL)
|
||||||
|
endif
|
||||||
|
ifeq ($(OS_ARCH),WINNT)
|
||||||
|
MOCHITEST_CHROME_FILES += \
|
||||||
$(filter disabled-for-very-frequent-orange--bug-630567, test_taskbarprogress_service.xul) \
|
$(filter disabled-for-very-frequent-orange--bug-630567, test_taskbarprogress_service.xul) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -166,17 +166,20 @@ function testSetup()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let isWin7OrHigher = false;
|
let isWin = /Win/.test(navigator.platform);
|
||||||
try {
|
if (isWin) {
|
||||||
let version = Cc["@mozilla.org/system-info;1"]
|
let isWin7OrHigher = false;
|
||||||
.getService(Ci.nsIPropertyBag2)
|
try {
|
||||||
.getProperty("version");
|
let version = Cc["@mozilla.org/system-info;1"]
|
||||||
isWin7OrHigher = (parseFloat(version) >= 6.1);
|
.getService(Ci.nsIPropertyBag2)
|
||||||
} catch (ex) { }
|
.getProperty("version");
|
||||||
|
isWin7OrHigher = (parseFloat(version) >= 6.1);
|
||||||
|
} catch (ex) { }
|
||||||
|
|
||||||
if (!isWin7OrHigher) {
|
if (!isWin7OrHigher) {
|
||||||
ok(true, "This test only runs on Windows 7 or higher");
|
ok(true, "This test only runs on Windows 7 or higher");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let tempScope = {};
|
let tempScope = {};
|
||||||
|
@ -184,10 +187,13 @@ function testSetup()
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
DownloadTaskbarProgress = tempScope.DownloadTaskbarProgress;
|
DownloadTaskbarProgress = tempScope.DownloadTaskbarProgress;
|
||||||
let TaskbarService = Cc[kTaskbarID].getService(Ci.nsIWinTaskbar);
|
|
||||||
|
|
||||||
isnot(DownloadTaskbarProgress, null, "Download taskbar progress service exists");
|
isnot(DownloadTaskbarProgress, null, "Download taskbar progress service exists");
|
||||||
is(TaskbarService.available, true, "Taskbar Service is available");
|
DownloadTaskbarProgress.init();
|
||||||
|
|
||||||
|
if (isWin) {
|
||||||
|
let TaskbarService = Cc[kTaskbarID].getService(Ci.nsIWinTaskbar);
|
||||||
|
is(TaskbarService.available, true, "Taskbar Service is available");
|
||||||
|
}
|
||||||
|
|
||||||
dm = Cc["@mozilla.org/download-manager;1"].
|
dm = Cc["@mozilla.org/download-manager;1"].
|
||||||
getService(Ci.nsIDownloadManager);
|
getService(Ci.nsIDownloadManager);
|
||||||
|
|
|
@ -122,6 +122,7 @@ ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
|
||||||
XPIDLSRCS += nsIMacDockSupport.idl \
|
XPIDLSRCS += nsIMacDockSupport.idl \
|
||||||
nsIStandaloneNativeMenu.idl \
|
nsIStandaloneNativeMenu.idl \
|
||||||
nsIMacWebAppUtils.idl \
|
nsIMacWebAppUtils.idl \
|
||||||
|
nsITaskbarProgress.idl \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -3,21 +3,38 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#import <Carbon/Carbon.h>
|
||||||
|
|
||||||
#include "nsIMacDockSupport.h"
|
#include "nsIMacDockSupport.h"
|
||||||
#include "nsIStandaloneNativeMenu.h"
|
#include "nsIStandaloneNativeMenu.h"
|
||||||
|
#include "nsITaskbarProgress.h"
|
||||||
|
#include "nsITimer.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
|
|
||||||
class nsMacDockSupport : public nsIMacDockSupport
|
class nsMacDockSupport : public nsIMacDockSupport, public nsITaskbarProgress
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
nsMacDockSupport() {}
|
nsMacDockSupport();
|
||||||
virtual ~nsMacDockSupport() {}
|
virtual ~nsMacDockSupport();
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSIMACDOCKSUPPORT
|
NS_DECL_NSIMACDOCKSUPPORT
|
||||||
|
NS_DECL_NSITASKBARPROGRESS
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsCOMPtr<nsIStandaloneNativeMenu> mDockMenu;
|
nsCOMPtr<nsIStandaloneNativeMenu> mDockMenu;
|
||||||
nsString mBadgeText;
|
nsString mBadgeText;
|
||||||
|
|
||||||
|
NSImage *mAppIcon, *mProgressBackground;
|
||||||
|
HIThemeTrackDrawInfo mProgressDrawInfo;
|
||||||
|
|
||||||
|
nsTaskbarProgressState mProgressState;
|
||||||
|
double mProgressFraction;
|
||||||
|
nsCOMPtr<nsITimer> mProgressTimer;
|
||||||
|
|
||||||
|
static void RedrawIconCallback(nsITimer* aTimer, void* aClosure);
|
||||||
|
|
||||||
|
bool InitProgress();
|
||||||
|
nsresult RedrawIcon();
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,12 +3,38 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#import <Carbon/Carbon.h>
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
#include "nsMacDockSupport.h"
|
#include "nsMacDockSupport.h"
|
||||||
#include "nsObjCExceptions.h"
|
#include "nsObjCExceptions.h"
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(nsMacDockSupport, nsIMacDockSupport)
|
NS_IMPL_ISUPPORTS2(nsMacDockSupport, nsIMacDockSupport, nsITaskbarProgress)
|
||||||
|
|
||||||
|
nsMacDockSupport::nsMacDockSupport()
|
||||||
|
: mAppIcon(nil)
|
||||||
|
, mProgressBackground(nil)
|
||||||
|
, mProgressState(STATE_NO_PROGRESS)
|
||||||
|
, mProgressFraction(0.0)
|
||||||
|
{
|
||||||
|
mProgressTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsMacDockSupport::~nsMacDockSupport()
|
||||||
|
{
|
||||||
|
if (mAppIcon) {
|
||||||
|
[mAppIcon release];
|
||||||
|
mAppIcon = nil;
|
||||||
|
}
|
||||||
|
if (mProgressBackground) {
|
||||||
|
[mProgressBackground release];
|
||||||
|
mProgressBackground = nil;
|
||||||
|
}
|
||||||
|
if (mProgressTimer) {
|
||||||
|
mProgressTimer->Cancel();
|
||||||
|
mProgressTimer = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsMacDockSupport::GetDockMenu(nsIStandaloneNativeMenu ** aDockMenu)
|
nsMacDockSupport::GetDockMenu(nsIStandaloneNativeMenu ** aDockMenu)
|
||||||
|
@ -62,3 +88,116 @@ nsMacDockSupport::GetBadgeText(nsAString& aBadgeText)
|
||||||
aBadgeText = mBadgeText;
|
aBadgeText = mBadgeText;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsMacDockSupport::SetProgressState(nsTaskbarProgressState aState,
|
||||||
|
PRUint64 aCurrentValue,
|
||||||
|
PRUint64 aMaxValue)
|
||||||
|
{
|
||||||
|
NS_ENSURE_ARG_RANGE(aState, 0, STATE_PAUSED);
|
||||||
|
if (aState == STATE_NO_PROGRESS || aState == STATE_INDETERMINATE) {
|
||||||
|
NS_ENSURE_TRUE(aCurrentValue == 0, NS_ERROR_INVALID_ARG);
|
||||||
|
NS_ENSURE_TRUE(aMaxValue == 0, NS_ERROR_INVALID_ARG);
|
||||||
|
}
|
||||||
|
if (aCurrentValue > aMaxValue) {
|
||||||
|
return NS_ERROR_ILLEGAL_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mProgressState = aState;
|
||||||
|
if (aMaxValue == 0) {
|
||||||
|
mProgressFraction = 0;
|
||||||
|
} else {
|
||||||
|
mProgressFraction = (double)aCurrentValue / aMaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mProgressState == STATE_NORMAL || mProgressState == STATE_INDETERMINATE) {
|
||||||
|
int perSecond = 30;
|
||||||
|
mProgressTimer->InitWithFuncCallback(RedrawIconCallback, this, 1000 / perSecond,
|
||||||
|
nsITimer::TYPE_REPEATING_SLACK);
|
||||||
|
return NS_OK;
|
||||||
|
} else {
|
||||||
|
mProgressTimer->Cancel();
|
||||||
|
return RedrawIcon();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
void nsMacDockSupport::RedrawIconCallback(nsITimer* aTimer, void* aClosure)
|
||||||
|
{
|
||||||
|
static_cast<nsMacDockSupport*>(aClosure)->RedrawIcon();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return whether to draw progress
|
||||||
|
bool nsMacDockSupport::InitProgress()
|
||||||
|
{
|
||||||
|
if (mProgressState != STATE_NORMAL && mProgressState != STATE_INDETERMINATE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mAppIcon) {
|
||||||
|
mProgressTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||||
|
mAppIcon = [[NSImage imageNamed:@"NSApplicationIcon"] retain];
|
||||||
|
mProgressBackground = [mAppIcon copyWithZone:nil];
|
||||||
|
|
||||||
|
NSSize sz = [mProgressBackground size];
|
||||||
|
mProgressDrawInfo.version = 0;
|
||||||
|
mProgressDrawInfo.min = 0;
|
||||||
|
mProgressDrawInfo.value = 0;
|
||||||
|
mProgressDrawInfo.max = PR_INT32_MAX;
|
||||||
|
mProgressDrawInfo.bounds = CGRectMake(sz.width * 1/32, sz.height * 3/32,
|
||||||
|
sz.width * 30/32, sz.height * 2/32);
|
||||||
|
mProgressDrawInfo.attributes = kThemeTrackHorizontal;
|
||||||
|
mProgressDrawInfo.enableState = kThemeTrackActive;
|
||||||
|
mProgressDrawInfo.kind = kThemeLargeProgressBar;
|
||||||
|
mProgressDrawInfo.trackInfo.progress.phase = 0;
|
||||||
|
|
||||||
|
// Draw a light background, to visually distinguish the progress.
|
||||||
|
HIRect bounds;
|
||||||
|
HIThemeGetTrackBounds(&mProgressDrawInfo, &bounds);
|
||||||
|
// Margins within track, empirically. FIXME: Don't hardcode?
|
||||||
|
int mleft = 3, mtop = 3, mright = 3, mbot = 1;
|
||||||
|
bounds.origin.x += mleft;
|
||||||
|
bounds.origin.y += mbot;
|
||||||
|
bounds.size.width -= mleft + mright;
|
||||||
|
bounds.size.height -= mtop + mbot;
|
||||||
|
|
||||||
|
[mProgressBackground lockFocus];
|
||||||
|
[[NSColor whiteColor] set];
|
||||||
|
NSRectFill(NSRectFromCGRect(bounds));
|
||||||
|
[mProgressBackground unlockFocus];
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsresult
|
||||||
|
nsMacDockSupport::RedrawIcon()
|
||||||
|
{
|
||||||
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||||
|
|
||||||
|
if (InitProgress()) {
|
||||||
|
// TODO: - Share code with nsNativeThemeCocoa?
|
||||||
|
// - Implement ERROR and PAUSED states?
|
||||||
|
NSImage *icon = [mProgressBackground copyWithZone:nil];
|
||||||
|
|
||||||
|
bool isIndeterminate = (mProgressState != STATE_NORMAL);
|
||||||
|
mProgressDrawInfo.value = PR_INT32_MAX * mProgressFraction;
|
||||||
|
mProgressDrawInfo.kind = isIndeterminate ? kThemeLargeIndeterminateBar
|
||||||
|
: kThemeLargeProgressBar;
|
||||||
|
|
||||||
|
int stepsPerSecond = isIndeterminate ? 60 : 30;
|
||||||
|
mProgressDrawInfo.trackInfo.progress.phase =
|
||||||
|
PR_IntervalToMilliseconds(PR_IntervalNow()) * stepsPerSecond / 1000 % 32;
|
||||||
|
|
||||||
|
[icon lockFocus];
|
||||||
|
CGContextRef ctx = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
|
||||||
|
HIThemeDrawTrack(&mProgressDrawInfo, NULL, ctx, kHIThemeOrientationNormal);
|
||||||
|
[icon unlockFocus];
|
||||||
|
[NSApp setApplicationIconImage:icon];
|
||||||
|
[icon release];
|
||||||
|
} else {
|
||||||
|
[NSApp setApplicationIconImage:mAppIcon];
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||||
|
}
|
||||||
|
|
|
@ -8,6 +8,9 @@ interface nsIStandaloneNativeMenu;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow applications to interface with the Mac OS X Dock.
|
* Allow applications to interface with the Mac OS X Dock.
|
||||||
|
*
|
||||||
|
* Applications may indicate progress on their Dock icon. Only one such
|
||||||
|
* progress indicator is available to the entire application.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
[scriptable, uuid(8BE66B0C-5F71-4B74-98CF-6C2551B999B1)]
|
[scriptable, uuid(8BE66B0C-5F71-4B74-98CF-6C2551B999B1)]
|
||||||
|
|
|
@ -80,13 +80,14 @@ MOCHITEST_CHROME_FILES += native_menus_window.xul \
|
||||||
test_key_event_counts.xul \
|
test_key_event_counts.xul \
|
||||||
test_bug596600.xul \
|
test_bug596600.xul \
|
||||||
test_bug673301.xul \
|
test_bug673301.xul \
|
||||||
|
test_taskbar_progress.xul \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||||
MOCHITEST_CHROME_FILES += taskbar_previews.xul \
|
MOCHITEST_CHROME_FILES += taskbar_previews.xul \
|
||||||
window_state_windows.xul \
|
window_state_windows.xul \
|
||||||
taskbar_progress.xul \
|
$(warning test_taskbar_progress.xul disabled due to regression, see bug 605813) \
|
||||||
test_chrome_context_menus_win.xul \
|
test_chrome_context_menus_win.xul \
|
||||||
test_plugin_input_event.html \
|
test_plugin_input_event.html \
|
||||||
chrome_context_menus_win.xul \
|
chrome_context_menus_win.xul \
|
||||||
|
|
|
@ -17,33 +17,21 @@
|
||||||
let Cu = Components.utils;
|
let Cu = Components.utils;
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
|
||||||
let taskbar = Cc["@mozilla.org/windows-taskbar;1"].getService(Ci.nsIWinTaskbar);
|
let TP = Ci.nsITaskbarProgress;
|
||||||
|
|
||||||
function IsWin7OrHigher() {
|
function winProgress() {
|
||||||
try {
|
let taskbar = Cc["@mozilla.org/windows-taskbar;1"];
|
||||||
var sysInfo = Cc["@mozilla.org/system-info;1"].
|
if (!taskbar)
|
||||||
getService(Ci.nsIPropertyBag2);
|
return null;
|
||||||
var ver = parseFloat(sysInfo.getProperty("version"));
|
taskbar = taskbar.getService(Ci.nsIWinTaskbar);
|
||||||
if (ver >= 6.1)
|
|
||||||
return true;
|
|
||||||
} catch (ex) { }
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
|
|
||||||
function loaded()
|
|
||||||
{
|
|
||||||
if (!taskbar.available)
|
if (!taskbar.available)
|
||||||
SimpleTest.finish();
|
return null;
|
||||||
|
|
||||||
// HACK from mconnor:
|
// HACK from mconnor:
|
||||||
var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
|
var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
|
||||||
let win = wm.getMostRecentWindow("navigator:browser");
|
let win = wm.getMostRecentWindow("navigator:browser");
|
||||||
let docShell = win.gBrowser.docShell;
|
let docShell = win.gBrowser.docShell;
|
||||||
|
|
||||||
let TP = Ci.nsITaskbarProgress;
|
|
||||||
|
|
||||||
let progress = taskbar.getTaskbarProgress(docShell);
|
let progress = taskbar.getTaskbarProgress(docShell);
|
||||||
isnot(progress, null, "Progress is not null");
|
isnot(progress, null, "Progress is not null");
|
||||||
|
|
||||||
|
@ -54,6 +42,24 @@
|
||||||
ok(true, "Cannot get progress for null docshell");
|
ok(true, "Cannot get progress for null docshell");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
function macProgress() {
|
||||||
|
let progress = Cc["@mozilla.org/widget/macdocksupport;1"];
|
||||||
|
if (!progress)
|
||||||
|
return null;
|
||||||
|
return progress.getService(TP);
|
||||||
|
}
|
||||||
|
|
||||||
|
SimpleTest.waitForExplicitFinish();
|
||||||
|
|
||||||
|
function loaded()
|
||||||
|
{
|
||||||
|
let progress = winProgress() || macProgress();
|
||||||
|
if (!TP)
|
||||||
|
SimpleTest.finish();
|
||||||
|
|
||||||
function shouldThrow(s,c,m) {
|
function shouldThrow(s,c,m) {
|
||||||
try {
|
try {
|
||||||
progress.setProgressState(s,c,m);
|
progress.setProgressState(s,c,m);
|
Загрузка…
Ссылка в новой задаче