mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 02:14:43 +00:00
Bug 909760 - Show download progress in the MacOS Finder r=spohl,mak
Show download progress in the MacOS Finder Differential Revision: https://phabricator.services.mozilla.com/D30688 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
c69f589086
commit
cf2e11f3c2
@ -1946,6 +1946,10 @@ var gBrowserInit = {
|
||||
DownloadsCommon.initializeAllDataLinks();
|
||||
ChromeUtils.import("resource:///modules/DownloadsTaskbar.jsm", {})
|
||||
.DownloadsTaskbar.registerIndicator(window);
|
||||
if (AppConstants.platform == "macosx") {
|
||||
ChromeUtils.import("resource:///modules/DownloadsMacFinderProgress.jsm")
|
||||
.DownloadsMacFinderProgress.register();
|
||||
}
|
||||
} catch (ex) {
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
|
87
browser/components/downloads/DownloadsMacFinderProgress.jsm
Normal file
87
browser/components/downloads/DownloadsMacFinderProgress.jsm
Normal file
@ -0,0 +1,87 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80 filetype=javascript: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
|
||||
/**
|
||||
* Handles the download progress indicator of the macOS Finder.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var EXPORTED_SYMBOLS = [
|
||||
"DownloadsMacFinderProgress",
|
||||
];
|
||||
|
||||
const {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
Downloads: "resource://gre/modules/Downloads.jsm",
|
||||
});
|
||||
|
||||
var DownloadsMacFinderProgress = {
|
||||
/**
|
||||
* Maps the path of the download, to the according progress indicator instance.
|
||||
*/
|
||||
_finderProgresses: null,
|
||||
|
||||
/**
|
||||
* This method is called after a new browser window on macOS is opened, it
|
||||
* registers for receiving download events for the progressbar of the Finder.
|
||||
*/
|
||||
register() {
|
||||
// Ensure to register only once per process and not for every window.
|
||||
if (!this._finderProgresses) {
|
||||
this._finderProgresses = new Map();
|
||||
Downloads.getList(Downloads.ALL).then(list => list.addView(this));
|
||||
}
|
||||
},
|
||||
|
||||
onDownloadAdded(download) {
|
||||
if (download.stopped) {
|
||||
return;
|
||||
}
|
||||
|
||||
let finderProgress = Cc["@mozilla.org/widget/macfinderprogress;1"]
|
||||
.createInstance(Ci.nsIMacFinderProgress);
|
||||
|
||||
let path = download.target.path;
|
||||
|
||||
finderProgress.init(path, () => {
|
||||
download.cancel().catch(Cu.reportError);
|
||||
download.removePartialData().catch(Cu.reportError);
|
||||
});
|
||||
|
||||
if (download.hasProgress) {
|
||||
finderProgress.updateProgress(download.currentBytes, download.totalBytes);
|
||||
} else {
|
||||
finderProgress.updateProgress(0, 0);
|
||||
}
|
||||
this._finderProgresses.set(path, finderProgress);
|
||||
},
|
||||
|
||||
onDownloadChanged(download) {
|
||||
let path = download.target.path;
|
||||
let finderProgress = this._finderProgresses.get(path);
|
||||
if (!finderProgress) {
|
||||
// The download is not tracked, it may have been restarted,
|
||||
// thus forward the call to onDownloadAdded to check if it should be tracked.
|
||||
this.onDownloadAdded(download);
|
||||
} else if (download.stopped) {
|
||||
finderProgress.end();
|
||||
this._finderProgresses.delete(path);
|
||||
} else {
|
||||
finderProgress.updateProgress(download.currentBytes, download.totalBytes);
|
||||
}
|
||||
},
|
||||
|
||||
onDownloadRemoved(download) {
|
||||
let path = download.target.path;
|
||||
let finderProgress = this._finderProgresses.get(path);
|
||||
if (finderProgress) {
|
||||
finderProgress.end();
|
||||
this._finderProgresses.delete(path);
|
||||
}
|
||||
},
|
||||
};
|
@ -18,5 +18,10 @@ EXTRA_JS_MODULES += [
|
||||
'DownloadsViewUI.jsm',
|
||||
]
|
||||
|
||||
toolkit = CONFIG['MOZ_WIDGET_TOOLKIT']
|
||||
|
||||
if toolkit == 'cocoa':
|
||||
EXTRA_JS_MODULES += ['DownloadsMacFinderProgress.jsm']
|
||||
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('Firefox', 'Downloads Panel')
|
||||
|
@ -39,6 +39,7 @@ UNIFIED_SOURCES += [
|
||||
'nsLookAndFeel.mm',
|
||||
'nsMacCursor.mm',
|
||||
'nsMacDockSupport.mm',
|
||||
'nsMacFinderProgress.mm',
|
||||
'nsMacSharingService.mm',
|
||||
'nsMacWebAppUtils.mm',
|
||||
'nsMenuBarX.mm',
|
||||
|
24
widget/cocoa/nsMacFinderProgress.h
Normal file
24
widget/cocoa/nsMacFinderProgress.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
#ifndef _MACFINDERPROGRESS_H_
|
||||
#define _MACFINDERPROGRESS_H_
|
||||
|
||||
#include "nsIMacFinderProgress.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsMacFinderProgress : public nsIMacFinderProgress {
|
||||
public:
|
||||
nsMacFinderProgress();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMACFINDERPROGRESS
|
||||
|
||||
protected:
|
||||
virtual ~nsMacFinderProgress();
|
||||
|
||||
NSProgress* mProgress;
|
||||
};
|
||||
|
||||
#endif
|
88
widget/cocoa/nsMacFinderProgress.mm
Normal file
88
widget/cocoa/nsMacFinderProgress.mm
Normal file
@ -0,0 +1,88 @@
|
||||
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "nsMacFinderProgress.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsString.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsMacFinderProgress, nsIMacFinderProgress)
|
||||
|
||||
nsMacFinderProgress::nsMacFinderProgress() : mProgress(nil) {}
|
||||
|
||||
nsMacFinderProgress::~nsMacFinderProgress() {
|
||||
if (mProgress) {
|
||||
[mProgress.cancellationHandler release];
|
||||
[mProgress release];
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMacFinderProgress::Init(const nsAString& path,
|
||||
nsIMacFinderProgressCanceledCallback* cancellationCallback) {
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
NSURL* pathUrl = [NSURL
|
||||
fileURLWithPath:[NSString
|
||||
stringWithCharacters:reinterpret_cast<const unichar*>(path.BeginReading())
|
||||
length:path.Length()]];
|
||||
NSDictionary* userInfo = @{
|
||||
@"NSProgressFileOperationKindKey" : @"NSProgressFileOperationKindDownloading",
|
||||
@"NSProgressFileURLKey" : pathUrl
|
||||
};
|
||||
|
||||
mProgress = [[NSProgress alloc] initWithParent:nil userInfo:userInfo];
|
||||
mProgress.kind = NSProgressKindFile;
|
||||
mProgress.cancellable = YES;
|
||||
|
||||
nsMainThreadPtrHandle<nsIMacFinderProgressCanceledCallback> cancellationCallbackHandle(
|
||||
new nsMainThreadPtrHolder<nsIMacFinderProgressCanceledCallback>(
|
||||
"MacFinderProgress::CancellationCallback", cancellationCallback));
|
||||
|
||||
mProgress.cancellationHandler = ^{
|
||||
NS_DispatchToMainThread(
|
||||
NS_NewRunnableFunction("MacFinderProgress::Canceled", [cancellationCallbackHandle] {
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
cancellationCallbackHandle->Canceled();
|
||||
}));
|
||||
};
|
||||
|
||||
[mProgress publish];
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMacFinderProgress::UpdateProgress(uint64_t currentProgress, uint64_t totalProgress) {
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
if (mProgress) {
|
||||
mProgress.totalUnitCount = totalProgress;
|
||||
mProgress.completedUnitCount = currentProgress;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMacFinderProgress::End() {
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
if (mProgress) {
|
||||
[mProgress unpublish];
|
||||
[mProgress release];
|
||||
mProgress = nil;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
@ -82,6 +82,9 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsNativeMenuServiceX)
|
||||
#include "nsMacDockSupport.h"
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacDockSupport)
|
||||
|
||||
#include "nsMacFinderProgress.h"
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacFinderProgress)
|
||||
|
||||
#include "nsMacSharingService.h"
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacSharingService)
|
||||
|
||||
@ -123,6 +126,7 @@ NS_DEFINE_NAMED_CID(NS_IDLE_SERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_SYSTEMALERTSSERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_NATIVEMENUSERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_MACDOCKSUPPORT_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_MACFINDERPROGRESS_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_MACSHARINGSERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_MACWEBAPPUTILS_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_STANDALONENATIVEMENU_CID);
|
||||
@ -153,6 +157,7 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
|
||||
{&kNS_SYSTEMALERTSSERVICE_CID, false, NULL, OSXNotificationCenterConstructor},
|
||||
{&kNS_NATIVEMENUSERVICE_CID, false, NULL, nsNativeMenuServiceXConstructor},
|
||||
{&kNS_MACDOCKSUPPORT_CID, false, NULL, nsMacDockSupportConstructor},
|
||||
{&kNS_MACFINDERPROGRESS_CID, false, NULL, nsMacFinderProgressConstructor},
|
||||
{&kNS_MACSHARINGSERVICE_CID, false, NULL, nsMacSharingServiceConstructor},
|
||||
{&kNS_MACWEBAPPUTILS_CID, false, NULL, nsMacWebAppUtilsConstructor},
|
||||
{&kNS_STANDALONENATIVEMENU_CID, false, NULL, nsStandaloneNativeMenuConstructor},
|
||||
@ -182,6 +187,7 @@ static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
|
||||
{"@mozilla.org/system-alerts-service;1", &kNS_SYSTEMALERTSSERVICE_CID},
|
||||
{"@mozilla.org/widget/nativemenuservice;1", &kNS_NATIVEMENUSERVICE_CID},
|
||||
{"@mozilla.org/widget/macdocksupport;1", &kNS_MACDOCKSUPPORT_CID},
|
||||
{"@mozilla.org/widget/macfinderprogress;1", &kNS_MACFINDERPROGRESS_CID},
|
||||
{"@mozilla.org/widget/macsharingservice;1", &kNS_MACSHARINGSERVICE_CID},
|
||||
{"@mozilla.org/widget/mac-web-app-utils;1", &kNS_MACWEBAPPUTILS_CID},
|
||||
{"@mozilla.org/widget/standalonenativemenu;1", &kNS_STANDALONENATIVEMENU_CID},
|
||||
|
@ -59,6 +59,7 @@ if toolkit == 'windows':
|
||||
elif toolkit == 'cocoa':
|
||||
XPIDL_SOURCES += [
|
||||
'nsIMacDockSupport.idl',
|
||||
'nsIMacFinderProgress.idl',
|
||||
'nsIMacSharingService.idl',
|
||||
'nsIMacWebAppUtils.idl',
|
||||
'nsIStandaloneNativeMenu.idl',
|
||||
|
43
widget/nsIMacFinderProgress.idl
Normal file
43
widget/nsIMacFinderProgress.idl
Normal file
@ -0,0 +1,43 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
|
||||
[scriptable, function, uuid(6BAE6D1C-7FFD-4354-8D7B-64697E98A801)]
|
||||
interface nsIMacFinderProgressCanceledCallback : nsISupports
|
||||
{
|
||||
void canceled();
|
||||
};
|
||||
|
||||
|
||||
[scriptable, uuid(25A0B01F-54D4-4AEF-B2BF-C5764CDC68A8)]
|
||||
interface nsIMacFinderProgress : nsISupports
|
||||
{
|
||||
/**
|
||||
* Initialize and display a new Finder progressbar on the given file
|
||||
*
|
||||
* @param path The path of the file
|
||||
*
|
||||
* @param canceledCallback Callback which is called when cancelation is requested
|
||||
*/
|
||||
void init(in AString path, in nsIMacFinderProgressCanceledCallback canceledCallback);
|
||||
|
||||
/**
|
||||
* Update the current and total progess. If currentProgress and totalProgress are both 0,
|
||||
* the progress is indetermined
|
||||
*
|
||||
* @param currentProgress The current progress
|
||||
*
|
||||
* @param totalProgress The total progress
|
||||
*/
|
||||
void updateProgress(in unsigned long long currentProgress, in unsigned long long totalProgress);
|
||||
|
||||
/**
|
||||
* End displaying the progressbar on the file
|
||||
*/
|
||||
void end();
|
||||
};
|
@ -90,6 +90,14 @@
|
||||
} \
|
||||
}
|
||||
|
||||
// {74EA4101-A5BB-49BC-9984-66DA8B225A37}
|
||||
#define NS_MACFINDERPROGRESS_CID \
|
||||
{ \
|
||||
0x74EA4101, 0xA5BB, 0x49BC, { \
|
||||
0x99, 0x84, 0x66, 0xDA, 0x8B, 0x22, 0x5A, 0x37 \
|
||||
} \
|
||||
}
|
||||
|
||||
// {de59fe1a-46c8-490f-b04d-34545acb06c9}
|
||||
#define NS_MACSHARINGSERVICE_CID \
|
||||
{ \
|
||||
|
Loading…
Reference in New Issue
Block a user