Skip to content

Commit a049efe

Browse files
committed
Add DisplayManager utility for improved display handling
1 parent d639144 commit a049efe

2 files changed

Lines changed: 102 additions & 105 deletions

File tree

app/main.js

Lines changed: 13 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import Command from './utils/commands.js'
2727
import { registerBreakShortcuts } from './utils/breakShortcuts.js'
2828
import defaultSettings from './utils/defaultSettings.js'
2929
import StatusMessages from './utils/statusMessages.js'
30+
import DisplayManager from './utils/displayManager.js'
3031

3132
const __filename = fileURLToPath(import.meta.url)
3233
const __dirname = dirname(__filename)
@@ -59,6 +60,7 @@ let breakIdeas
5960
let breakPlanner
6061
let appIcon = null
6162
let autostartManager = null
63+
let displayManager = null
6264
let processWin = null
6365
let microbreakWins = null
6466
let breakWins = null
@@ -272,6 +274,8 @@ async function initialize (isAppStart = true) {
272274
app
273275
})
274276

277+
displayManager = new DisplayManager(settings, log)
278+
275279
startI18next()
276280
startProcessWin()
277281
createWelcomeWindow()
@@ -379,7 +383,7 @@ function startPowerMonitoring () {
379383
}
380384

381385
function numberOfDisplays () {
382-
return screen.getAllDisplays().length
386+
return displayManager.getDisplayCount()
383387
}
384388

