|
1 | | -const { app, BrowserWindow, Menu, shell, screen, globalShortcut, ipcMain, Tray, nativeImage, dialog, crashReporter } = require('electron'); |
| 1 | +const { app, BrowserWindow, Menu, shell, screen, globalShortcut, ipcMain, Tray, nativeImage, dialog, crashReporter, session, systemPreferences } = require('electron'); |
2 | 2 | const path = require('path'); |
3 | 3 | const settings = require('./settings'); |
4 | 4 | const fileOperations = require('./fileOperations'); |
@@ -441,6 +441,29 @@ function registerIpcHandlers() { |
441 | 441 | } |
442 | 442 | }); |
443 | 443 |
|
| 444 | + // 摄像头权限(macOS) |
| 445 | + ipcMain.handle('media:getCameraStatus', () => { |
| 446 | + try { |
| 447 | + if (process.platform !== 'darwin') return 'not_supported'; |
| 448 | + return systemPreferences.getMediaAccessStatus('camera'); |
| 449 | + } catch (e) { |
| 450 | + return 'unknown'; |
| 451 | + } |
| 452 | + }); |
| 453 | + |
| 454 | + ipcMain.handle('media:askForCameraAccess', async () => { |
| 455 | + try { |
| 456 | + if (process.platform !== 'darwin') return false; |
| 457 | + const status = systemPreferences.getMediaAccessStatus('camera'); |
| 458 | + if (status === 'granted') return true; |
| 459 | + // 会触发系统弹窗(若已拒绝通常会直接返回 false) |
| 460 | + const ok = await systemPreferences.askForMediaAccess('camera'); |
| 461 | + return !!ok; |
| 462 | + } catch (e) { |
| 463 | + return false; |
| 464 | + } |
| 465 | + }); |
| 466 | + |
444 | 467 | // 获取窗口是否可见 |
445 | 468 | ipcMain.handle('quick-search:isVisible', () => { |
446 | 469 | return quickSearchWindow && !quickSearchWindow.isDestroyed() && quickSearchWindow.isVisible(); |
@@ -890,6 +913,26 @@ app.whenReady().then(() => { |
890 | 913 | app.setAsDefaultProtocolClient('devtools-suite'); |
891 | 914 | } |
892 | 915 | } |
| 916 | + |
| 917 | + // 摄像头/麦克风权限(用于 getUserMedia) |
| 918 | + // Electron 默认会自动放行权限请求,显式处理更可控 |
| 919 | + try { |
| 920 | + session.defaultSession.setPermissionRequestHandler((webContents, permission, callback, details) => { |
| 921 | + if (permission !== 'media') return callback(false); |
| 922 | + |
| 923 | + const requestingUrl = details?.requestingUrl || webContents.getURL() || ''; |
| 924 | + const allow = |
| 925 | + requestingUrl.startsWith('file://') || |
| 926 | + requestingUrl.startsWith('http://localhost:') || |
| 927 | + requestingUrl.startsWith('http://127.0.0.1:') || |
| 928 | + requestingUrl.startsWith('https://localhost:') || |
| 929 | + requestingUrl.startsWith('https://127.0.0.1:'); |
| 930 | + |
| 931 | + callback(allow); |
| 932 | + }); |
| 933 | + } catch (e) { |
| 934 | + console.warn('[Electron] 设置媒体权限处理失败:', e?.message || e); |
| 935 | + } |
893 | 936 |
|
894 | 937 | createWindow(); |
895 | 938 | createMenu(); |
|
0 commit comments