Repository navigation
Expand file tree
/
Copy pathmain.js
More file actions
135 lines (118 loc) · 4.02 KB
/
Copy pathmain.js
File metadata and controls
135 lines (118 loc) · 4.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Adwaita Shell — Electron main process.
// Creates a fullscreen, frameless shell window and exposes a small IPC
// surface (system info, installed Windows apps, app launching, power).
const { app, BrowserWindow, ipcMain, shell, screen } = require('electron');
const fs = require('fs');
const path = require('path');
const os = require('os');
const { exec } = require('child_process');
let shellWindow = null;
function createShell() {
const primary = screen.getPrimaryDisplay();
const { width, height } = primary.bounds;
shellWindow = new BrowserWindow({
x: primary.bounds.x,
y: primary.bounds.y,
width,
height,
frame: false,
fullscreen: true,
autoHideMenuBar: true,
backgroundColor: '#1e1e1e',
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
contextIsolation: true,
nodeIntegration: false,
},
});
shellWindow.loadFile(path.join(__dirname, 'renderer', 'index.html'));
// Esc is handled in-page; allow quitting via the power menu (ipc) or Alt+F4.
shellWindow.on('closed', () => {
shellWindow = null;
});
}
// --- Installed-app discovery -------------------------------------------------
// Scans the Windows Start Menu shortcut folders for .lnk files so the app
// grid can launch real applications. Returns [] on non-Windows platforms.
function scanStartMenu() {
const roots = [
process.env.APPDATA &&
path.join(process.env.APPDATA, 'Microsoft', 'Windows', 'Start Menu', 'Programs'),
'C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs',
].filter(Boolean);
const found = new Map();
const skip = new Set(['uninstall', 'help', 'documentation', 'readme', 'license']);
const IGNORE = new Set(['desktop.ini']);
const walk = (dir, depth) => {
if (depth > 3) return;
let entries;
try {
entries = fs.readdirSync(dir, { withFileTypes: true });
} catch {
return;
}
for (const e of entries) {
const full = path.join(dir, e.name);
if (e.isDirectory()) {
walk(full, depth + 1);
} else if (e.name.toLowerCase().endsWith('.lnk') && !IGNORE.has(e.name.toLowerCase())) {
const name = e.name.replace(/\.lnk$/i, '');
if (skip.has(name.toLowerCase().split(' ')[0])) continue;
if (!found.has(name)) found.set(name, full);
}
}
};
roots.forEach((r) => walk(r, 0));
return [...found.entries()]
.map(([name, lnk]) => ({ name, path: lnk }))
.sort((a, b) => a.name.localeCompare(b.name));
}
// --- IPC -------------------------------------------------------------------
ipcMain.handle('shell:info', () => ({
platform: process.platform,
hostname: os.hostname(),
username: os.userInfo().username,
electron: process.versions.electron,
}));
ipcMain.handle('shell:list-apps', () => scanStartMenu());
ipcMain.handle('shell:launch', async (_evt, payload) => {
if (!payload || !payload.path) return { ok: false };
try {
// shell.openPath resolves .lnk shortcuts correctly on Windows.
const err = await shell.openPath(payload.path);
return err ? { ok: false, error: err } : { ok: true };
} catch (e) {
return { ok: false, error: String(e) };
}
});
ipcMain.handle('shell:power', (_evt, action) => {
switch (action) {
case 'quit':
app.quit();
return { ok: true };
case 'minimize':
if (shellWindow) shellWindow.minimize();
return { ok: true };
case 'lock':
// Lock the workstation underneath the shell.
if (process.platform === 'win32') exec('rundll32.exe user32.dll,LockWorkStation');
return { ok: true };
case 'suspend':
if (process.platform === 'win32') exec('rundll32.exe powrprof.dll,SetSuspendState 0,1,0');
return { ok: true };
default:
return { ok: false };
}
});
ipcMain.handle('shell:devtools', () => {
if (shellWindow) shellWindow.webContents.toggleDevTools();
});
app.whenReady().then(() => {
createShell();
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) createShell();
});
});
app.on('window-all-closed', () => {
app.quit();
});