app.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import * as fs from 'fs';
  2. import { Menu, deprecate } from 'electron/main';
  3. const bindings = process._linkedBinding('electron_browser_app');
  4. const commandLine = process._linkedBinding('electron_common_command_line');
  5. const { app } = bindings;
  6. // Only one app object permitted.
  7. export default app;
  8. let dockMenu: Electron.Menu | null = null;
  9. // Properties.
  10. const nativeASGetter = app.isAccessibilitySupportEnabled;
  11. const nativeASSetter = app.setAccessibilitySupportEnabled;
  12. Object.defineProperty(app, 'accessibilitySupportEnabled', {
  13. get: () => nativeASGetter.call(app),
  14. set: (enabled) => nativeASSetter.call(app, enabled)
  15. });
  16. const nativeBCGetter = app.getBadgeCount;
  17. const nativeBCSetter = app.setBadgeCount;
  18. Object.defineProperty(app, 'badgeCount', {
  19. get: () => nativeBCGetter.call(app),
  20. set: (count) => nativeBCSetter.call(app, count)
  21. });
  22. const nativeNGetter = app.getName;
  23. const nativeNSetter = app.setName;
  24. Object.defineProperty(app, 'name', {
  25. get: () => nativeNGetter.call(app),
  26. set: (name) => nativeNSetter.call(app, name)
  27. });
  28. Object.assign(app, {
  29. commandLine: {
  30. hasSwitch: (theSwitch: string) => commandLine.hasSwitch(String(theSwitch)),
  31. getSwitchValue: (theSwitch: string) => commandLine.getSwitchValue(String(theSwitch)),
  32. appendSwitch: (theSwitch: string, value?: string) => commandLine.appendSwitch(String(theSwitch), typeof value === 'undefined' ? value : String(value)),
  33. appendArgument: (arg: string) => commandLine.appendArgument(String(arg)),
  34. removeSwitch: (theSwitch: string) => commandLine.removeSwitch(String(theSwitch))
  35. } as Electron.CommandLine
  36. });
  37. // we define this here because it'd be overly complicated to
  38. // do in native land
  39. Object.defineProperty(app, 'applicationMenu', {
  40. get () {
  41. return Menu.getApplicationMenu();
  42. },
  43. set (menu: Electron.Menu | null) {
  44. return Menu.setApplicationMenu(menu);
  45. }
  46. });
  47. // The native implementation is not provided on non-windows platforms
  48. app.setAppUserModelId = app.setAppUserModelId || (() => {});
  49. if (process.platform === 'darwin') {
  50. const setDockMenu = app.dock!.setMenu;
  51. app.dock!.setMenu = (menu) => {
  52. dockMenu = menu;
  53. setDockMenu(menu);
  54. };
  55. app.dock!.getMenu = () => dockMenu;
  56. }
  57. if (process.platform === 'linux') {
  58. const patternVmRSS = /^VmRSS:\s*(\d+) kB$/m;
  59. const patternVmHWM = /^VmHWM:\s*(\d+) kB$/m;
  60. const getStatus = (pid: number) => {
  61. try {
  62. return fs.readFileSync(`/proc/${pid}/status`, 'utf8');
  63. } catch {
  64. return '';
  65. }
  66. };
  67. const getEntry = (file: string, pattern: RegExp) => {
  68. const match = file.match(pattern);
  69. return match ? parseInt(match[1], 10) : 0;
  70. };
  71. const getProcessMemoryInfo = (pid: number) => {
  72. const file = getStatus(pid);
  73. return {
  74. workingSetSize: getEntry(file, patternVmRSS),
  75. peakWorkingSetSize: getEntry(file, patternVmHWM)
  76. };
  77. };
  78. const nativeFn = app.getAppMetrics;
  79. app.getAppMetrics = () => {
  80. const metrics = nativeFn.call(app);
  81. for (const metric of metrics) {
  82. metric.memory = getProcessMemoryInfo(metric.pid);
  83. }
  84. return metrics;
  85. };
  86. }
  87. // Routes the events to webContents.
  88. const events = ['certificate-error', 'select-client-certificate'];
  89. for (const name of events) {
  90. app.on(name as 'certificate-error', (event, webContents, ...args: any[]) => {
  91. webContents.emit(name, event, ...args);
  92. });
  93. }
  94. // Deprecation.
  95. deprecate.event(app, 'gpu-process-crashed', 'child-process-gone');
  96. deprecate.event(app, 'renderer-process-crashed', 'render-process-gone');