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

Fix white screen bug / Remove window flicker when starting hidden / Add "start automatically" setting #95

Merged
merged 3 commits into from
Jan 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"author": "jllankfo@ncsu.edu",
"license": "ISC",
"dependencies": {
"auto-launch": "^5.0.5",
"electron-context-menu": "^3.1.1",
"electron-store": "^8.0.0",
"sass": "^1.32.8"
Expand Down
57 changes: 50 additions & 7 deletions src/main.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Requires
const { app, nativeImage, BrowserWindow, Tray, Menu, ipcMain, BrowserView, shell, powerMonitor } = require('electron');
const constants = require('./constants');
const AutoLaunch = require('auto-launch')
const contextMenu = require('electron-context-menu');
const BadgeGenerator = require('./badge_generator');
const path = require('path');
Expand All @@ -11,7 +12,7 @@ const Url = require('url');
// Constants
const store = new Store();
const appPath = app.getAppPath();
const REFRESH_RATE = 1000; // 1 seconds
const REFRESH_RATE = 3000; // 3 seconds
const icon = path.join(appPath, 'images', constants.APPLICATION_ICON_MEDIUM);
const iconTray = path.join(appPath, 'images', constants.APPLICATION_ICON_SMALL);
const iconTrayDirty = path.join(appPath, 'images', constants.APPLICATION_ICON_SMALL_WITH_INDICATOR);
Expand Down Expand Up @@ -79,12 +80,14 @@ app.whenReady().then(createWindow);

// Creates and returns this application's main BrowserWindow, navigated to Google Voice.
function createWindow() {
// Create the window. If we have it on record, re-apply the window size last set by the user.
// Create the window, making it hidden initially. If we have
// it on record, re-apply the window size last set by the user.
const prefs = store.get('prefs') || {};
win = new BrowserWindow({
width: prefs.windowWidth || DEFAULT_WIDTH,
height: prefs.windowHeight || DEFAULT_HEIGHT,
icon,
show: false,
webPreferences: {
spellcheck: true,
preload: path.join(__dirname, 'preload.js'),
Expand Down Expand Up @@ -216,9 +219,10 @@ function createWindow() {

win.on('resize', saveWindowSize);

// Hide if startMinimized is true in prefs
if (prefs.startMinimized) {
win.hide();
// Now that we've finished creating and initializing the window, show
// it (unless the user has enabled the "start minimized" setting).
if (!prefs.startMinimized) {
win.show();
}

return win;
Expand All @@ -241,6 +245,7 @@ function loadGoogleVoice(loadExternal=false) {

// Invoked every "REFRESH_RATE" seconds. Parses the current notification count from Google
// Voice's markup and then has this application display it to the user in an appropriate way.
// Also implements a workaround for Electron's "blank white screen" bug that many users encounter.
function updateNotifications(app) {
if (!win || BrowserWindow.getAllWindows().length === 0) {
return;
Expand All @@ -261,6 +266,24 @@ function updateNotifications(app) {

processNotificationCount(app, sum);
});

// The following is a workaround for the Electron bug where after an indeterminate
// period of inactivity, the main application window turns into a blank white screen.
// When this happens, inspection shows that the loaded page consists of the following
// empty HTML markup:
//
// <html><head></head><body></body></html>
//
// As such, we perform a simple check as to whether the <body/> of our loaded page
// has become empty. If it has, then we automatically reload Google Voice for the
// user. This seems to eliminate the problem entirely, without any adverse effects,
// as once we detect an empty body, the application is already in a non-working state.
win.webContents.executeJavaScript("document.querySelector('body').childNodes.length").then(
(result) => {
if (result === 0){
loadGoogleVoice();
}
})
}

// Displays a specified notification count to the user (if it isn't already
Expand Down Expand Up @@ -422,12 +445,18 @@ ipcMain.handle('get-platform', () => {
});

// Returns an object representing the user's current settings store.
ipcMain.handle('get-user-prefs', (event) => {
ipcMain.handle('get-user-prefs', () => {
return store.get('prefs') || {};
});

// Returns a bool indicating whether this application is registered to start automatically at logon.
ipcMain.handle('get-start-automatically', async () => {
let autoLaunch = new AutoLaunch({name: constants.APPLICATION_NAME, path: app.getPath('exe')})
return await autoLaunch.isEnabled();
});

// Returns the current zoom level of this this application's main window.
ipcMain.handle('get-zoom-level', (event) => {
ipcMain.handle('get-zoom-level', () => {
return win.webContents.getZoomLevel();
});

Expand Down Expand Up @@ -467,6 +496,20 @@ ipcMain.on('pref-change-show-menubar', (e, showMenuBar) => {
store.set('prefs', prefs);
});

// Called when the "start automatically" checkbox has been checked/unchecked.
ipcMain.on('pref-change-start-automatically', (e, startAutomatically) => {
console.log(`"Start Automatically" changed to: ${startAutomatically}`);

// Register/unregister this application to be automatically started at logon.
let autoLaunch = new AutoLaunch({name: constants.APPLICATION_NAME, path: app.getPath('exe')})
if (startAutomatically) {
autoLaunch.enable();
}
else {
autoLaunch.disable();
}
});

// Called when the "start minimized" checkbox has been checked/unchecked.
ipcMain.on('pref-change-start-minimized', (e, startMinimized) => {
console.log(`"Start Minimized" changed to: ${startMinimized}`);
Expand Down
14 changes: 10 additions & 4 deletions src/pages/customize.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,27 +36,33 @@
<!--Options-->
<div class="form-group">
<label class="font-weight-bold">Options</label>

<!--"Show menu bar" checkbox (Windows/Linux only, will get hidden for Mac)-->
<div class="form-check" id="show-menubar-div">
<input class="form-check-input" type="checkbox" id="show-menubar">
<label class="form-check-label" for="show-menubar">Show menu bar</label>
</div>

<!--"Start automatically" checkbox-->
<div class="form-check">
<input class="form-check-input" type="checkbox" id="start-automatically">
<label class="form-check-label" for="start-automatically">Start application automatically at logon</label>
</div>

<!--"Start minimized" checkbox-->
<div class="form-check">
<input class="form-check-input" type="checkbox" id="start-minimized">
<label class="form-check-label" for="start-minimized">Start minimized to tray</label>
<label class="form-check-label" for="start-minimized">Start application minimized to tray</label>
</div>

<!--"Exit on close" checkbox-->
<div class="form-check">
<input class="form-check-input" type="checkbox" id="exit-on-close">
<label class="form-check-label" for="exit-on-close">Exit application when main window is closed</label>
</div>
</div>
</div>

<!--Place window buttons in this div.-->
<div id="second-row">
<!--"Close" button-->
Expand Down
9 changes: 9 additions & 0 deletions src/pages/customize.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@
});
}

// Set the "start automatically" checkbox based on the user's currently selected
// preference. Notify the main process whenever the preference changes.
const startAutomatically = document.getElementById('start-automatically');
startAutomatically.checked = await ipcRenderer.invoke('get-start-automatically');
startAutomatically.addEventListener('change', (e) => {
const checked = e.target.checked;
ipcRenderer.send('pref-change-start-automatically', checked);
});

// Set the "start minimized" checkbox based on the user's currently selected
// startup mode. Notify the main process whenever the user changes the mode.
const minimizedSetting = document.getElementById('start-minimized');
Expand Down