Bug 1602196: Generate an icon for the ssb shortcut on windows. r=mhowell

Differential Revision: https://phabricator.services.mozilla.com/D56773

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Dave Townsend 2019-12-16 21:40:38 +00:00
Родитель 4c915f1aa5
Коммит e3397c4603
6 изменённых файлов: 104 добавлений и 8 удалений

Просмотреть файл

@ -9,5 +9,5 @@ interface nsIFile;
[scriptable, uuid(fb9b59db-5a91-4e67-92b6-35e7d6e6d3fd)]
interface nsIWindowsShellService : nsISupports
{
void createShortcut(in nsIFile aBinary, in Array<AString> aArguments, in AString aDescription, in nsIFile aTarget);
void createShortcut(in nsIFile aBinary, in Array<AString> aArguments, in AString aDescription, in nsIFile aIconFile, in nsIFile aTarget);
};

Просмотреть файл

@ -701,7 +701,7 @@ NS_IMETHODIMP
nsWindowsShellService::CreateShortcut(nsIFile* aBinary,
const nsTArray<nsString>& aArguments,
const nsAString& aDescription,
nsIFile* aTarget) {
nsIFile* aIconFile, nsIFile* aTarget) {
NS_ENSURE_ARG(aBinary);
NS_ENSURE_ARG(aTarget);
@ -725,6 +725,11 @@ nsWindowsShellService::CreateShortcut(nsIFile* aBinary,
link->SetArguments(arguments.get());
if (aIconFile) {
nsString icon(aIconFile->NativePath());
link->SetIconLocation(icon.get(), 0);
}
RefPtr<IPersistFile> persist;
hr = link->QueryInterface(IID_IPersistFile, getter_AddRefs(persist));
NS_ENSURE_HRESULT(hr, NS_ERROR_FAILURE);

Просмотреть файл

@ -8,11 +8,11 @@ const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
ChromeUtils.defineModuleGetter(
this,
"NetUtil",
"resource://gre/modules/NetUtil.jsm"
);
XPCOMUtils.defineLazyModuleGetters(this, {
FileUtils: "resource://gre/modules/FileUtils.jsm",
NetUtil: "resource://gre/modules/NetUtil.jsm",
});
XPCOMUtils.defineLazyServiceGetter(
this,
"ImgTools",
@ -57,4 +57,24 @@ const ImageTools = {
);
});
},
saveIcon(container, width, height, target) {
return new Promise((resolve, reject) => {
let output = FileUtils.openFileOutputStream(target);
let stream = ImgTools.encodeScaledImage(
container,
"image/vnd.microsoft.icon",
width,
height,
""
);
NetUtil.asyncCopy(stream, output, status => {
if (Components.isSuccessCode(status)) {
resolve();
} else {
reject(Components.Exception("Failed to save icon.", status));
}
});
});
},
};

Просмотреть файл

@ -42,6 +42,27 @@ const WindowsSupport = {
return;
}
let dir = OS.Path.join(OS.Constants.Path.profileDir, "ssb", ssb.id);
await OS.File.makeDir(dir, {
from: OS.Constants.Path.profileDir,
ignoreExisting: true,
});
let iconFile = new File(OS.Path.join(dir, "icon.ico"));
// We should be embedding multiple icon sizes, but the current icon encoder
// does not support this. For now just embed a sensible size.
let icon = ssb.getIcon(128);
if (icon) {
let { container } = await ImageTools.loadImage(
Services.io.newURI(icon.src)
);
ImageTools.saveIcon(container, 128, 128, iconFile);
} else {
// TODO use a default icon file.
iconFile = null;
}
let desktop = Services.dirsvc.get("Desk", Ci.nsIFile);
let link = OS.Path.join(desktop.path, `${ssb.name}.lnk`);
@ -49,6 +70,7 @@ const WindowsSupport = {
Services.dirsvc.get("XREExeF", Ci.nsIFile),
["-profile", OS.Constants.Path.profileDir, "-start-ssb", ssb.id],
ssb.name,
iconFile,
new File(link)
);
},
@ -71,6 +93,16 @@ const WindowsSupport = {
} catch (e) {
console.error(e);
}
let dir = OS.Path.join(OS.Constants.Path.profileDir, "ssb", ssb.id);
try {
await OS.File.removeDir(dir, {
ignoreAbsent: true,
ignorePermissions: true,
});
} catch (e) {
console.error(e);
}
},
/**

Просмотреть файл

@ -9,6 +9,19 @@ const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
const ICON16 =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAADUExURUdwTIL60tIAAAABdFJOUwBA5thmAAAAC0lEQVQIHWMgEQAAADAAAQrnSBQAAAAASUVORK5CYII=";
const ICON32 =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgAQMAAABJtOi3AAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAADUExURUdwTIL60tIAAAABdFJOUwBA5thmAAAAC0lEQVQIHWMY5AAAAKAAAZearVIAAAAASUVORK5CYII=";
const ICON48 =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAQMAAABtzGvEAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAADUExURUdwTIL60tIAAAABdFJOUwBA5thmAAAADElEQVQYGWMYBVQFAAFQAAHUa/NpAAAAAElFTkSuQmCC";
const ICON96 =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgAQMAAADYVuV7AAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAADUExURUdwTIL60tIAAAABdFJOUwBA5thmAAAAEUlEQVQYGWMYBaNgFIyCYQoABOAAAZ11NUsAAAAASUVORK5CYII=";
const ICON128 =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACAAQMAAAD58POIAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAADUExURUdwTIL60tIAAAABdFJOUwBA5thmAAAAGElEQVQYGWMYBaNgFIyCUTAKRsEooDMAAAiAAAE2cKqmAAAAAElFTkSuQmCC";
const ICON256 =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEAAQMAAABmvDolAAAAA1BMVEVHcEyC+tLSAAAAAXRSTlMAQObYZgAAAB9JREFUGBntwQENAAAAwiD7p34ON2AAAAAAAAAAAOcCIQAAAfWivQQAAAAASUVORK5CYII=";
XPCOMUtils.defineLazyModuleGetters(this, {
ManifestProcessor: "resource://gre/modules/ManifestProcessor.jsm",
KeyValueService: "resource://gre/modules/kvstore.jsm",

Просмотреть файл

@ -5,7 +5,24 @@
add_task(async () => {
Services.prefs.setBoolPref("browser.ssb.osintegration", true);
let ssb = SiteSpecificBrowser.createFromURI(uri("https://www.mozilla.org/"));
let ssb = await SiteSpecificBrowser.createFromManifest(
parseManifest("https://www.mozilla.org/", {
icons: [
{
src: ICON32,
sizes: "32x32",
},
{
src: ICON48,
sizes: "48x48",
},
{
src: ICON128,
sizes: "128x128",
},
],
})
);
await ssb.install();
let ssbs = await SiteSpecificBrowserService.list();
@ -27,7 +44,16 @@ add_task(async () => {
Assert.ok(link.isFile());
let icon = gSSBData.clone();
icon.append(ssb.id);
icon.append("icon.ico");
Assert.ok(icon.isFile());
await ssb.uninstall();
Assert.ok(!link.exists());
let dir = gSSBData.clone();
dir.append(ssb.id);
Assert.ok(!dir.exists());
}
});