Revision control
Copy as Markdown
Other Tools
/* 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
/**
* This interface provides a tool to merge the tray icon with unread
* badge on Linux. It's here to circumvent incorrectly or not at all
* implemented org.freedesktop.StatusNotifierItem.OverlayIconPixmap
* API on KDE and AppIndicator.
*/
export class MessengerLinuxTrayIntegration {
QueryInterface = ChromeUtils.generateQI(["nsIMessengerLinuxTrayIntegration"]);
/**
* @param {number[]} iconRgbaData Pixel data of the tray icon
* @param {number} iconWidth Tray icon width
* @param {number} iconHeight Tray icon height
* @param {number[]} badgeRgbaData Pixel data of the unread mail badge in ARGB format
* @param {number} badgeWidth Badge width
* @param {number} badgeHeight Badge height
* @returns {null|imgIContainer}
*/
mergeTrayIconBadge(
iconRgbaData,
iconWidth,
iconHeight,
badgeRgbaData,
badgeWidth,
badgeHeight
) {
const window = Services.wm.getMostRecentBrowserWindow();
if (!window) {
return null;
}
// putImageData() doesn't have parameters to resize an image so we need to first
// draw the image on a seperate canvas in plain size then leverage drawImage() parameters
// to resize it.
const badgeCanvas = window.document.createElement("canvas");
badgeCanvas.width = badgeWidth;
badgeCanvas.height = badgeHeight;
badgeCanvas.style.width = `${badgeCanvas.width}px`;
badgeCanvas.style.height = `${badgeCanvas.height}px`;
const badgeCtx = badgeCanvas.getContext("2d");
badgeCtx.save();
badgeCtx.putImageData(
new ImageData(
new Uint8ClampedArray(badgeRgbaData),
badgeWidth,
badgeHeight
),
0,
0
);
badgeCtx.restore();
const canvas = window.document.createElement("canvas");
canvas.width = iconWidth;
canvas.height = iconHeight;
canvas.style.width = `${canvas.width}px`;
canvas.style.height = `${canvas.width}px`;
const ctx = canvas.getContext("2d");
ctx.save();
// Draw tray icon
ctx.putImageData(
new ImageData(new Uint8ClampedArray(iconRgbaData), iconWidth, iconHeight),
0,
0
);
// Compute badge sizes and offsets before drawing on the final canvas and draw badge
const dWidth = Math.ceil(0.6 * badgeCanvas.width);
const dHeight = Math.ceil(0.6 * badgeCanvas.height);
const dx = Math.ceil(iconWidth - dWidth);
const dy = Math.ceil(iconHeight - dHeight);
ctx.drawImage(badgeCanvas, dx, dy, dWidth, dHeight);
ctx.restore();
return getCanvasAsImgContainer(canvas, iconWidth, iconHeight);
}
}