Skip to content

Commit f58940b

Browse files
authored
Merging development into main for 0.20.0 release
A series of improvements and bug-fixes
2 parents 5c42aeb + 65273aa commit f58940b

30 files changed

+1073
-400
lines changed

.github/workflows/build.yml

+30-19
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,11 @@ jobs:
2424
matrix:
2525
config:
2626
- os: [self-hosted, windows-sign-pc]
27+
id: windows
2728
- os: ubuntu-latest
28-
- os: macos-13
29-
- os: macos-14
29+
id: linux
30+
- os: macos-latest
31+
id: macos-universal
3032
runs-on: ${{ matrix.config.os }}
3133
timeout-minutes: 90
3234

@@ -92,9 +94,9 @@ jobs:
9294
npm run build
9395
9496
- name: Upload [GitHub Actions]
95-
uses: actions/upload-artifact@v3
97+
uses: actions/upload-artifact@v4
9698
with:
97-
name: ${{ env.JOB_TRANSFER_ARTIFACT }}
99+
name: ${{ env.JOB_TRANSFER_ARTIFACT }}-${{ matrix.config.id }}
98100
path: dist
99101

100102
artifacts:
@@ -108,26 +110,29 @@ jobs:
108110
artifact:
109111
- path: "*-linux_x64.zip"
110112
name: Arduino-Lab-for-MicroPython_Linux_X86-64
111-
- path: "*-mac_x64.zip"
112-
name: Arduino-Lab-for-MicroPython_macOS_X86-64
113-
- path: "*-mac_arm64.zip"
114-
name: Arduino-Lab-for-MicroPython_macOS_arm-64
113+
id: linux
114+
- path: "*-mac_universal.zip"
115+
name: Arduino-Lab-for-MicroPython_macOS_Universal
116+
id: macos-universal
115117
# - path: "*Windows_64bit.exe"
116118
# name: Windows_X86-64_interactive_installer
119+
# id: windows
117120
# - path: "*Windows_64bit.msi"
118121
# name: Windows_X86-64_MSI
122+
# id: windows
119123
- path: "*-win_x64.zip"
120124
name: Arduino-Lab-for-MicroPython_Windows_X86-64
125+
id: windows
121126

122127
steps:
123128
- name: Download job transfer artifact
124-
uses: actions/download-artifact@v3
129+
uses: actions/download-artifact@v4
125130
with:
126-
name: ${{ env.JOB_TRANSFER_ARTIFACT }}
131+
name: ${{ env.JOB_TRANSFER_ARTIFACT }}-${{ matrix.artifact.id }}
127132
path: ${{ env.JOB_TRANSFER_ARTIFACT }}
128133

129134
- name: Upload tester build artifact
130-
uses: actions/upload-artifact@v3
135+
uses: actions/upload-artifact@v4
131136
with:
132137
name: ${{ matrix.artifact.name }}
133138
path: ${{ env.JOB_TRANSFER_ARTIFACT }}/${{ matrix.artifact.path }}
@@ -137,23 +142,25 @@ jobs:
137142
if: github.repository == 'arduino/lab-micropython-editor' && startsWith(github.ref, 'refs/tags/')
138143
runs-on: ubuntu-latest
139144
steps:
140-
- name: Download [GitHub Actions]
141-
uses: actions/download-artifact@v3
145+
- name: Download all artifacts
146+
uses: actions/download-artifact@v4
142147
with:
143-
name: ${{ env.JOB_TRANSFER_ARTIFACT }}
144-
path: ${{ env.JOB_TRANSFER_ARTIFACT }}
148+
path: artifacts
149+
150+
- name: List artifacts
151+
run: ls -R artifacts
145152

