app.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. import * as fs from 'fs';
  2. import * as path from 'path';
  3. import { deprecate, Menu } from 'electron/main';
  4. const bindings = process._linkedBinding('electron_browser_app');
  5. const commandLine = process._linkedBinding('electron_common_command_line');
  6. const { app } = bindings;
  7. // Only one app object permitted.
  8. export default app;
  9. let dockMenu: Electron.Menu | null = null;
  10. // Properties.
  11. const nativeASGetter = app.isAccessibilitySupportEnabled;
  12. const nativeASSetter = app.setAccessibilitySupportEnabled;
  13. Object.defineProperty(app, 'accessibilitySupportEnabled', {
  14. get: () => nativeASGetter.call(app),
  15. set: (enabled) => nativeASSetter.call(app, enabled)
  16. });
  17. const nativeBCGetter = app.getBadgeCount;
  18. const nativeBCSetter = app.setBadgeCount;
  19. Object.defineProperty(app, 'badgeCount', {
  20. get: () => nativeBCGetter.call(app),
  21. set: (count) => nativeBCSetter.call(app, count)
  22. });
  23. const nativeNGetter = app.getName;
  24. const nativeNSetter = app.setName;
  25. Object.defineProperty(app, 'name', {
  26. get: () => nativeNGetter.call(app),
  27. set: (name) => nativeNSetter.call(app, name)
  28. });
  29. Object.assign(app, {
  30. commandLine: {
  31. hasSwitch: (theSwitch: string) => commandLine.hasSwitch(String(theSwitch)),
  32. getSwitchValue: (theSwitch: string) => commandLine.getSwitchValue(String(theSwitch)),
  33. appendSwitch: (theSwitch: string, value?: string) => commandLine.appendSwitch(String(theSwitch), typeof value === 'undefined' ? value : String(value)),
  34. appendArgument: (arg: string) => commandLine.appendArgument(String(arg))
  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. (app as any).isPackaged = (() => {
  48. const execFile = path.basename(process.execPath).toLowerCase();
  49. if (process.platform === 'win32') {
  50. return execFile !== 'electron.exe';
  51. }
  52. return execFile !== 'electron';
  53. })();
  54. app._setDefaultAppPaths = (packagePath) => {
  55. // Set the user path according to application's name.
  56. app.setPath('userData', path.join(app.getPath('appData'), app.name!));
  57. app.setPath('userCache', path.join(app.getPath('cache'), app.name!));
  58. app.setAppPath(packagePath);
  59. // Add support for --user-data-dir=
  60. if (app.commandLine.hasSwitch('user-data-dir')) {
  61. const userDataDir = app.commandLine.getSwitchValue('user-data-dir');
  62. if (path.isAbsolute(userDataDir)) app.setPath('userData', userDataDir);
  63. }
  64. };
  65. if (process.platform === 'darwin') {
  66. const setDockMenu = app.dock!.setMenu;
  67. app.dock!.setMenu = (menu) => {
  68. dockMenu = menu;
  69. setDockMenu(menu);
  70. };
  71. app.dock!.getMenu = () => dockMenu;
  72. }
  73. if (process.platform === 'linux') {
  74. const patternVmRSS = /^VmRSS:\s*(\d+) kB$/m;
  75. const patternVmHWM = /^VmHWM:\s*(\d+) kB$/m;
  76. const getStatus = (pid: number) => {
  77. try {
  78. return fs.readFileSync(`/proc/${pid}/status`, 'utf8');
  79. } catch {
  80. return '';
  81. }
  82. };
  83. const getEntry = (file: string, pattern: RegExp) => {
  84. const match = file.match(pattern);
  85. return match ? parseInt(match[1], 10) : 0;
  86. };
  87. const getProcessMemoryInfo = (pid: number) => {
  88. const file = getStatus(pid);
  89. return {
  90. workingSetSize: getEntry(file, patternVmRSS),
  91. peakWorkingSetSize: getEntry(file, patternVmHWM)
  92. };
  93. };
  94. const nativeFn = app.getAppMetrics;
  95. app.getAppMetrics = () => {
  96. const metrics = nativeFn.call(app);
  97. for (const metric of metrics) {
  98. metric.memory = getProcessMemoryInfo(metric.pid);
  99. }
  100. return metrics;
  101. };
  102. }
  103. // Routes the events to webContents.
  104. const events = ['certificate-error', 'select-client-certificate'];
  105. for (const name of events) {
  106. app.on(name as 'certificate-error', (event, webContents, ...args: any[]) => {
  107. webContents.emit(name, event, ...args);
  108. });
  109. }
  110. // Deprecate allowRendererProcessReuse but only if they set it to false, no need to log if
  111. // they are setting it to true
  112. deprecate.removeProperty({ __proto__: app } as any, 'allowRendererProcessReuse', [false]);