diff --git a/.gitignore b/.gitignore
index 6dd2b988..7f753927 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
diff --git a/electron_app/src/electron-main.js b/electron_app/src/electron-main.js
index 29a9f08a..ab844bd3 100644
--- a/electron_app/src/electron-main.js
+++ b/electron_app/src/electron-main.js
@@ -161,12 +161,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) => {
diff --git a/electron_app/src/tray.js b/electron_app/src/tray.js
index 2ccdf40c..5409194d 100644
--- a/electron_app/src/tray.js
+++ b/electron_app/src/tray.js
@@ -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 {
@@ -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);
+    });
 };
diff --git a/src/vector/platform/ElectronPlatform.js b/src/vector/platform/ElectronPlatform.js
index 82ef0b51..5710e66e 100644
--- a/src/vector/platform/ElectronPlatform.js
+++ b/src/vector/platform/ElectronPlatform.js
@@ -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);
 
@@ -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 {
diff --git a/src/vector/platform/VectorBasePlatform.js b/src/vector/platform/VectorBasePlatform.js
index 1466b76a..00c9c47c 100644
--- a/src/vector/platform/VectorBasePlatform.js
+++ b/src/vector/platform/VectorBasePlatform.js
@@ -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.
diff --git a/src/vector/platform/WebPlatform.js b/src/vector/platform/WebPlatform.js
index 72ca19f0..204317ba 100644
--- a/src/vector/platform/WebPlatform.js
+++ b/src/vector/platform/WebPlatform.js
@@ -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';
@@ -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