summaryrefslogtreecommitdiffhomepage
path: root/app
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@codeispoetry.ru>2017-03-20 13:00:05 +0000
committerAndrej Mihajlov <and@codeispoetry.ru>2017-03-20 13:00:05 +0000
commit0e3e9b765fa90f7beee7b7b89c884ebd7189f4e8 (patch)
treea7706f06543e7ba5e6822d950faf4a41719e0a5e /app
parent85f0ac9be65b0e81989e9d992e15b1f760b3b28d (diff)
parent62b3e2784b8aab2c5a13b3eb0f18f2a158e6bb7f (diff)
downloadmullvadvpn-0e3e9b765fa90f7beee7b7b89c884ebd7189f4e8.tar.xz
mullvadvpn-0e3e9b765fa90f7beee7b7b89c884ebd7189f4e8.zip
Merge branch 'feature/refactor-animations'
Diffstat (limited to 'app')
-rw-r--r--app/lib/keyframe-animation.js349
-rw-r--r--app/lib/tray-animation.js264
-rw-r--r--app/lib/tray-animator.js113
-rw-r--r--app/lib/tray-icon-manager.js85
-rw-r--r--app/lib/tray-icon-provider.js47
-rw-r--r--app/main.js5
6 files changed, 386 insertions, 477 deletions
diff --git a/app/lib/keyframe-animation.js b/app/lib/keyframe-animation.js
new file mode 100644
index 0000000000..b8f4a206d4
--- /dev/null
+++ b/app/lib/keyframe-animation.js
@@ -0,0 +1,349 @@
+import assert from 'assert';
+import { nativeImage } from 'electron';
+
+/**
+ * Keyframe animation
+ *
+ * @export
+ * @class KeyframeAnimation
+ */
+export default class KeyframeAnimation {
+
+ /**
+ * Set callback called on each frame update
+ *
+ * @type {function}
+ * @memberOf KeyframeAnimation
+ */
+ set onFrame(v) { this._onFrame = v; }
+
+ /**
+ * Get callback called on each frame update
+ *
+ * @readonly
+ * @type {function}
+ * @memberOf KeyframeAnimation
+ */
+ get onFrame() { this._onFrame; }
+
+ /**
+ * Set callback called when animation finished
+ *
+ * @type {function}
+ * @memberOf KeyframeAnimation
+ */
+ set onFinish(v) { this._onFinish = v; }
+
+ /**
+ * Get callback called when animation finished
+ *
+ * @readonly
+ *
+ * @memberOf KeyframeAnimation
+ */
+ get onFinish() { this._onFinish; }
+
+ /**
+ * Set animation pace per frame in ms
+ *
+ * @type {number}
+ * @memberOf KeyframeAnimation
+ */
+ set speed(v) { this._speed = parseInt(v); }
+
+ /**
+ * Get animation pace per frame in ms
+ *
+ * @readonly
+ * @type {number}
+ * @memberOf KeyframeAnimation
+ */
+ get speed() { return this._speed; }
+
+ /**
+ * Set animation repetition
+ * @type {bool}
+ *
+ * @memberOf KeyframeAnimation
+ */
+ set repeat(v) { this._repeat = !!v; }
+
+ /**
+ * Get animation repetition
+ *
+ * @readonly
+ * @type {bool}
+ * @memberOf KeyframeAnimation
+ */
+ get repeat() { return this._repeat; }
+
+ /**
+ * Set animation reversal
+ * @type {bool}
+ * @memberOf KeyframeAnimation
+ */
+ set reverse(v) { this._reverse = !!v; }
+
+ /**
+ * Get animation reversal
+ *
+ * @readonly
+ * @type {bool}
+ * @memberOf KeyframeAnimation
+ */
+ get reverse() { return this._repeat; }
+
+ /**
+ * Set animation alternation
+ * @type {bool}
+ * @memberOf KeyframeAnimation
+ */
+ set alternate(v) { this._alternate = !!v; }
+
+ /**
+ * Get animation alternation
+ *
+ * @readonly
+ * @type {bool}
+ * @memberOf KeyframeAnimation
+ */
+ get alternate() { return this._alternate; }
+
+ /**
+ * Source array of images
+ *
+ * @readonly
+ * @type {array}
+ * @memberOf KeyframeAnimation
+ */
+ get source() { return this._source.slice(); }
+
+ /**
+ * Array of NativeImage instances loaded based on source input
+ *
+ * @readonly
+ * @type {Electron.NativeImage[]}
+ * @memberOf KeyframeAnimation
+ */
+ get nativeImages() { return this._nativeImages.slice(); }
+
+ /**
+ * Flag that tells whether animation finished
+ *
+ * @readonly
+ * @type {bool}
+ * @memberOf KeyframeAnimation
+ */
+ get isFinished() { return this._isFinished; }
+
+ /**
+ * Create animation using file sequence
+ *
+ * @static
+ * @param {string} filePattern - file name pattern where {s} is replaced with index
+ * @param {number[]} range - sequence range [start, end]
+ *
+ * @memberOf KeyframeAnimation
+ * @return {KeyframeAnimation}
+ */
+ static fromFileSequence(filePattern, range) {
+ assert(range.length === 2 && range[0] < range[1]);
+
+ let images = [];
+ for(let i = range[0]; i <= range[1]; i++) {
+ images.push(filePattern.replace('{s}', i));
+ }
+
+ return new KeyframeAnimation(images);
+ }
+
+ /**
+ * Creates an instance of KeyframeAnimation.
+ * @param {string[]} images
+ *
+ * @memberOf KeyframeAnimation
+ */
+ constructor(images) {
+ assert(images.length > 0);
+
+ this._source = images.slice();
+ this._nativeImages = images.map((pathOrNativeImage) => {
+ if(typeof(pathOrNativeImage) === 'string') {
+ return nativeImage.createFromPath(pathOrNativeImage);
+ } else if((pathOrNativeImage + '') === '[object NativeImage]') {
+ return pathOrNativeImage;
+ }
+ return nativeImage.createEmpty();
+ });
+
+ this._speed = 200; // ms
+ this._repeat = false;
+ this._reverse = false;
+ this._alternate = false;
+
+ this._numFrames = images.length;
+ this._currentFrame = 0;
+ this._frameRange = [0, this._numFrames];
+ this._isFinished = false;
+
+ this._isFirstRun = true;
+ }
+
+ /**
+ * Get current sprite
+ *
+ * @readonly
+ * @type {Electron.NativeImage}
+ * @memberOf KeyframeAnimation
+ */
+ get currentImage() {
+ return this._nativeImages[this._currentFrame];
+ }
+
+ /**
+ * Prepare initial state for animation before running it.
+ * @param {object} [options = {}] - animation options
+ * @param {number} [options.startFrame] - start frame
+ * @param {number} [options.endFrame] - end frame
+ * @param {bool} [options.beginFromCurrentState] - continue animation from current state
+ * @param {string} [options.advanceTo] - resets current frame. (possible values: end)
+ * @memberOf KeyframeAnimation
+ */
+ play(options = {}) {
+ let { startFrame, endFrame, beginFromCurrentState, advanceTo } = options;
+
+ if(startFrame !== undefined && endFrame !== undefined) {
+ assert(startFrame >= 0 && startFrame < this._numFrames);
+ assert(endFrame >= 0 && endFrame < this._numFrames);
+
+ if(startFrame < endFrame) {
+ this._frameRange = [ startFrame, endFrame ];
+ } else {
+ this._frameRange = [ endFrame, startFrame ];
+ }
+ } else {
+ this._frameRange = [ 0, this._numFrames - 1 ];
+ }
+
+ if(!beginFromCurrentState || this._isFirstRun) {
+ this._currentFrame = this._frameRange[this._reverse ? 1 : 0];
+ }
+
+ if(this._isFirstRun) {
+ this._isFirstRun = false;
+ }
+
+ if(advanceTo === 'end') {
+ this._currentFrame = this._frameRange[this._reverse ? 0 : 1];
+ }
+
+ this._isFinished = false;
+
+ this._unscheduleUpdate();
+
+ this._render();
+ this._scheduleUpdate();
+ }
+
+ /**
+ * Stop animation
+ * @memberOf KeyframeAnimation
+ */
+ stop() {
+ this._unscheduleUpdate();
+ }
+
+ _unscheduleUpdate() {
+ if(this._timeout) {
+ clearTimeout(this._timeout);
+ this._timeout = null;
+ }
+ }
+
+ _scheduleUpdate() {
+ this._timeout = setTimeout(::this._onUpdateFrame, this._speed);
+ }
+
+ _render() {
+ if(this._onFrame) {
+ this._onFrame(this._nativeImages[this._currentFrame]);
+ }
+ }
+
+ _didFinish() {
+ if(this._onFinish) {
+ this._onFinish();
+ }
+ }
+
+ _onUpdateFrame() {
+ this._advanceFrame();
+
+ if(!this._isFinished) {
+ this._render();
+ this._scheduleUpdate();
+ }
+ }
+
+ /**
+ * Advance animation frame
+ * @memberOf KeyframeAnimation
+ */
+ _advanceFrame() {
+ // do not advance frame when animation is finished
+ if(this._isFinished) { return; }
+
+ // advance frame
+ let didReachEnd = this._currentFrame === this._frameRange[this._reverse ? 0 : 1];
+
+ // did reach end?
+ if(didReachEnd) {
+ // mark animation as finished if it's not marked as repeating
+ if(!this._repeat) {
+ this._isFinished = true;
+
+ this._didFinish();
+ return;
+ }
+
+ // change animation direction if marked for alternation
+ if(this._alternate) {
+ this._reverse = !this._reverse;
+
+ this._currentFrame = this._nextFrame(this._currentFrame, this._frameRange, this._reverse);
+ } else {
+ this._currentFrame = this._frameRange[this._reverse ? 1 : 0];
+ }
+ } else {
+ this._currentFrame = this._nextFrame(this._currentFrame, this._frameRange, this._reverse);
+ }
+ }
+
+ /**
+ * Calculate next frame
+ * @private
+ * @param {number} cur - current frame
+ * @param {number[]} frameRange - frame range
+ * @param {bool} isReverse - reverse sequence direction?
+ * @returns {number}
+ *
+ * @memberOf KeyframeAnimation
+ */
+ _nextFrame(cur, frameRange, isReverse) {
+ if(isReverse) {
+ if(cur < frameRange[0]) {
+ return cur + 1;
+ } else if(cur > frameRange[0]) {
+ return cur - 1;
+ }
+ } else {
+ if(cur > frameRange[1]) {
+ return cur - 1;
+ } else if(cur < frameRange[1]) {
+ return cur + 1;
+ }
+ }
+ return cur;
+ }
+
+} \ No newline at end of file
diff --git a/app/lib/tray-animation.js b/app/lib/tray-animation.js
deleted file mode 100644
index 618d0383c0..0000000000
--- a/app/lib/tray-animation.js
+++ /dev/null
@@ -1,264 +0,0 @@
-import assert from 'assert';
-import { nativeImage } from 'electron';
-
-/**
- * Tray animation descriptor
- *
- * @export
- * @class TrayAnimation
- */
-export default class TrayAnimation {
-
- /**
- * Set animation pace per frame in ms
- *
- * @type {number}
- * @memberOf TrayAnimation
- */
- set speed(v) { this._speed = parseInt(v); }
-
- /**
- * Get animation pace per frame in ms
- *
- * @readonly
- * @type {number}
- * @memberOf TrayAnimation
- */
- get speed() { return this._speed; }
-
- /**
- * Set animation repetition
- * @type {bool}
- *
- * @memberOf TrayAnimation
- */
- set repeat(v) { this._repeat = !!v; }
-
- /**
- * Get animation repetition
- *
- * @readonly
- * @type {bool}
- * @memberOf TrayAnimation
- */
- get repeat() { return this._repeat; }
-
- /**
- * Set animation reversal
- * @type {bool}
- * @memberOf TrayAnimation
- */
- set reverse(v) { this._reverse = !!v; }
-
- /**
- * Get animation reversal
- *
- * @readonly
- * @type {bool}
- * @memberOf TrayAnimation
- */
- get reverse() { return this._repeat; }
-
- /**
- * Set animation alternation
- * @type {bool}
- * @memberOf TrayAnimation
- */
- set alternate(v) { this._alternate = !!v; }
-
- /**
- * Get animation alternation
- *
- * @readonly
- * @type {bool}
- * @memberOf TrayAnimation
- */
- get alternate() { return this._alternate; }
-
- /**
- * Source array of images
- *
- * @readonly
- * @type {array}
- * @memberOf TrayAnimation
- */
- get source() { return this._source.slice(); }
-
- /**
- * Array of NativeImage instances loaded based on source input
- *
- * @readonly
- * @type {Electron.NativeImage[]}
- * @memberOf TrayAnimation
- */
- get nativeImages() { return this._nativeImages.slice(); }
-
- /**
- * Flag that tells whether animation finished
- *
- * @readonly
- * @type {bool}
- * @memberOf TrayAnimation
- */
- get isFinished() { return this._isFinished; }
-
- /**
- * Create animation using file sequence
- *
- * @static
- * @param {string} filePattern - file name pattern where {s} is replaced with index
- * @param {number[]} range - sequence range [start, end]
- *
- * @memberOf TrayAnimation
- * @return {TrayAnimation}
- */
- static fromFileSequence(filePattern, range) {
- assert(range.length === 2 && range[0] < range[1]);
-
- let images = [];
- for(let i = range[0]; i <= range[1]; i++) {
- images.push(filePattern.replace('{s}', i));
- }
-
- return new TrayAnimation(images);
- }
-
- /**
- * Creates an instance of TrayAnimation.
- * @param {string[]} images
- *
- * @memberOf TrayAnimation
- */
- constructor(images) {
- assert(images.length > 0);
-
- this._source = images.slice();
- this._nativeImages = images.map((pathOrNativeImage) => {
- if(typeof(pathOrNativeImage) === 'string') {
- return nativeImage.createFromPath(pathOrNativeImage);
- } else if((pathOrNativeImage + '') === '[object NativeImage]') {
- return pathOrNativeImage;
- }
- return nativeImage.createEmpty();
- });
-
- this._speed = 200; // ms
- this._repeat = false;
- this._reverse = false;
- this._alternate = false;
-
- this._numFrames = images.length;
- this._currentFrame = 0;
- this._isFinished = false;
- }
-
- /**
- * Get current sprite
- *
- * @readonly
- * @type {Electron.NativeImage}
- * @memberOf TrayAnimation
- */
- get currentImage() {
- return this._nativeImages[this._currentFrame];
- }
-
- /**
- * Prepare initial state for animation before running it.
- * @memberOf TrayAnimation
- */
- prepare() {
- this._currentFrame = this._firstFrame(this._reverse);
- }
-
- /**
- * Advance animation to the start. This method respects animation reversal
- *
- * @memberOf TrayAnimation
- */
- advanceToStart() {
- this._currentFrame = this._firstFrame(this._reverse);
- }
-
- /**
- * Advance animation to the end. This method respects animation reversal
- *
- * @memberOf TrayAnimation
- */
- advanceToEnd() {
- this._currentFrame = this._lastFrame(this._reverse);
- }
-
- /**
- * Advance animation frame
- * @memberOf TrayAnimation
- */
- advanceFrame() {
- // do not advance frame when animation is finished
- if(this._isFinished) { return; }
-
- // advance frame
- let nextFrame = this._nextFrame(this._currentFrame, this._reverse);
-
- // did reach end?
- if(nextFrame < 0 || nextFrame >= this._numFrames) {
- // mark animation as finished if it's not marked as repeating
- if(!this._repeat) {
- this._isFinished = true;
- return;
- }
-
- // change animation direction if marked for alternation
- if(this._alternate) {
- this._reverse = !this._reverse;
-
- // clamp range
- nextFrame = Math.min(Math.max(0, nextFrame), this._numFrames - 1);
-
- // skip corner frame when alternating by advancing frame once again
- nextFrame = this._nextFrame(nextFrame, this._reverse);
- } else {
- nextFrame = this._firstFrame(this._reverse);
- }
- }
- this._currentFrame = nextFrame;
- }
-
- /**
- * Calculate next frame
- * @private
- * @param {number} cur - current frame
- * @param {bool} isReverse - reverse sequence direction?
- * @returns {number}
- *
- * @memberOf TrayAnimation
- */
- _nextFrame(cur, isReverse) {
- return cur + (isReverse ? -1 : 1);
- }
-
- /**
- * Get first frame of animation
- *
- * @param {bool} isReverse reverse animation?
- * @returns {number}
- *
- * @memberOf TrayAnimation
- */
- _firstFrame(isReverse) {
- return isReverse ? this._numFrames - 1 : 0;
- }
-
- /**
- * Get last frame of animation
- *
- * @param {bool} isReverse reverse animation?
- * @returns {number}
- *
- * @memberOf TrayAnimation
- */
- _lastFrame(isReverse) {
- return isReverse ? 0 : this._numFrames - 1;
- }
-
-} \ No newline at end of file
diff --git a/app/lib/tray-animator.js b/app/lib/tray-animator.js
deleted file mode 100644
index 9fb03b5588..0000000000
--- a/app/lib/tray-animator.js
+++ /dev/null
@@ -1,113 +0,0 @@
-import assert from 'assert';
-
-/**
- * Tray icon animator
- * @class TrayAnimator
- */
-export default class TrayAnimator {
-
- /**
- * Whether animator has started.
- * @readonly
- * @memberOf TrayAnimator
- */
- get isStarted() { return this._started; }
-
- /**
- * Creates an instance of TrayAnimator.
- * @param {Electron.Tray} tray - an instance of Tray
- * @param {TrayAnimation} animation - an instance of TrayAnimation
- *
- * @memberOf TrayAnimator
- */
- constructor(tray, animation) {
- assert(tray);
- assert(animation);
-
- this._tray = tray;
- this._animation = animation;
- this._started = false;
- this._timer = null;
- }
-
- /**
- * Advance animation to the start *
- * @memberOf TrayAnimator
- */
- advanceToStart() {
- this._animation.advanceToStart();
- this._updateTrayIcon();
- }
-
- /**
- * Advance animation to the end
- * @memberOf TrayAnimator
- */
- advanceToEnd() {
- this._animation.advanceToEnd();
- this._updateTrayIcon();
- }
-
- /**
- * Start animating
- * @memberOf TrayAnimator
- */
- start() {
- if(this._started) { return; }
-
- this._timer = this._nextFrame();
- this._started = true;
-
- // prepare animation
- this._animation.prepare();
-
- // update from initial frame
- this._updateTrayIcon();
- }
-
- /**
- * Stop animating
- * @memberOf TrayAnimator
- */
- stop() {
- if(!this._started) { return; }
-
- this._started = false;
-
- clearTimeout(this._timer);
- this._timer = null;
- }
-
- /**
- * Schedules next animation frame
- * @returns {number} timer ID
- * @memberOf TrayAnimator
- */
- _nextFrame() {
- return setTimeout(::this._updateAnimationFrame, this._animation.speed);
- }
-
- /**
- * Updates animation frame
- * @memberOf TrayAnimator
- */
- _updateAnimationFrame() {
- if(!this._started) { return; }
-
- this._animation.advanceFrame();
- this._updateTrayIcon();
-
- if(!this._animation.isFinished) {
- this._nextFrame();
- }
- }
-
- /**
- * Update tray icon with current frame
- * @memberOf TrayAnimator
- */
- _updateTrayIcon() {
- this._tray.setImage(this._animation.currentImage);
- }
-
-}
diff --git a/app/lib/tray-icon-manager.js b/app/lib/tray-icon-manager.js
index 987698a23d..82c226d3f6 100644
--- a/app/lib/tray-icon-manager.js
+++ b/app/lib/tray-icon-manager.js
@@ -1,7 +1,7 @@
import assert from 'assert';
-import TrayAnimator from './tray-animator';
-import TrayIconProvider from './tray-icon-provider';
+import path from 'path';
import { TrayIconType } from '../enums';
+import KeyframeAnimation from './keyframe-animation';
/**
* Tray icon manager
@@ -14,17 +14,19 @@ export default class TrayIconManager {
/**
* Creates an instance of TrayIconManager.
* @param {Electron.Tray} tray
- * @param {TrayIconProvider} iconProvider
*
* @memberOf TrayIconManager
*/
- constructor(tray, iconProvider) {
+ constructor(tray) {
assert(tray);
- assert(iconProvider);
- this._tray = tray;
- this._iconProvider = iconProvider;
- this._animator = null;
+ const basePath = path.join(path.resolve(__dirname, '..'), 'assets/images/menubar icons');
+ let filePath = path.join(basePath, 'lock-{s}.png');
+ let animation = KeyframeAnimation.fromFileSequence(filePath, [1, 9]);
+ animation.onFrame = (img) => tray.setImage(img);
+ animation.speed = 100;
+
+ this._animation = animation;
this._iconType = null;
}
@@ -33,9 +35,9 @@ export default class TrayIconManager {
* @memberOf TrayIconManager
*/
destroy() {
- if(this._animator) {
- this._animator.stop();
- this._animator = null;
+ if(this._animation) {
+ this._animation.stop();
+ this._animation = null;
}
this._iconType = null;
}
@@ -67,64 +69,47 @@ export default class TrayIconManager {
*
* @memberOf TrayIconManager
*/
- _updateIconType(type) {
+ _updateIconType(type) {
// no-op if same animator requested
if(this._iconType === type) { return; }
- // skip animation if:
- // 1. there was no icon set before (which is usually when app starts)
- // 2. unsecured -> securing
- // 3. securing -> unsecured
- const skip = this._iconType === null ||
- type === TrayIconType.securing || // unsecured -> securing
- (type === TrayIconType.unsecured && this._iconType === TrayIconType.securing); // securing -> unsecured
-
- // do not animate if setting icon for the first time
- this._updateType(type, skip);
- }
-
- /**
- * Get animation for iconType
- *
- * @param {TrayIconType} type
- * @returns TrayIconAnimator
- *
- * @memberOf TrayIconManager
- */
- _animationForType(type) {
- switch(type) {
- case TrayIconType.secured: return this._iconProvider.lockAnimation();
- case TrayIconType.unsecured: return this._iconProvider.unlockAnimation();
- case TrayIconType.securing: return this._iconProvider.unlockAnimation();
- }
+ this._updateType(type);
}
/**
* Update icon animator with new type
*
* @param {TrayIconType} type
- * @param {boolean} [skipAnimation=false] whether animation should be skipped
*
* @memberOf TrayIconManager
*/
- _updateType(type, skipAnimation = false) {
+ _updateType(type) {
assert(TrayIconType.isValid(type));
- let animator = new TrayAnimator(this._tray, this._animationForType(type));
+ let options = { beginFromCurrentState: true };
- // destroy existing animator
- if(this._animator) {
- this._animator.stop();
- this._animator = null;
+ switch(type) {
+ case TrayIconType.secured:
+ this._animation.reverse = false;
+ break;
+ case TrayIconType.securing:
+ case TrayIconType.unsecured:
+ this._animation.reverse = true;
+ break;
}
- if(skipAnimation) {
- animator.advanceToEnd();
- } else {
- animator.start();
+ if(this._iconType === null) {
+ options.advanceTo = 'end';
}
+
+ this._animation.play(options);
+
+ // if(skipAnimation) {
+ // animator.advanceToEnd();
+ // } else {
+ // animator.start();
+ // }
- this._animator = animator;
this._iconType = type;
}
diff --git a/app/lib/tray-icon-provider.js b/app/lib/tray-icon-provider.js
deleted file mode 100644
index aa50a71a71..0000000000
--- a/app/lib/tray-icon-provider.js
+++ /dev/null
@@ -1,47 +0,0 @@
-import path from 'path';
-import { EventEmitter } from 'events';
-import TrayAnimation from './tray-animation';
-import Enum from './enum';
-
-const menubarIcons = {
- base: path.join(path.resolve(__dirname, '..'), 'assets/images/menubar icons'),
- lock: 'lock-{s}.png'
-};
-
-/**
- * Tray icon provider
- *
- * @export
- * @class TrayIconProvider
- */
-export default class TrayIconProvider {
-
- /**
- * Get lock animation
- *
- * @param {boolean} [isReverse=false] whether animation should be reversed
- * @returns TrayIconAnimator
- *
- * @memberOf TrayIconProvider
- */
- lockAnimation(isReverse = false) {
- let filePath = path.join(menubarIcons.base, menubarIcons.lock);
- let animation = TrayAnimation.fromFileSequence(filePath, [1, 9]);
- animation.speed = 100;
- animation.reverse = isReverse;
-
- return animation;
- }
-
- /**
- * Get unlock animation
- *
- * @returns TrayIconAnimator
- *
- * @memberOf TrayIconProvider
- */
- unlockAnimation() {
- return this.lockAnimation(true);
- }
-
-} \ No newline at end of file
diff --git a/app/main.js b/app/main.js
index 374ece212b..2534cfa089 100644
--- a/app/main.js
+++ b/app/main.js
@@ -1,7 +1,6 @@
import path from 'path';
import { app, crashReporter, BrowserWindow, ipcMain, Tray, Menu, nativeImage } from 'electron';
import TrayIconManager from './lib/tray-icon-manager';
-import TrayIconProvider from './lib/tray-icon-provider';
// Override appData path to avoid collisions with old client
// New userData path, i.e on macOS: ~/Library/Application Support/mullvad.vpn
@@ -158,9 +157,9 @@ const showWindow = () => {
const createTray = () => {
tray = new Tray(nativeImage.createEmpty());
tray.on('click', toggleWindow);
- tray.setHighlightMode('selection');
+ tray.setHighlightMode('never');
- trayIconManager = new TrayIconManager(tray, new TrayIconProvider());
+ trayIconManager = new TrayIconManager(tray);
};
crashReporter.start({