browser-window.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. 'use strict'
  2. const electron = require('electron')
  3. const { WebContentsView, TopLevelWindow } = electron
  4. const { BrowserWindow } = process.atomBinding('window')
  5. Object.setPrototypeOf(BrowserWindow.prototype, TopLevelWindow.prototype)
  6. BrowserWindow.prototype._init = function () {
  7. // Call parent class's _init.
  8. TopLevelWindow.prototype._init.call(this)
  9. // Avoid recursive require.
  10. const { app } = electron
  11. // Create WebContentsView.
  12. this.setContentView(new WebContentsView(this.webContents))
  13. const nativeSetBounds = this.setBounds
  14. this.setBounds = (bounds, ...opts) => {
  15. bounds = {
  16. ...this.getBounds(),
  17. ...bounds
  18. }
  19. nativeSetBounds.call(this, bounds, ...opts)
  20. }
  21. // window.resizeTo(...)
  22. // window.moveTo(...)
  23. this.webContents.on('move', (event, size) => {
  24. this.setBounds(size)
  25. })
  26. // Hide the auto-hide menu when webContents is focused.
  27. this.webContents.on('activate', () => {
  28. if (process.platform !== 'darwin' && this.isMenuBarAutoHide() && this.isMenuBarVisible()) {
  29. this.setMenuBarVisibility(false)
  30. }
  31. })
  32. // Change window title to page title.
  33. this.webContents.on('page-title-updated', (event, title, ...args) => {
  34. // Route the event to BrowserWindow.
  35. this.emit('page-title-updated', event, title, ...args)
  36. if (!this.isDestroyed() && !event.defaultPrevented) this.setTitle(title)
  37. })
  38. // Sometimes the webContents doesn't get focus when window is shown, so we
  39. // have to force focusing on webContents in this case. The safest way is to
  40. // focus it when we first start to load URL, if we do it earlier it won't
  41. // have effect, if we do it later we might move focus in the page.
  42. //
  43. // Though this hack is only needed on macOS when the app is launched from
  44. // Finder, we still do it on all platforms in case of other bugs we don't
  45. // know.
  46. this.webContents.once('load-url', function () {
  47. this.focus()
  48. })
  49. // Redirect focus/blur event to app instance too.
  50. this.on('blur', (event) => {
  51. app.emit('browser-window-blur', event, this)
  52. })
  53. this.on('focus', (event) => {
  54. app.emit('browser-window-focus', event, this)
  55. })
  56. // Subscribe to visibilityState changes and pass to renderer process.
  57. let isVisible = this.isVisible() && !this.isMinimized()
  58. const visibilityChanged = () => {
  59. const newState = this.isVisible() && !this.isMinimized()
  60. if (isVisible !== newState) {
  61. isVisible = newState
  62. const visibilityState = isVisible ? 'visible' : 'hidden'
  63. this.webContents.emit('-window-visibility-change', visibilityState)
  64. }
  65. }
  66. const visibilityEvents = ['show', 'hide', 'minimize', 'maximize', 'restore']
  67. for (const event of visibilityEvents) {
  68. this.on(event, visibilityChanged)
  69. }
  70. // Notify the creation of the window.
  71. app.emit('browser-window-created', {}, this)
  72. Object.defineProperty(this, 'devToolsWebContents', {
  73. enumerable: true,
  74. configurable: false,
  75. get () {
  76. return this.webContents.devToolsWebContents
  77. }
  78. })
  79. }
  80. const isBrowserWindow = (win) => {
  81. return win && win.constructor.name === 'BrowserWindow'
  82. }
  83. BrowserWindow.fromId = (id) => {
  84. const win = TopLevelWindow.fromId(id)
  85. return isBrowserWindow(win) ? win : null
  86. }
  87. BrowserWindow.getAllWindows = () => {
  88. return TopLevelWindow.getAllWindows().filter(isBrowserWindow)
  89. }
  90. BrowserWindow.getFocusedWindow = () => {
  91. for (const window of BrowserWindow.getAllWindows()) {
  92. if (window.isFocused() || window.isDevToolsFocused()) return window
  93. }
  94. return null
  95. }
  96. BrowserWindow.fromWebContents = (webContents) => {
  97. for (const window of BrowserWindow.getAllWindows()) {
  98. if (window.webContents.equal(webContents)) return window
  99. }
  100. }
  101. BrowserWindow.fromBrowserView = (browserView) => {
  102. for (const window of BrowserWindow.getAllWindows()) {
  103. if (window.getBrowserView() === browserView) return window
  104. }
  105. return null
  106. }
  107. BrowserWindow.fromDevToolsWebContents = (webContents) => {
  108. for (const window of BrowserWindow.getAllWindows()) {
  109. const { devToolsWebContents } = window
  110. if (devToolsWebContents != null && devToolsWebContents.equal(webContents)) {
  111. return window
  112. }
  113. }
  114. }
  115. // Helpers.
  116. Object.assign(BrowserWindow.prototype, {
  117. loadURL (...args) {
  118. return this.webContents.loadURL(...args)
  119. },
  120. getURL (...args) {
  121. return this.webContents.getURL()
  122. },
  123. loadFile (...args) {
  124. return this.webContents.loadFile(...args)
  125. },
  126. reload (...args) {
  127. return this.webContents.reload(...args)
  128. },
  129. send (...args) {
  130. return this.webContents.send(...args)
  131. },
  132. openDevTools (...args) {
  133. return this.webContents.openDevTools(...args)
  134. },
  135. closeDevTools () {
  136. return this.webContents.closeDevTools()
  137. },
  138. isDevToolsOpened () {
  139. return this.webContents.isDevToolsOpened()
  140. },
  141. isDevToolsFocused () {
  142. return this.webContents.isDevToolsFocused()
  143. },
  144. toggleDevTools () {
  145. return this.webContents.toggleDevTools()
  146. },
  147. inspectElement (...args) {
  148. return this.webContents.inspectElement(...args)
  149. },
  150. inspectServiceWorker () {
  151. return this.webContents.inspectServiceWorker()
  152. },
  153. showDefinitionForSelection () {
  154. return this.webContents.showDefinitionForSelection()
  155. },
  156. capturePage (...args) {
  157. return this.webContents.capturePage(...args)
  158. },
  159. setTouchBar (touchBar) {
  160. electron.TouchBar._setOnWindow(touchBar, this)
  161. },
  162. setBackgroundThrottling (allowed) {
  163. this.webContents.setBackgroundThrottling(allowed)
  164. }
  165. })
  166. module.exports = BrowserWindow