146153
- name: Get Tag
147154
id: tag_name
148155
run: |
149-
echo ::set-output name=TAG_NAME::${GITHUB_REF#refs/tags/}
156+
echo "TAG_NAME=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
150157
151158
- name: Publish Release [GitHub]
152159
uses: svenstaro/[email protected]
153160
with:
154161
repo_token: ${{ secrets.GITHUB_TOKEN }}
155162
release_name: ${{ steps.tag_name.outputs.TAG_NAME }}
156-
file: ${{ env.JOB_TRANSFER_ARTIFACT }}/*
163+
file: artifacts/**/*
157164
tag: ${{ github.ref }}
158165
file_glob: true
159166

@@ -167,7 +174,11 @@ jobs:
167174
runs-on: ubuntu-latest
168175

169176
steps:
170-
- name: Remove unneeded job transfer artifact
177+
- name: Remove unneeded job transfer artifacts
171178
uses: geekyeggo/delete-artifact@v2
172179
with:
173-
name: ${{ env.JOB_TRANSFER_ARTIFACT }}
180+
name: |
181+
${{ env.JOB_TRANSFER_ARTIFACT }}-windows
182+
${{ env.JOB_TRANSFER_ARTIFACT }}-linux
183+
${{ env.JOB_TRANSFER_ARTIFACT }}-macos-x64
184+
${{ env.JOB_TRANSFER_ARTIFACT }}-macos-arm64

backend/ipc.js

+25
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const fs = require('fs')
22
const registerMenu = require('./menu.js')
33
const serial = require('./serial/serial.js').sharedInstance
4+
const { shell } = require('electron');
45

56
const {
67
openFolderDialog,
@@ -138,6 +139,30 @@ module.exports = function registerIPCHandlers(win, ipcMain, app, dialog) {
138139
registerMenu(win, state)
139140
})
140141

142+
ipcMain.handle('launch-app', async (event, urlScheme) => {
143+
// Launch an external app with a custom protocol
144+
return new Promise((resolve, reject) => {
145+
if(app.getApplicationNameForProtocol(urlScheme) === '') {
146+
resolve(false); // App not installed
147+
return;
148+
}
149+
150+
try {
151+
shell.openExternal(urlScheme).then(() => {
152+
resolve(true); // App opened successfully
153+
}).catch(() => {
154+
resolve(false); // App not installed
155+
});
156+
} catch (err) {
157+
reject(err);
158+
}
159+
});
160+
});
161+
162+
ipcMain.handle('open-url', async (event, url) => {
163+
shell.openExternal(url);
164+
});
165+
141166
win.on('close', (event) => {
142167
console.log('BrowserWindow', 'close')
143168
event.preventDefault()

backend/menu.js

+52-32
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,49 @@
11
const { app, Menu } = require('electron')
2+
const { shortcuts, disableShortcuts } = require('./shortcuts.js')
23
const path = require('path')
34
const serial = require('./serial/serial.js').sharedInstance
45
const openAboutWindow = require('about-window').default
5-
const shortcuts = require('./shortcuts.js')
6+
67
const { type } = require('os')
78

9+
let appInfoWindow = null
10+
11+
function closeAppInfo(win) {
12+
disableShortcuts(win, false)
13+
appInfoWindow.off('close', () => closeAppInfo(win))
14+
appInfoWindow = null
15+
16+
}
17+
function openAppInfo(win) {
18+
if (appInfoWindow != null) {
19+
appInfoWindow.show()
20+
} else {
21+
appInfoWindow = openAboutWindow({
22+
icon_path: path.resolve(__dirname, '../ui/arduino/media/about_image.png'),
23+
css_path: path.resolve(__dirname, '../ui/arduino/views/about.css'),
24+
copyright: '© Arduino SA 2022',
25+
package_json_dir: path.resolve(__dirname, '..'),
26+
bug_report_url: "https://github.com/arduino/lab-micropython-editor/issues",
27+
bug_link_text: "report an issue",
28+
homepage: "https://labs.arduino.cc",
29+
use_version_info: false,
30+
win_options: {
31+
parent: win,
32+
modal: true,
33+
},
34+
show_close_button: 'Close',
35+
})
36+
appInfoWindow.on('close', () => closeAppInfo(win));
37+
disableShortcuts(win, true)
38+
}
39+
}
40+
841
module.exports = function registerMenu(win, state = {}) {
942
const isMac = process.platform === 'darwin'
1043
const template = [
1144
...(isMac ? [{
1245
label: app.name,
1346
submenu: [
14-
{ role: 'about'},
15-
{ type: 'separator' },
1647
{ type: 'separator' },
1748
{ role: 'hide', accelerator: 'CmdOrCtrl+Shift+H' },
1849
{ role: 'hideOthers' },
@@ -24,7 +55,22 @@ module.exports = function registerMenu(win, state = {}) {
2455
{
2556
label: 'File',
2657
submenu: [
27-
isMac ? { role: 'close' } : { role: 'quit' }
58+
{ label: 'New',
59+
accelerator: shortcuts.menu.NEW,
60+
enabled: state.view === 'editor',
61+
click: () => win.webContents.send('shortcut-cmd', shortcuts.global.NEW)
62+
},
63+
{ label: 'Save',
64+
accelerator: shortcuts.menu.SAVE,
65+
enabled: state.view === 'editor',
66+
click: () => win.webContents.send('shortcut-cmd', shortcuts.global.SAVE)
67+
},
68+
{ label: 'Close tab',
69+
accelerator: 'CmdOrCtrl+W',
70+
enabled: state.view === 'editor',
71+
click: () => win.webContents.send('shortcut-cmd', shortcuts.global.CLOSE)
72+
},
73+
{ role: 'quit' }
2874
]
2975
},
3076
{
@@ -167,41 +213,15 @@ module.exports = function registerMenu(win, state = {}) {
167213
}
168214
},
169215
{
170-
label:'Info about this app',
171-
click: () => {
172-
openAboutWindow({
173-
icon_path: path.resolve(__dirname, '../ui/arduino/media/about_image.png'),
174-
css_path: path.resolve(__dirname, '../ui/arduino/views/about.css'),
175-
copyright: '© Arduino SA 2022',
176-
package_json_dir: path.resolve(__dirname, '..'),
177-
bug_report_url: "https://github.com/arduino/lab-micropython-editor/issues",
178-
bug_link_text: "report an issue",
179-
homepage: "https://labs.arduino.cc",
180-
use_version_info: false,
181-
win_options: {
182-
parent: win,
183-
modal: true,
184-
},
185-
show_close_button: 'Close',
186-
})
187-
}
216+
label:'About Arduino Lab for MicroPython',
217+
click: () => { openAppInfo(win) }
188218
},
189219
]
190220
}
191221
]
192222

193223
const menu = Menu.buildFromTemplate(template)
194224

195-
app.setAboutPanelOptions({
196-
applicationName: app.name,
197-
applicationVersion: app.getVersion(),
198-
copyright: app.copyright,
199-
credits: '(See "Info about this app" in the Help menu)',
200-
authors: ['Arduino'],
201-
website: 'https://arduino.cc',
202-
iconPath: path.join(__dirname, '../assets/image.png'),
203-
})
204-
205225
Menu.setApplicationMenu(menu)
206226

207227
}

backend/serial/serial-bridge.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ const SerialBridge = {
9797
return path.posix.join(navigation, target)
9898
},
9999
getFullPath: (root, navigation, file) => {
100-
return path.posix.join(root, navigation, file)
100+
return path.posix.join(root, navigation.replaceAll(path.win32.sep, path.posix.sep), file.replaceAll(path.win32.sep, path.posix.sep))
101101
},
102102
getParentPath: (navigation) => {
103103
return path.posix.dirname(navigation)

backend/shortcuts.js

+22-5
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,46 @@
1-
module.exports = {
1+
const { globalShortcut } = require('electron')
2+
let shortcutsActive = false
3+
const shortcuts = {
24
global: {
5+
CLOSE: 'CommandOrControl+W',
36
CONNECT: 'CommandOrControl+Shift+C',
47
DISCONNECT: 'CommandOrControl+Shift+D',
5-
SAVE: 'CommandOrControl+S',
68
RUN: 'CommandOrControl+R',
79
RUN_SELECTION: 'CommandOrControl+Alt+R',
810
RUN_SELECTION_WL: 'CommandOrControl+Alt+S',
911
STOP: 'CommandOrControl+H',
1012
RESET: 'CommandOrControl+Shift+R',
13+
NEW: 'CommandOrControl+N',
14+
SAVE: 'CommandOrControl+S',
1115
CLEAR_TERMINAL: 'CommandOrControl+L',
1216
EDITOR_VIEW: 'CommandOrControl+Alt+1',
1317
FILES_VIEW: 'CommandOrControl+Alt+2',
14-
ESC: 'Escape'
1518
},
1619
menu: {
20+
CLOSE: 'CmdOrCtrl+W',
1721
CONNECT: 'CmdOrCtrl+Shift+C',
1822
DISCONNECT: 'CmdOrCtrl+Shift+D',
19-
SAVE: 'CmdOrCtrl+S',
2023
RUN: 'CmdOrCtrl+R',
2124
RUN_SELECTION: 'CmdOrCtrl+Alt+R',
2225
RUN_SELECTION_WL: 'CmdOrCtrl+Alt+S',
2326
STOP: 'CmdOrCtrl+H',
2427
RESET: 'CmdOrCtrl+Shift+R',
28+
NEW: 'CmdOrCtrl+N',
29+
SAVE: 'CmdOrCtrl+S',
2530
CLEAR_TERMINAL: 'CmdOrCtrl+L',
2631
EDITOR_VIEW: 'CmdOrCtrl+Alt+1',
2732
FILES_VIEW: 'CmdOrCtrl+Alt+2'
28-
}
33+
},
34+
// Shortcuts
35+
}
36+
37+
function disableShortcuts (win, value) {
38+
console.log(value ? 'disabling' : 'enabling', 'shortcuts')
39+
win.send('ignore-shortcuts', value)
40+
}
41+
42+
module.exports = {
43+
shortcuts,
44+
disableShortcuts
2945
}
46+

index.js

+4-21
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
const { app, BrowserWindow, ipcMain, dialog, globalShortcut } = require('electron')
22
const path = require('path')
33
const fs = require('fs')
4-
const shortcuts = require('./backend/shortcuts.js').global
5-
64
const registerIPCHandlers = require('./backend/ipc.js')
75
const registerMenu = require('./backend/menu.js')
86

@@ -14,8 +12,8 @@ let splashTimestamp = null
1412
function createWindow () {
1513
// Create the browser window.
1614
win = new BrowserWindow({
17-
width: 720,
18-
height: 640,
15+
width: 820,
16+
height: 700,
1917
webPreferences: {
2018
nodeIntegration: false,
2119
webSecurity: true,
@@ -63,28 +61,13 @@ function createWindow () {
6361
})
6462
}
6563

66-
function shortcutAction(key) {
67-
win.webContents.send('shortcut-cmd', key);
68-
}
69-
70-
// Shortcuts
71-
function registerShortcuts() {
72-
Object.entries(shortcuts).forEach(([command, shortcut]) => {
73-
globalShortcut.register(shortcut, () => {
74-
shortcutAction(shortcut)
75-
});
76-
})
77-
}
78-
7964
app.on('ready', () => {
8065
createWindow()
81-
registerShortcuts()
8266

8367
win.on('focus', () => {
84-
registerShortcuts()
8568
})
69+
8670
win.on('blur', () => {
87-
globalShortcut.unregisterAll()
8871
})
8972

90-
})
73+
})

0 commit comments

Comments
 (0)