From e1190e471c3c5fa7439f7c3baa82daa920dc2c05 Mon Sep 17 00:00:00 2001 From: Christopher Greaves <28542943+Chris-Greaves@users.noreply.github.com> Date: Wed, 13 Nov 2019 01:27:57 +0000 Subject: [PATCH 1/2] Implement ability to minimise to Tray instead of Taskbar Added config option to minimize to the tray when clicking the close or minimize button. Added menu options for the tray icon Added ability to double click on the tray icon to open Added text in all languages --- src/background.js | 79 ++++++++++++++----- src/components/TopBar.vue | 12 ++- .../modals/settings/GeneralSettings.vue | 14 ++++ src/i18n/en.json | 1 + src/i18n/hr.json | 1 + src/i18n/pl.json | 1 + src/i18n/zh.json | 1 + src/repositories/settingsRepository.js | 1 + src/store/modules/settings.js | 8 ++ 9 files changed, 96 insertions(+), 22 deletions(-) diff --git a/src/background.js b/src/background.js index 128de0a..582a07b 100644 --- a/src/background.js +++ b/src/background.js @@ -1,9 +1,10 @@ 'use strict'; /* global __static */ -import {app, BrowserWindow, Menu, protocol} from 'electron'; -import {createProtocol, installVueDevtools} from 'vue-cli-plugin-electron-builder/lib'; +import { app, BrowserWindow, Tray, Menu, protocol } from 'electron'; +import { createProtocol, installVueDevtools } from 'vue-cli-plugin-electron-builder/lib'; import windowRepository from './windowRepository'; +import StateBlock from 'markdown-it/lib/rules_block/state_block'; const path = require('path'); @@ -18,11 +19,11 @@ const windowSettings = windowRepository(path.join(app.getPath('userData'), 'wind let win; // Standard scheme must be registered before the app is ready -protocol.registerSchemesAsPrivileged([{scheme: 'app', privileges: {secure: true}}]); +protocol.registerSchemesAsPrivileged([{ scheme: 'app', privileges: { secure: true } }]); function createWindow() { - windowSettings.updateWindowState({minWidth: 600}); + windowSettings.updateWindowState({ minWidth: 600 }); const windowConfig = windowSettings.getWindowState(); windowConfig.icon = path.join(__static, 'icon.png'); windowConfig.frame = false; @@ -34,6 +35,38 @@ function createWindow() { win = new BrowserWindow(windowConfig); win.userDataPath = path.join(app.getPath('userData'), 'backlog.json'); + let isQuiting; + + app.on('before-quit', function () { + isQuiting = true; + }); + + var appIcon = new Tray(path.join(__static, 'icon.png')) + + var contextMenu = Menu.buildFromTemplate([ + { + label: 'Show App', click: function () { + win.show() + } + }, + { + label: 'Quit', click: function () { + isQuiting = true + app.quit() + } + } + ]) + + appIcon.setContextMenu(contextMenu) + appIcon.setToolTip('Backlog') + appIcon.on('double-click', () => { + win.show(); + }) + + win.on('show', function () { + appIcon.setHighlightMode('always') + }) + if (process.platform === 'darwin') { Menu.setApplicationMenu(createMenuOnMac()); } else { @@ -61,7 +94,14 @@ function createWindow() { win.on('resize', () => windowSettings.updateWindowState(win.getBounds())); win.on('move', () => windowSettings.updateWindowState(win.getBounds())); - win.on('close', () => windowSettings.updateWindowState(win.getBounds())); + win.on('close', () => { + windowSettings.updateWindowState(win.getBounds()); + if (!isQuiting) { + event.preventDefault(); + window.hide(); + event.returnValue = false; + } + }); } // Quit when all windows are closed. @@ -84,7 +124,7 @@ app.on('activate', () => { // This method will be called when Electron has finished // initialization and is ready to create browser windows. // Some APIs can only be used after this event occurs. -app.on('ready', async() => { +app.on('ready', async () => { if (isDevelopment && !process.env.IS_TEST) { // Install Vue Devtools try { @@ -111,25 +151,24 @@ if (isDevelopment) { } } - function createMenuOnMac() { return Menu.buildFromTemplate([ { label: app.getName(), submenu: [ - {role: 'undo'}, - {role: 'redo'}, - {type: 'separator'}, - {role: 'cut'}, - {role: 'copy'}, - {role: 'paste'}, - {role: 'pasteandmatchstyle'}, - {role: 'delete'}, - {role: 'selectall'}, - {role: 'quit'}, - {role: 'hide'}, - {role: 'hideothers'}, - {role: 'unhide'}, + { role: 'undo' }, + { role: 'redo' }, + { type: 'separator' }, + { role: 'cut' }, + { role: 'copy' }, + { role: 'paste' }, + { role: 'pasteandmatchstyle' }, + { role: 'delete' }, + { role: 'selectall' }, + { role: 'quit' }, + { role: 'hide' }, + { role: 'hideothers' }, + { role: 'unhide' }, ], }, ]); diff --git a/src/components/TopBar.vue b/src/components/TopBar.vue index 5c37398..6204e83 100644 --- a/src/components/TopBar.vue +++ b/src/components/TopBar.vue @@ -27,10 +27,18 @@ }, methods: { closeApp () { - remote.app.quit(); + if (this.$store.state.settings.minimizeToTray) { + remote.BrowserWindow.getFocusedWindow().hide(); + } else { + remote.app.quit(); + } }, minimize () { - remote.BrowserWindow.getFocusedWindow().minimize(); + if (this.$store.state.settings.minimizeToTray) { + remote.BrowserWindow.getFocusedWindow().hide(); + } else { + remote.BrowserWindow.getFocusedWindow().minimize(); + } } } }; diff --git a/src/components/modals/settings/GeneralSettings.vue b/src/components/modals/settings/GeneralSettings.vue index 43703fa..548ab01 100644 --- a/src/components/modals/settings/GeneralSettings.vue +++ b/src/components/modals/settings/GeneralSettings.vue @@ -5,6 +5,11 @@ {{$t('modals.show_creation_date_for_each_item')}} +