Skip to content

feature: add support for multiple displays #4

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

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
38 changes: 29 additions & 9 deletions src/background.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable import/no-extraneous-dependencies */
import path from 'path'
import sane, { Watcher } from 'sane'
import { app, protocol, powerMonitor, BrowserWindow, Tray } from 'electron'
import { app, BrowserWindow, Display, powerMonitor, protocol, screen, Tray } from 'electron'
import installExtension, { VUEJS_DEVTOOLS } from 'electron-devtools-installer'
import { createWindow, destroyMenu, createMenu, sleep } from './electron/utils'
// import pkg from '../package.json'
Expand All @@ -10,7 +10,7 @@ const isDevelopment = process.env.NODE_ENV !== 'production'

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let win: BrowserWindow | null
let allWindows: BrowserWindow[] = []
let appIcon: Tray | null
let watcher: Watcher | null

Expand All @@ -31,8 +31,9 @@ app.on('window-all-closed', () => {
app.on('activate', () => {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (win === null) {
win = createWindow()
const internalDisplayWindow = allWindows[0]
if (internalDisplayWindow === null) {
allWindows[0] = createWindow()
}
})

Expand All @@ -49,7 +50,25 @@ app.on('ready', async () => {
console.error('Vue Devtools failed to install:', e.toString())
}
}
win = createWindow()

const displays = screen.getAllDisplays()
const internalDisplays: Display[] = []
const externalDisplays: Display[] = []

displays.forEach(display => {
const isExternalDisplay = display.bounds.x !== 0 || display.bounds.y !== 0
if (isExternalDisplay) {
externalDisplays.push(display)
} else {
internalDisplays.push(display)
}
})

allWindows = [
...internalDisplays.map(createWindow),
...externalDisplays.map(externalDisplay => createWindow(externalDisplay)),
]

const widgetsFolderPath = path.resolve(__dirname, '../src/widgets')
const iconPath = path.resolve(__dirname, '../src/assets/logo.png')

Expand All @@ -60,21 +79,22 @@ app.on('ready', async () => {
})
app.dock.hide()

appIcon = await createMenu(win)
const internalDisplayWindow = allWindows[0]
appIcon = await createMenu(internalDisplayWindow)

// we need to refresh the tray menu when widgets are added or removed
watcher = sane(widgetsFolderPath, { glob: ['**/*.widget.vue'] })
watcher
.on('add', async () => {
destroyMenu(appIcon as Tray)
appIcon = await createMenu(win as BrowserWindow)
appIcon = await createMenu(internalDisplayWindow as BrowserWindow)
})
.on('delete', async () => {
destroyMenu(appIcon as Tray)
appIcon = await createMenu(win as BrowserWindow)
appIcon = await createMenu(internalDisplayWindow as BrowserWindow)
})
powerMonitor.on('resume', () => {
;(win as BrowserWindow).reload()
;(internalDisplayWindow as BrowserWindow).reload()
})
})

Expand Down
21 changes: 15 additions & 6 deletions src/electron/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import glob from 'glob'
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
import {
app,
shell,
BrowserWindow,
BrowserWindowConstructorOptions,
Display,
Menu,
MenuItem,
Tray,
nativeImage,
MenuItemConstructorOptions,
nativeImage,
shell,
Tray,
} from 'electron'

let win: BrowserWindow | null = null
Expand Down Expand Up @@ -48,8 +50,8 @@ function createSettingsWindow(): BrowserWindow {
return settingsWin
}

export function createWindow(): BrowserWindow {
win = new BrowserWindow({
export function createWindow(externalDisplay?: Display): BrowserWindow {
const displayConfig: BrowserWindowConstructorOptions = {
transparent: true,
backgroundColor: '#00FFFFFF',
width: 800,
Expand All @@ -60,7 +62,14 @@ export function createWindow(): BrowserWindow {
webPreferences: {
nodeIntegration: true,
},
})
}

if (externalDisplay) {
displayConfig.x = externalDisplay.bounds.x + 50
displayConfig.y = externalDisplay.bounds.y + 50
}

win = new BrowserWindow(displayConfig)
win.maximize()

loadWindow(win)
Expand Down