electron-menubar 1.0.2 → 10.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,37 +1,77 @@
1
1
  {
2
2
  "name": "electron-menubar",
3
- "version": "1.0.2",
4
- "description": "Easy way to create an electron menubar application.",
5
- "main": "index.js",
3
+ "version": "10.1.1",
4
+ "description": "high level way to create menubar desktop applications with electron",
5
+ "keywords": [
6
+ "app",
7
+ "electron",
8
+ "linux",
9
+ "mac",
10
+ "menu",
11
+ "menubar",
12
+ "shell",
13
+ "taskbar",
14
+ "tray",
15
+ "traybar",
16
+ "windows"
17
+ ],
18
+ "homepage": "https://github.com/gitify-app/electron-menubar",
19
+ "bugs": {
20
+ "url": "https://github.com/gitify-app/electron-menubar/issues"
21
+ },
22
+ "license": "BSD-2-Clause",
23
+ "author": "Gitify",
24
+ "contributors": [
25
+ "Afonso Jorge Ramos (https://github.com/afonsojramos)",
26
+ "Adam Setch (https://github.com/setchy)"
27
+ ],
6
28
  "repository": {
7
29
  "type": "git",
8
- "url": "https://github.com/hacdias/electron-menubar.git"
30
+ "url": "git+https://github.com/gitify-app/electron-menubar.git"
31
+ },
32
+ "files": [
33
+ "assets/IconTemplate.png",
34
+ "assets/IconTemplate@2x.png",
35
+ "lib"
36
+ ],
37
+ "main": "lib/index.cjs",
38
+ "module": "lib/index.mjs",
39
+ "types": "lib/index.d.cts",
40
+ "exports": {
41
+ ".": {
42
+ "import": {
43
+ "types": "./lib/index.d.mts",
44
+ "default": "./lib/index.mjs"
45
+ },
46
+ "require": {
47
+ "types": "./lib/index.d.cts",
48
+ "default": "./lib/index.cjs"
49
+ }
50
+ }
51
+ },
52
+ "publishConfig": {
53
+ "access": "public"
9
54
  },
10
55
  "scripts": {
11
- "test": "standard",
12
- "lint": "standard"
56
+ "build": "vp pack",
57
+ "lint:check": "vp check",
58
+ "lint": "vp check --fix",
59
+ "test": "vp test",
60
+ "test:e2e": "playwright test --config tests/e2e/playwright.config.ts",
61
+ "test:visual": "node tests/visual/run.mts",
62
+ "typecheck": "tsc --noEmit"
13
63
  },
14
- "keywords": [
15
- "electron",
16
- "atom",
17
- "shell",
18
- "menubar",
19
- "menu",
20
- "mac",
21
- "windows",
22
- "linux",
23
- "app"
24
- ],
25
- "author": "Henrique Dias <hacdias@gmail.com>",
26
- "license": "MIT",
27
64
  "devDependencies": {
28
- "pre-commit": "^1.2.2",
29
- "standard": "^12.0.1"
65
+ "@playwright/test": "1.61.1",
66
+ "@types/pngjs": "6.0.5",
67
+ "electron": "43.0.0",
68
+ "pngjs": "7.0.0",
69
+ "typescript": "6.0.3",
70
+ "vite-plus": "0.2.1",
71
+ "vitest": "npm:@voidzero-dev/vite-plus-test@0.1.24"
30
72
  },
31
- "dependencies": {
32
- "lodash.merge": "^4.6.1"
73
+ "peerDependencies": {
74
+ "electron": "43.0.0"
33
75
  },
34
- "pre-commit": [
35
- "lint"
36
- ]
76
+ "packageManager": "pnpm@11.9.0"
37
77
  }
package/.travis.yml DELETED
@@ -1,4 +0,0 @@
1
- language: node_js
2
-
3
- node_js:
4
- - node
package/index.js DELETED
@@ -1,7 +0,0 @@
1
- const Menubar = require('./menubar')
2
- const Positioner = require('./positioner')
3
-
4
- module.exports = {
5
- Menubar: Menubar,
6
- Positioner: Positioner
7
- }
package/menubar.js DELETED
@@ -1,179 +0,0 @@
1
- const path = require('path')
2
- const Positioner = require('./positioner')
3
- const merge = require('lodash.merge')
4
- const { EventEmitter } = require('events')
5
- const electron = require('electron')
6
- const { app, Tray, BrowserWindow } = electron
7
-
8
- const defaults = {
9
- preloadWindow: false,
10
- showDockIcon: false,
11
- showOnRightClick: false,
12
- showOnAllWorkspaces: true,
13
- tooltip: '',
14
- window: {
15
- width: 400,
16
- height: 400,
17
- show: false,
18
- frame: false
19
- }
20
- }
21
-
22
- /**
23
- * Class Menubar.
24
- */
25
- class Menubar extends EventEmitter {
26
- constructor (opts) {
27
- super()
28
-
29
- if (typeof opts !== 'object') {
30
- opts = {}
31
- }
32
-
33
- opts = merge(defaults, opts)
34
-
35
- if (!opts.index) {
36
- opts.index = `file://${path.join(app.getAppPath(), 'index.html')}`
37
- }
38
-
39
- if (!opts.icon) {
40
- opts.icon = path.join(app.getAppPath(), 'icon.png')
41
- }
42
-
43
- this.opts = opts
44
- this.ready = false
45
- this.cachedBounds = null
46
- this.window = null
47
-
48
- if (app.isReady()) {
49
- this._appReady()
50
- } else {
51
- app.on('ready', this._appReady.bind(this))
52
- }
53
- }
54
-
55
- /**
56
- * This sets up the tray. Must only be called once.
57
- *
58
- * @returns {void}
59
- */
60
- _appReady () {
61
- if (app.dock && !this.opts.showDockIcon) {
62
- app.dock.hide()
63
- }
64
-
65
- let clickEvent = this.opts.showOnRightClick ? 'right-click' : 'click'
66
-
67
- this.tray = new Tray(this.opts.icon)
68
- this.tray.on(clickEvent, this._clicked.bind(this))
69
- this.tray.on('double-click', this._clicked.bind(this))
70
- this.tray.setToolTip(this.opts.tooltip)
71
- this.tray.setHighlightMode('never')
72
-
73
- if (this.opts.preloadWindow) {
74
- this._createWindow()
75
- }
76
-
77
- this.ready = true
78
- this.emit('ready')
79
- }
80
-
81
- /**
82
- * Creates the Window. Must only be called once.
83
- *
84
- * @returns {void}
85
- */
86
- _createWindow () {
87
- this.emit('create-window')
88
-
89
- this.window = new BrowserWindow(this.opts.window)
90
-
91
- if (this.opts.showOnAllWorkspaces !== false) {
92
- this.window.setVisibleOnAllWorkspaces(true)
93
- }
94
-
95
- this.window.on('close', () => {
96
- this.window = null
97
- })
98
-
99
- this.window.on('blur', () => {
100
- if (!this.window.isAlwaysOnTop()) this.hide()
101
- })
102
-
103
- this.window.loadURL(this.opts.index)
104
- this.emit('after-create-window')
105
- }
106
-
107
- /**
108
- * Triggered when clicking the tray icon.
109
- *
110
- * @param {Event} event
111
- * @param {Rectangle} bounds
112
- *
113
- * @returns {void}
114
- */
115
- _clicked (event, bounds) {
116
- // Hide the window if clicking with ALT/SHIFT/CTRL or Meta keys.
117
- if (event.altKey || event.shiftKey || event.ctrlKey || event.metaKey) {
118
- return this.hide()
119
- }
120
-
121
- // If there is a window and it is already visible, hide it.
122
- if (this.window && this.window.isVisible()) {
123
- return this.hide()
124
- }
125
-
126
- this.cachedBounds = bounds || this.cachedBounds
127
- this.show()
128
- }
129
-
130
- /**
131
- * Informs if the Menubar is already ready.
132
- *
133
- * @returns {void}
134
- */
135
- isReady () {
136
- return this.ready
137
- }
138
-
139
- /**
140
- * Hides the Window.
141
- *
142
- * @returns {void}
143
- */
144
- hide () {
145
- this.tray.setHighlightMode('never')
146
- if (!this.window) return
147
- this.emit('hide')
148
- this.window.hide()
149
- this.emit('after-hide')
150
- }
151
-
152
- /**
153
- * Shows the Window.
154
- *
155
- * @returns {void}
156
- */
157
- show () {
158
- this.tray.setHighlightMode('always')
159
- if (!this.window) {
160
- this._createWindow()
161
- }
162
-
163
- this.emit('show')
164
-
165
- if (!this.cachedBounds) {
166
- this.cachedBounds = this.tray.getBounds()
167
- }
168
-
169
- let pos = Positioner.calculate(this.window.getBounds(), this.cachedBounds)
170
- pos.x = (this.opts.window.x !== undefined) ? this.opts.window.x : pos.x
171
- pos.y = (this.opts.window.y !== undefined) ? this.opts.window.y : pos.y
172
-
173
- this.window.setPosition(pos.x, pos.y)
174
- this.window.show()
175
- this.emit('after-show')
176
- }
177
- }
178
-
179
- module.exports = Menubar
package/positioner.js DELETED
@@ -1,211 +0,0 @@
1
- const electron = require('electron')
2
-
3
- /**
4
- * Get the display nearest the current cursor position
5
- *
6
- * @return {Display} - the display closest to the current cursor position
7
- */
8
- function getDisplay () {
9
- const screen = electron.screen
10
- return screen.getDisplayNearestPoint(screen.getCursorScreenPoint())
11
- }
12
-
13
- /**
14
- * Get cursor position
15
- *
16
- * @return {Point} - the position of the cursor
17
- */
18
- function getCursorPosition () {
19
- return electron.screen.getCursorScreenPoint()
20
- }
21
-
22
- /**
23
- * Calculates the x position of the tray window
24
- *
25
- * @param {Rectangle} windowBounds - electron BrowserWindow bounds of tray window to position
26
- * @param {Rectangle} trayBounds - tray bounds from electron Tray.getBounds()
27
- * @param {string} [align] - align left|center|right, default: center
28
- *
29
- * @return {integer} - calculated x position
30
- */
31
- function calculateXAlign (windowBounds, trayBounds, align) {
32
- const display = getDisplay()
33
- let x
34
-
35
- switch (align) {
36
- case 'right':
37
- x = trayBounds.x
38
- break
39
- case 'left':
40
- x = trayBounds.x + trayBounds.width - windowBounds.width
41
- break
42
- case 'center':
43
- default:
44
- x = Math.round(trayBounds.x + (trayBounds.width / 2) - (windowBounds.width / 2))
45
- }
46
-
47
- if (x + windowBounds.width > display.bounds.width && align !== 'left') {
48
- // if window would overlap on right side align it to the end of the screen
49
- x = display.bounds.width - windowBounds.width
50
- } else if (x < 0 && align !== 'right') {
51
- // if window would overlap on the left side align it to the beginning
52
- x = 0
53
- }
54
-
55
- return x
56
- }
57
-
58
- /**
59
- * Calculates the y position of the tray window
60
- *
61
- * @param {Rectangle} windowBounds - electron BrowserWindow bounds
62
- * @param {Rectangle} trayBounds - tray bounds from electron Tray.getBounds()
63
- * @param {string} [align] - align up|middle|down, default: down
64
- *
65
- * @return {integer} - calculated y position
66
- */
67
- function calculateYAlign (windowBounds, trayBounds, align) {
68
- const display = getDisplay()
69
- let y
70
-
71
- switch (align) {
72
- case 'up':
73
- y = trayBounds.y + trayBounds.height - windowBounds.height
74
- break
75
- case 'down':
76
- y = trayBounds.y
77
- break
78
- case 'center':
79
- default:
80
- y = Math.round((trayBounds.y + (trayBounds.height / 2)) - (windowBounds.height / 2))
81
- break
82
- }
83
-
84
- if (y + windowBounds.height > display.bounds.height && align !== 'up') {
85
- y = trayBounds.y + trayBounds.height - windowBounds.height
86
- } else if (y < 0 && align !== 'down') {
87
- y = 0
88
- }
89
-
90
- return y
91
- }
92
-
93
- /**
94
- * Calculates the position of the tray window based on current cursor position
95
- * This method is used on linux where trayBounds are not available
96
- *
97
- * @param {Rectangle} windowBounds - electron BrowserWindow bounds of tray window to position
98
- * @param {Eelectron.Display} display - display on which the cursor is currently
99
- * @param {Point} cursor - current cursor position
100
- *
101
- * @return {Point} - Calculated point {x, y} where the window should be positioned
102
- */
103
- function calculateByCursorPosition (windowBounds, display, cursor) {
104
- let x = cursor.x
105
- let y = cursor.y
106
-
107
- if (x + windowBounds.width > display.bounds.width) {
108
- // if window would overlap on right side of screen, align it to the left of the cursor
109
- x -= windowBounds.width
110
- }
111
-
112
- if (y + windowBounds.height > display.bounds.height) {
113
- // if window would overlap at bottom of screen, align it up from cursor position
114
- y -= windowBounds.height
115
- }
116
-
117
- return {
118
- x: x,
119
- y: y
120
- }
121
- }
122
-
123
- class Positioner {
124
- /**
125
- * Calculates the position of the tray window
126
- *
127
- * @param {Rectangle} windowBounds - electron BrowserWindow bounds of tray window to position
128
- * @param {Rectangle} trayBounds - tray bounds from electron Tray
129
- * @param {Object} [alignment] - alignment of window to tray
130
- * @param {string} [alignment.x] - x align if tray bar is on top or bottom (left|center|right),
131
- default: center
132
- * @param {string} [alignment.y] - y align if tray bar is left or right (up|middle|down),
133
- default: down
134
- * @return {Point} - Calculated point {x, y} where the window should be positioned
135
- */
136
- static calculate (windowBounds, trayBounds, alignment) {
137
- if (process.platform === 'linux') {
138
- const cursor = getCursorPosition()
139
- return calculateByCursorPosition(windowBounds, getDisplay(), cursor)
140
- }
141
-
142
- const _alignment = alignment || {}
143
- const taskbarPosition = this.getTaskbarPosition()
144
- const display = getDisplay()
145
- let x
146
- let y
147
-
148
- switch (taskbarPosition) {
149
- case 'left':
150
- x = display.workArea.x
151
- y = calculateYAlign(windowBounds, trayBounds, _alignment.y)
152
- break
153
- case 'right':
154
- x = display.workArea.width - windowBounds.width
155
- y = calculateYAlign(windowBounds, trayBounds, _alignment.y)
156
- break
157
- case 'bottom':
158
- x = calculateXAlign(windowBounds, trayBounds, _alignment.x)
159
- y = display.workArea.height - windowBounds.height
160
- break
161
- case 'top':
162
- default:
163
- x = calculateXAlign(windowBounds, trayBounds, _alignment.x)
164
- y = display.workArea.y
165
- }
166
-
167
- return {
168
- x,
169
- y
170
- }
171
- }
172
-
173
- /**
174
- * Calculates the position of the tray window
175
- *
176
- * @param {BrowserWindow} window - window to position
177
- * @param {Rectangle} trayBounds - tray bounds from electron Tray
178
- * @param {Object} [alignment] - alignment of window to tray
179
- * @param {string} [alignment.x] - x align if tray bar is on top or bottom (left|center|right),
180
- default: center
181
- * @param {string} [alignment.y] - y align if tray bar is left or right (up|middle|down),
182
- default: down
183
- *
184
- * @return {Void}
185
- */
186
- static position (window, trayBounds, alignment) {
187
- const position = this.calculate(window.getBounds(), trayBounds, alignment)
188
- window.setPosition(position.x, position.y, false)
189
- }
190
-
191
- /**
192
- * Calculates the position of the tray window
193
- *
194
- * @return {string} - the position of the taskbar (top|right|bottom|left)
195
- */
196
- static getTaskbarPosition () {
197
- const { bounds, workArea } = getDisplay()
198
-
199
- if (workArea.y > bounds.y) {
200
- return 'top'
201
- } else if (workArea.x > bounds.x) {
202
- return 'left'
203
- } else if (workArea.width === bounds.width) {
204
- return 'bottom'
205
- }
206
-
207
- return 'right'
208
- }
209
- }
210
-
211
- module.exports = Positioner