DEV Community

Tomasz Wegrzanowski
Tomasz Wegrzanowski

Posted on

Electron Adventures: Episode 86: Remembering User Preferences

This is something I probably should have done much earlier in the series, but better late than never.

When user starts the app, it will place the window is some default position, and give it some deafult size, and that's fine. The user can then resize it and move it to whichever monitor and location they want.

The problem is that when the app quits, we never remember that.

Well, let's implement a simple way to remember window position. We'll use electron-settings to save our app settings in some JSON file in OS-appropriate place in the filesystem.

index.js

let { app, BrowserWindow } = require("electron")
let settings = require("electron-settings")

let windowState = settings.getSync("windowState") || {width: 800, height: 600}

function createWindow() {
  let win = new BrowserWindow({
    x: windowState.x,
    y: windowState.y,
    width: windowState.width,
    height: windowState.height,
    webPreferences: {
      preload: `${__dirname}/preload.js`,
    },
  })

  function saveSettings() {
    windowState = win.getBounds()
    console.log("SAVING", windowState)
    settings.setSync("windowState", windowState)
  }

  win.on("resize", saveSettings)
  win.on("move", saveSettings)
  win.on("close", saveSettings)

  win.loadURL("http://localhost:5000/")
}

app.on("ready", createWindow)

app.on("window-all-closed", () => {
  app.quit()
})
Enter fullscreen mode Exit fullscreen mode

So a few things to unpack here.

First, windowState is the variable storing our window state - if we don't have any we initialize it to {width: 800, height: 600}. Every time this variable changes we save it to JSON-backed settings too. And when the app restarts, we load it from that JSON.

When we create a new window, we use data from windowState. And finally we attach a few event handlers to update the windowState variable when the window is resized or moved.

Saved JSON

Location of the JSON file is based on name of the app, which is based on package.json. I put "name": "episode-86-remembering-user-preferences" in package.json, and on OSX that means the settings will go to ~/Library/Application\ Support/episode-86-remembering-user-preferences/settings.json and will look something like this:

{"windowState":{"x":1520,"y":780,"width":707,"height":517}}
Enter fullscreen mode Exit fullscreen mode

Limitations

This solution is good enough for single screen use, unfortunately it doesn't handle a few more complex issues:

  • what about maximized / fullscreen / minimized states - this part is OS specific, and we'd unfortunately need to do testing on every OS (and there were some Electron bugs related to such states). I'd say that generally we should not be remembering such special states, and just open the last "normal" window state, but it might vary by app.
  • if user has multiple screens, which screen is the window on
  • what happens if number of screens changes
  • what happens if position is no longer possible (because user is on a different screen, and app would be out of the screen)
  • what if the app has multiple windows

Fortunately packages that manage this for us already exist like electron-window-state, and hopefully they considered all such issues.

Results

Here's the results, remembering weird resizing I did:

Episode 86 Screenshot

In the next episode, we'll create a simple game board for our game.

As usual, all the code for the episode is here.

Discussion (0)