385389
function closeWindows (windowArray) {
@@ -395,115 +399,19 @@ function closeWindows (windowArray) {
395399
}
396400

397401
function displaysX (displayID = -1, width = 800, fullscreen = false) {
398-
let theScreen
399-
400-
if (!settings.get('allScreens')) {
401-
if (settings.get('screen') === 'primary') {
402-
theScreen = screen.getPrimaryDisplay()
403-
} else if (settings.get('screen') === 'cursor') {
404-
theScreen = screen.getDisplayNearestPoint(screen.getCursorScreenPoint())
405-
} else {
406-
displayID = parseInt(settings.get('screen'))
407-
}
408-
}
409-
410-
if (displayID === -1) {
411-
theScreen = screen.getDisplayNearestPoint(screen.getCursorScreenPoint())
412-
} else if (displayID >= numberOfDisplays() || displayID < 0) {
413-
log.warn(`Stretchly: invalid displayID ${displayID} to displaysX`)
414-
theScreen = screen.getDisplayNearestPoint(screen.getCursorScreenPoint())
415-
} else {
416-
const screens = screen.getAllDisplays()
417-
theScreen = screens[displayID]
418-
}
419-
const bounds = theScreen.bounds
420-
if (fullscreen) {
421-
return Math.ceil(bounds.x)
422-
} else {
423-
return Math.ceil(bounds.x + ((bounds.width - width) / 2))
424-
}
402+
return displayManager.getDisplayX(displayID, width, fullscreen)
425403
}
426404

427405
function displaysY (displayID = -1, height = 600, fullscreen = false) {
428-
let theScreen
429-
430-
if (!settings.get('allScreens')) {
431-
if (settings.get('screen') === 'primary') {
432-
theScreen = screen.getPrimaryDisplay()
433-
} else if (settings.get('screen') === 'cursor') {
434-
theScreen = screen.getDisplayNearestPoint(screen.getCursorScreenPoint())
435-
} else {
436-
displayID = parseInt(settings.get('screen'))
437-
}
438-
}
439-
440-
if (displayID === -1) {
441-
theScreen = screen.getDisplayNearestPoint(screen.getCursorScreenPoint())
442-
} else if (displayID >= numberOfDisplays() || displayID < 0) {
443-
log.warn(`Stretchly: invalid displayID ${displayID} to displaysY`)
444-
theScreen = screen.getDisplayNearestPoint(screen.getCursorScreenPoint())
445-
} else {
446-
const screens = screen.getAllDisplays()
447-
theScreen = screens[displayID]
448-
}
449-
const bounds = theScreen.bounds
450-
if (fullscreen) {
451-
return Math.ceil(bounds.y)
452-
} else {
453-
return Math.ceil(bounds.y + ((bounds.height - height) / 2))
454-
}
406+
return displayManager.getDisplayY(displayID, height, fullscreen)
455407
}
456408

457409
function displaysWidth (displayID = -1) {
458-
let theScreen
459-
460-
if (!settings.get('allScreens')) {
461-
if (settings.get('screen') === 'primary') {
462-
theScreen = screen.getPrimaryDisplay()
463-
} else if (settings.get('screen') === 'cursor') {
464-
theScreen = screen.getDisplayNearestPoint(screen.getCursorScreenPoint())
465-
} else {
466-
displayID = parseInt(settings.get('screen'))
467-
}
468-
}
469-
470-
if (displayID === -1) {
471-
theScreen = screen.getDisplayNearestPoint(screen.getCursorScreenPoint())
472-
} else if (displayID >= numberOfDisplays() || displayID < 0) {
473-
log.warn(`Stretchly: invalid displayID ${displayID} to displaysWidth`)
474-
theScreen = screen.getDisplayNearestPoint(screen.getCursorScreenPoint())
475-
} else {
476-
const screens = screen.getAllDisplays()
477-
theScreen = screens[displayID]
478-
}
479-
const bounds = theScreen.bounds
480-
return Math.ceil(bounds.width)
410+
return displayManager.getDisplayWidth(displayID)
481411
}
482412

483413
function displaysHeight (displayID = -1) {
484-
let theScreen
485-
486-
if (!settings.get('allScreens')) {
487-
if (settings.get('screen') === 'primary') {
488-
theScreen = screen.getPrimaryDisplay()
489-
} else if (settings.get('screen') === 'cursor') {
490-
theScreen = screen.getDisplayNearestPoint(screen.getCursorScreenPoint())
491-
} else {
492-
displayID = parseInt(settings.get('screen'))
493-
}
494-
}
495-
496-
if (displayID === -1) {
497-
theScreen = screen.getDisplayNearestPoint(screen.getCursorScreenPoint())
498-
} else if (displayID >= numberOfDisplays() || displayID < 0) {
499-
log.warn(`Stretchly: invalid displayID ${displayID} to displaysHeight`)
500-
theScreen = screen.getDisplayNearestPoint(screen.getCursorScreenPoint())
501-
} else {
502-
const screens = screen.getAllDisplays()
503-
theScreen = screens[displayID]
504-
}
505-
const bounds = theScreen.bounds
506-
return Math.ceil(bounds.height)
414+
return displayManager.getDisplayHeight(displayID)
507415
}
508416

509417
function trayIconPath () {
@@ -748,8 +656,8 @@ function startMicrobreak () {
748656

749657
for (let localDisplayId = 0; localDisplayId < numberOfDisplays(); localDisplayId++) {
750658
const windowOptions = {
751-
width: Number.parseInt(displaysWidth(localDisplayId) * settings.get('breakWindowWidth')),
752-
height: Number.parseInt(displaysHeight(localDisplayId) * settings.get('breakWindowHeight')),
659+
width: Math.floor(displaysWidth(localDisplayId) * settings.get('breakWindowWidth')),
660+
height: Math.floor(displaysHeight(localDisplayId) * settings.get('breakWindowHeight')),
753661
autoHideMenuBar: true,
754662
icon: windowIconPath(),
755663
resizable: false,
@@ -897,8 +805,8 @@ function startBreak () {
897805

898806
for (let localDisplayId = 0; localDisplayId < numberOfDisplays(); localDisplayId++) {
899807
const windowOptions = {
900-
width: Number.parseInt(displaysWidth(localDisplayId) * settings.get('breakWindowWidth')),
901-
height: Number.parseInt(displaysHeight(localDisplayId) * settings.get('breakWindowHeight')),
808+
width: Math.floor(displaysWidth(localDisplayId) * settings.get('breakWindowWidth')),
809+
height: Math.floor(displaysHeight(localDisplayId) * settings.get('breakWindowHeight')),
902810
autoHideMenuBar: true,
903811
icon: windowIconPath(),
904812
resizable: false,

app/utils/displayManager.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { screen } from 'electron'
2+
3+
class DisplayManager {
4+
constructor (settings, log) {
5+
this.settings = settings
6+
this.log = log
7+
}
8+
9+
getDisplayCount () {
10+
return screen.getAllDisplays().length
11+
}
12+
13+
getTargetDisplay (displayID = -1) {
14+
let targetScreen
15+
16+
// If not using all screens, check screen preference
17+
if (!this.settings.get('allScreens')) {
18+
const screenSetting = this.settings.get('screen')
19+
if (screenSetting === 'primary') {
20+
targetScreen = screen.getPrimaryDisplay()
21+
} else if (screenSetting === 'cursor') {
22+
targetScreen = screen.getDisplayNearestPoint(screen.getCursorScreenPoint())
23+
} else {
24+
displayID = parseInt(screenSetting)
25+
}
26+
}
27+
28+
// If we already have a target screen from settings, return it
29+
if (targetScreen) {
30+
return targetScreen
31+
}
32+
33+
// Handle displayID-based selection
34+
if (displayID === -1) {
35+
targetScreen = screen.getDisplayNearestPoint(screen.getCursorScreenPoint())
36+
} else if (displayID >= this.getDisplayCount() || displayID < 0) {
37+
this.log.warn(`Stretchly: invalid displayID ${displayID}, falling back to cursor display`)
38+
targetScreen = screen.getDisplayNearestPoint(screen.getCursorScreenPoint())
39+
} else {
40+
const screens = screen.getAllDisplays()
41+
targetScreen = screens[displayID]
42+
}
43+
44+
return targetScreen
45+
}
46+
47+
getDisplayBounds (displayID = -1) {
48+
return this.getTargetDisplay(displayID).bounds
49+
}
50+
51+
getDisplayX (displayID = -1, width = 800, fullscreen = false) {
52+
const bounds = this.getDisplayBounds(displayID)
53+
if (fullscreen) {
54+
return Math.floor(bounds.x)
55+
} else {
56+
return Math.floor(bounds.x + ((bounds.width - width) / 2))
57+
}
58+
}
59+
60+
getDisplayY (displayID = -1, height = 600, fullscreen = false) {
61+
const bounds = this.getDisplayBounds(displayID)
62+
if (fullscreen) {
63+
return Math.floor(bounds.y)
64+
} else {
65+
return Math.floor(bounds.y + ((bounds.height - height) / 2))
66+
}
67+
}
68+
69+
getDisplayWidth (displayID = -1) {
70+
const bounds = this.getDisplayBounds(displayID)
71+
return Math.floor(bounds.width)
72+
}
73+
74+
getDisplayHeight (displayID = -1) {
75+
const bounds = this.getDisplayBounds(displayID)
76+
return Math.floor(bounds.height)
77+
}
78+
79+
getWindowPosition (displayID = -1, { width = 800, height = 600, fullscreen = false } = {}) {
80+
return {
81+
x: this.getDisplayX(displayID, width, fullscreen),
82+
y: this.getDisplayY(displayID, height, fullscreen),
83+
width: fullscreen ? this.getDisplayWidth(displayID) : width,
84+
height: fullscreen ? this.getDisplayHeight(displayID) : height
85+
}
86+
}
87+
}
88+
89+
export default DisplayManager

0 commit comments

Comments
 (0)