Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Electron Tray Improvements #3909

Merged
merged 8 commits into from
May 19, 2017
Merged
5 changes: 2 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@
/key.pem
/lib
/node_modules
/electron/node_modules
/electron_app/node_modules
/electron_app/dist
/packages/
/webapp
/.npmrc
.DS_Store
npm-debug.log
electron/dist
electron/pub
/config.json
/src/component-index.js
21 changes: 20 additions & 1 deletion electron_app/src/electron-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,31 @@ function startAutoUpdate(update_base_url) {
// no other way to catch this error).
// Assuming we generally run from the console when developing,
// this is far preferable.
process.on('uncaughtException', function (error) {
process.on('uncaughtException', function(error) {
console.log("Unhandled exception", error);
});

electron.ipcMain.on('install_update', installUpdate);

let focusHandlerAttached = false;
electron.ipcMain.on('setBadgeCount', function(ev, count) {
electron.app.setBadgeCount(count);
if (process.platform === 'win32' && mainWindow && !mainWindow.isFocused()) {
if (count > 0) {
if (!focusHandlerAttached) {
mainWindow.once('focus', () => {
mainWindow.flashFrame(false);
focusHandlerAttached = false;
});
focusHandlerAttached = true;
}
mainWindow.flashFrame(true);
} else {
mainWindow.flashFrame(false);
}
}
});

electron.app.commandLine.appendSwitch('--enable-usermedia-screen-capturing');

const shouldQuit = electron.app.makeSingleInstance((commandLine, workingDirectory) => {
Expand Down
49 changes: 34 additions & 15 deletions electron_app/src/tray.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,21 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

const path = require('path');
const electron = require('electron');

const app = electron.app;
const Tray = electron.Tray;
const MenuItem = electron.MenuItem;
const {app, Tray, Menu, nativeImage} = require('electron');

let trayIcon = null;

exports.hasTray = function hasTray() {
return (trayIcon !== null);
}
};

exports.create = function (win, config) {
exports.create = function(win, config) {
// no trays on darwin
if (process.platform === 'darwin' || trayIcon) {
return;
}

const toggleWin = function () {
const toggleWin = function() {
if (win.isVisible() && !win.isMinimized()) {
win.hide();
} else {
Expand All @@ -44,24 +39,48 @@ exports.create = function (win, config) {
}
};

const contextMenu = electron.Menu.buildFromTemplate([
const contextMenu = Menu.buildFromTemplate([
{
label: 'Show/Hide ' + config.brand,
click: toggleWin
click: toggleWin,
},
{
type: 'separator'
type: 'separator',
},
{
label: 'Quit',
click: function () {
click: function() {
app.quit();
}
}
},
},
]);

trayIcon = new Tray(config.icon_path);
trayIcon.setToolTip(config.brand);
trayIcon.setContextMenu(contextMenu);
trayIcon.on('click', toggleWin);

let lastFavicon = null;
win.webContents.on('page-favicon-updated', function(ev, favicons) {
let newFavicon = config.icon_path;
if (favicons && favicons.length > 0 && favicons[0].startsWith('data:')) {
newFavicon = favicons[0];
}

// No need to change, shortcut
if (newFavicon === lastFavicon) return;
lastFavicon = newFavicon;

// if its not default we have to construct into nativeImage
if (newFavicon !== config.icon_path) {
newFavicon = nativeImage.createFromDataURL(favicons[0]);
}

trayIcon.setImage(newFavicon);
win.setIcon(newFavicon);
});

win.webContents.on('page-title-updated', function(ev, title) {
trayIcon.setToolTip(title);
});
};
14 changes: 3 additions & 11 deletions src/vector/platform/ElectronPlatform.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ limitations under the License.
import VectorBasePlatform from './VectorBasePlatform';
import dis from 'matrix-react-sdk/lib/dispatcher';
import q from 'q';
import electron, {remote} from 'electron';
import electron, {remote, ipcRenderer} from 'electron';

remote.autoUpdater.on('update-downloaded', onUpdateDownloaded);

Expand Down Expand Up @@ -58,16 +58,8 @@ export default class ElectronPlatform extends VectorBasePlatform {
setNotificationCount(count: number) {
if (this.notificationCount === count) return;
super.setNotificationCount(count);
// this sometimes throws because electron is made of fail:
// https://github.com/electron/electron/issues/7351
// For now, let's catch the error, but I suspect it may
// continue to fail and we might just have to accept that
// electron's remote RPC is a non-starter for now and use IPC
try {
remote.app.setBadgeCount(count);
} catch (e) {
console.error('Failed to set notification count', e);
}

ipcRenderer.send('setBadgeCount', count);
}

supportsNotifications(): boolean {
Expand Down
47 changes: 46 additions & 1 deletion src/vector/platform/VectorBasePlatform.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,57 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import BasePlatform from 'matrix-react-sdk/lib/BasePlatform'
import BasePlatform from 'matrix-react-sdk/lib/BasePlatform';
import Favico from 'favico.js';

/**
* Vector-specific extensions to the BasePlatform template
*/
export default class VectorBasePlatform extends BasePlatform {
constructor() {
super();

// The 'animations' are really low framerate and look terrible.
// Also it re-starts the animationb every time you set the badge,
// and we set the state each time, even if the value hasn't changed,
// so we'd need to fix that if enabling the animation.
this.favicon = new Favico({animation: 'none'});
this._updateFavicon();
}

_updateFavicon() {
try {
// This needs to be in in a try block as it will throw
// if there are more than 100 badge count changes in
// its internal queue
let bgColor = "#d00",
notif = this.notificationCount;

if (this.errorDidOccur) {
notif = notif || "×";
bgColor = "#f00";
}

this.favicon.badge(notif, {
bgColor: bgColor,
});
} catch (e) {
console.warn(`Failed to set badge count: ${e.message}`);
}
}

setNotificationCount(count: number) {
if (this.notificationCount === count) return;
super.setNotificationCount(count);
this._updateFavicon();
}

setErrorStatus(errorDidOccur: boolean) {
if (this.errorDidOccur === errorDidOccur) return;
super.setErrorStatus(errorDidOccur);
this._updateFavicon();
}

/**
* Check for the availability of an update to the version of the
* app that's currently running.
Expand Down
44 changes: 0 additions & 44 deletions src/vector/platform/WebPlatform.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ limitations under the License.
*/

import VectorBasePlatform from './VectorBasePlatform';
import Favico from 'favico.js';
import request from 'browser-request';
import dis from 'matrix-react-sdk/lib/dispatcher.js';
import q from 'q';
Expand All @@ -27,49 +26,6 @@ import url from 'url';
import UAParser from 'ua-parser-js';

export default class WebPlatform extends VectorBasePlatform {
constructor() {
super();
this.runningVersion = null;
// The 'animations' are really low framerate and look terrible.
// Also it re-starts the animationb every time you set the badge,
// and we set the state each time, even if the value hasn't changed,
// so we'd need to fix that if enabling the animation.
this.favicon = new Favico({animation: 'none'});
this._updateFavicon();
}

_updateFavicon() {
try {
// This needs to be in in a try block as it will throw
// if there are more than 100 badge count changes in
// its internal queue
let bgColor = "#d00",
notif = this.notificationCount;

if (this.errorDidOccur) {
notif = notif || "×";
bgColor = "#f00";
}

this.favicon.badge(notif, {
bgColor: bgColor,
});
} catch (e) {
console.warn(`Failed to set badge count: ${e.message}`);
}
}

setNotificationCount(count: number) {
if (this.notificationCount === count) return;
super.setNotificationCount(count);
this._updateFavicon();
}

setErrorStatus(errorDidOccur: boolean) {
if (this.errorDidOccur === errorDidOccur) return;
super.setErrorStatus(errorDidOccur);
this._updateFavicon();
}

/**
* Returns true if the platform supports displaying
Expand Down