Skip to content

Commit 7d531ab

Browse files
committed
update
1 parent 1f31b47 commit 7d531ab

2 files changed

Lines changed: 79 additions & 53 deletions

File tree

Electron/main.js

Lines changed: 78 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,89 +1020,115 @@ callFakeMenu["exit"] = () => {
10201020
})
10211021
}
10221022

1023-
const devicesHID = {};
1024-
10251023
let deviceDialogOpen = false;
1024+
// Track callbacks we've already used so we never call the same Electron callback twice
1025+
const usedHIDCallbacks = new WeakSet();
10261026

10271027
const createHIDDialog = (deviceList, cbk) => {
1028-
if (deviceDialogOpen) return;
1028+
// If Electron passes us a callback we've already used, never touch it again.
1029+
if (usedHIDCallbacks.has(cbk)) {
1030+
console.log('HID: callback already used, ignoring this event');
1031+
return;
1032+
}
1033+
1034+
// If a dialog is already open, ignore new events and let the existing
1035+
// dialog eventually resolve its callback.
1036+
if (deviceDialogOpen) {
1037+
console.log('HID: dialog already open, ignoring this event');
1038+
return;
1039+
}
10291040

10301041
deviceDialogOpen = true;
10311042
let done = false;
10321043

1033-
console.log('HID Dialog!');
1044+
const finish = (id) => {
1045+
if (done) return; // never call the same callback more than once
1046+
done = true;
1047+
deviceDialogOpen = false;
10341048

1035-
const win = new BrowserWindow({
1036-
vibrancy: "sidebar", // in my case...
1037-
frame: true,
1038-
show: false,
1039-
titleBarStyle: 'hiddenInset',
1040-
width: 400,
1041-
height: 300,
1042-
resizable: false,
1043-
title: 'Device selector',
1044-
webPreferences: {
1045-
preload: path.join(__dirname, 'preload_device.js'),
1046-
webSecurity: false,
1047-
//nodeIntegration: true
1049+
if (!usedHIDCallbacks.has(cbk)) {
1050+
usedHIDCallbacks.add(cbk);
10481051
}
1049-
});
1050-
1051-
win.loadFile(path.join(__dirname, 'device.html'));
10521052

1053-
win.on('ready-to-show', () => {
1053+
try {
1054+
cbk(id);
1055+
} catch (err) {
1056+
console.error('Error in HID callback:', err);
1057+
}
1058+
};
10541059

1055-
const list = deviceList.map((e) => {
1056-
return {name: e.name || e.deviceName, id: e.deviceId}
1060+
console.log('HID Dialog (dialog.showMessageBox)!');
1061+
1062+
const list = (deviceList || []).map((e) => ({
1063+
name: e.name || e.deviceName || 'Unknown device',
1064+
id: e.deviceId
1065+
}));
1066+
1067+
// No devices -> show info dialog, then "cancel" selection
1068+
if (!list.length) {
1069+
dialog.showMessageBox({
1070+
type: 'info',
1071+
buttons: ['OK'],
1072+
defaultId: 0,
1073+
title: 'Device selector',
1074+
message: 'No devices available',
1075+
detail: 'No HID-compatible devices are currently available. Please connect a device and try again.',
1076+
noLink: true,
1077+
normalizeAccessKeys: true
1078+
})
1079+
.finally(() => {
1080+
finish(''); // signal "no selection"
10571081
});
1058-
console.log(deviceList);
1059-
10601082

1061-
win.webContents.send('load', {
1062-
list: list
1063-
});
1064-
1065-
ipcMain.once('choise_hid', (e, id) => {
1066-
done = true;
1067-
cbk(id);
1068-
win.close();
1069-
});
1083+
return;
1084+
}
10701085

1071-
win.show();
1072-
});
1086+
const buttons = list.map(d => d.name);
1087+
buttons.push('Cancel');
1088+
const cancelId = buttons.length - 1;
10731089

1074-
win.on('close', () => {
1075-
deviceDialogOpen = false;
1076-
if (done) return;
1077-
cbk('');
1090+
dialog.showMessageBox({
1091+
type: 'question',
1092+
buttons,
1093+
cancelId,
1094+
defaultId: 0,
1095+
title: 'Device selector',
1096+
message: 'Select a HID device',
1097+
detail: 'Choose the device you want to use from the list below.',
1098+
noLink: true,
1099+
normalizeAccessKeys: true
10781100
})
1079-
}
1101+
.then(({ response }) => {
1102+
if (response === cancelId) {
1103+
finish('');
1104+
} else {
1105+
const selected = list[response];
1106+
finish(selected ? selected.id : '');
1107+
}
1108+
})
1109+
.catch((err) => {
1110+
console.error('Error showing HID selection dialog:', err);
1111+
finish('');
1112+
});
1113+
};
10801114

10811115
/* permissions for the main window, special headers */
10821116
const setHID = (/** @type {BrowserWindow} */ mainWindow) => {
10831117

10841118

10851119
mainWindow.webContents.on('select-bluetooth-device', (event, deviceList, callback) => {
1086-
console.log('Select HID');
1087-
1120+
console.log('Select HID (bluetooth)');
10881121
event.preventDefault();
1089-
//select bluetooth
1090-
console.log('select bluetooth');
10911122
createHIDDialog(deviceList, callback);
10921123
return false;
10931124
});
1094-
1125+
10951126
mainWindow.webContents.session.on('select-hid-device', (event, details, callback) => {
1096-
// Add events to handle devices being added or removed before the callback on
1097-
// `select-hid-device` is called.
10981127
console.log('Select HID');
1099-
11001128
event.preventDefault();
1101-
1102-
console.log('select hid');
11031129
createHIDDialog(details.deviceList, callback);
11041130
return false;
1105-
})
1131+
});
11061132

11071133
mainWindow.webContents.session.setPermissionCheckHandler((webContents, permission, requestingOrigin, details) => {
11081134
return true

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "wljs-notebook",
3-
"version": "2.8.9",
3+
"version": "2.9.0",
44
"recommended-client-version": "2.6.3",
55
"description": "Dynamic Notebook Environment for Wolfram Language written in Javascript",
66
"author": {

0 commit comments

Comments
 (0)