CefLifeSpanHandler.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. namespace Xilium.CefGlue
  2. {
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. using System.Runtime.InteropServices;
  7. using Xilium.CefGlue.Interop;
  8. /// <summary>
  9. /// Implement this interface to handle events related to browser life span. The
  10. /// methods of this class will be called on the UI thread unless otherwise
  11. /// indicated.
  12. /// </summary>
  13. public abstract unsafe partial class CefLifeSpanHandler
  14. {
  15. private int on_before_popup(cef_life_span_handler_t* self, cef_browser_t* browser, cef_frame_t* frame, cef_string_t* target_url, cef_string_t* target_frame_name, CefWindowOpenDisposition target_disposition, int user_gesture, cef_popup_features_t* popupFeatures, cef_window_info_t* windowInfo, cef_client_t** client, cef_browser_settings_t* settings, cef_dictionary_value_t** extra_info, int* no_javascript_access)
  16. {
  17. CheckSelf(self);
  18. var m_browser = CefBrowser.FromNative(browser);
  19. var m_frame = CefFrame.FromNative(frame);
  20. var m_targetUrl = cef_string_t.ToString(target_url);
  21. var m_targetFrameName = cef_string_t.ToString(target_frame_name);
  22. var m_userGesture = user_gesture != 0;
  23. var m_popupFeatures = new CefPopupFeatures(popupFeatures);
  24. var m_windowInfo = CefWindowInfo.FromNative(windowInfo);
  25. var m_client = CefClient.FromNative(*client);
  26. var m_settings = new CefBrowserSettings(settings);
  27. var m_extraInfo = CefDictionaryValue.FromNativeOrNull(*extra_info); // TODO dispose?
  28. var m_noJavascriptAccess = (*no_javascript_access) != 0;
  29. var o_extraInfo = m_extraInfo;
  30. var o_client = m_client;
  31. var result = OnBeforePopup(m_browser, m_frame, m_targetUrl, m_targetFrameName, target_disposition, m_userGesture, m_popupFeatures, m_windowInfo, ref m_client, m_settings, ref m_extraInfo, ref m_noJavascriptAccess);
  32. if ((object)o_client != m_client && m_client != null)
  33. {
  34. *client = m_client.ToNative();
  35. }
  36. if ((object)o_extraInfo != m_extraInfo)
  37. {
  38. *extra_info = m_extraInfo != null ? m_extraInfo.ToNative() : null;
  39. }
  40. *no_javascript_access = m_noJavascriptAccess ? 1 : 0;
  41. m_popupFeatures.Dispose();
  42. m_windowInfo.Dispose();
  43. m_settings.Dispose();
  44. return result ? 1 : 0;
  45. }
  46. /// <summary>
  47. /// Called on the UI thread before a new popup browser is created. The
  48. /// |browser| and |frame| values represent the source of the popup request. The
  49. /// |target_url| and |target_frame_name| values indicate where the popup
  50. /// browser should navigate and may be empty if not specified with the request.
  51. /// The |target_disposition| value indicates where the user intended to open
  52. /// the popup (e.g. current tab, new tab, etc). The |user_gesture| value will
  53. /// be true if the popup was opened via explicit user gesture (e.g. clicking a
  54. /// link) or false if the popup opened automatically (e.g. via the
  55. /// DomContentLoaded event). The |popupFeatures| structure contains additional
  56. /// information about the requested popup window. To allow creation of the
  57. /// popup browser optionally modify |windowInfo|, |client|, |settings| and
  58. /// |no_javascript_access| and return false. To cancel creation of the popup
  59. /// browser return true. The |client| and |settings| values will default to the
  60. /// source browser's values. If the |no_javascript_access| value is set to
  61. /// false the new browser will not be scriptable and may not be hosted in the
  62. /// same renderer process as the source browser. Any modifications to
  63. /// |windowInfo| will be ignored if the parent browser is wrapped in a
  64. /// CefBrowserView. Popup browser creation will be canceled if the parent
  65. /// browser is destroyed before the popup browser creation completes (indicated
  66. /// by a call to OnAfterCreated for the popup browser). The |extra_info|
  67. /// parameter provides an opportunity to specify extra information specific
  68. /// to the created popup browser that will be passed to
  69. /// CefRenderProcessHandler::OnBrowserCreated() in the render process.
  70. /// </summary>
  71. protected virtual bool OnBeforePopup(CefBrowser browser, CefFrame frame, string targetUrl, string targetFrameName, CefWindowOpenDisposition targetDisposition, bool userGesture, CefPopupFeatures popupFeatures, CefWindowInfo windowInfo, ref CefClient client, CefBrowserSettings settings, ref CefDictionaryValue extraInfo, ref bool noJavascriptAccess)
  72. {
  73. return false;
  74. }
  75. private void on_after_created(cef_life_span_handler_t* self, cef_browser_t* browser)
  76. {
  77. CheckSelf(self);
  78. var m_browser = CefBrowser.FromNative(browser);
  79. OnAfterCreated(m_browser);
  80. }
  81. /// <summary>
  82. /// Called after a new browser is created. This callback will be the first
  83. /// notification that references |browser|.
  84. /// </summary>
  85. protected virtual void OnAfterCreated(CefBrowser browser)
  86. {
  87. }
  88. private int do_close(cef_life_span_handler_t* self, cef_browser_t* browser)
  89. {
  90. CheckSelf(self);
  91. var m_browser = CefBrowser.FromNative(browser);
  92. return DoClose(m_browser) ? 1 : 0;
  93. }
  94. /// <summary>
  95. /// Called when a browser has recieved a request to close. This may result
  96. /// directly from a call to CefBrowserHost::*CloseBrowser() or indirectly if
  97. /// the browser is parented to a top-level window created by CEF and the user
  98. /// attempts to close that window (by clicking the 'X', for example). The
  99. /// DoClose() method will be called after the JavaScript 'onunload' event has
  100. /// been fired.
  101. /// An application should handle top-level owner window close notifications by
  102. /// calling CefBrowserHost::TryCloseBrowser() or
  103. /// CefBrowserHost::CloseBrowser(false) instead of allowing the window to close
  104. /// immediately (see the examples below). This gives CEF an opportunity to
  105. /// process the 'onbeforeunload' event and optionally cancel the close before
  106. /// DoClose() is called.
  107. /// When windowed rendering is enabled CEF will internally create a window or
  108. /// view to host the browser. In that case returning false from DoClose() will
  109. /// send the standard close notification to the browser's top-level owner
  110. /// window (e.g. WM_CLOSE on Windows, performClose: on OS X, "delete_event" on
  111. /// Linux or CefWindowDelegate::CanClose() callback from Views). If the
  112. /// browser's host window/view has already been destroyed (via view hierarchy
  113. /// tear-down, for example) then DoClose() will not be called for that browser
  114. /// since is no longer possible to cancel the close.
  115. /// When windowed rendering is disabled returning false from DoClose() will
  116. /// cause the browser object to be destroyed immediately.
  117. /// If the browser's top-level owner window requires a non-standard close
  118. /// notification then send that notification from DoClose() and return true.
  119. /// The CefLifeSpanHandler::OnBeforeClose() method will be called after
  120. /// DoClose() (if DoClose() is called) and immediately before the browser
  121. /// object is destroyed. The application should only exit after OnBeforeClose()
  122. /// has been called for all existing browsers.
  123. /// The below examples describe what should happen during window close when the
  124. /// browser is parented to an application-provided top-level window.
  125. /// Example 1: Using CefBrowserHost::TryCloseBrowser(). This is recommended for
  126. /// clients using standard close handling and windows created on the browser
  127. /// process UI thread.
  128. /// 1. User clicks the window close button which sends a close notification to
  129. /// the application's top-level window.
  130. /// 2. Application's top-level window receives the close notification and
  131. /// calls TryCloseBrowser() (which internally calls CloseBrowser(false)).
  132. /// TryCloseBrowser() returns false so the client cancels the window close.
  133. /// 3. JavaScript 'onbeforeunload' handler executes and shows the close
  134. /// confirmation dialog (which can be overridden via
  135. /// CefJSDialogHandler::OnBeforeUnloadDialog()).
  136. /// 4. User approves the close.
  137. /// 5. JavaScript 'onunload' handler executes.
  138. /// 6. CEF sends a close notification to the application's top-level window
  139. /// (because DoClose() returned false by default).
  140. /// 7. Application's top-level window receives the close notification and
  141. /// calls TryCloseBrowser(). TryCloseBrowser() returns true so the client
  142. /// allows the window close.
  143. /// 8. Application's top-level window is destroyed.
  144. /// 9. Application's OnBeforeClose() handler is called and the browser object
  145. /// is destroyed.
  146. /// 10. Application exits by calling CefQuitMessageLoop() if no other browsers
  147. /// exist.
  148. /// Example 2: Using CefBrowserHost::CloseBrowser(false) and implementing the
  149. /// DoClose() callback. This is recommended for clients using non-standard
  150. /// close handling or windows that were not created on the browser process UI
  151. /// thread.
  152. /// 1. User clicks the window close button which sends a close notification to
  153. /// the application's top-level window.
  154. /// 2. Application's top-level window receives the close notification and:
  155. /// A. Calls CefBrowserHost::CloseBrowser(false).
  156. /// B. Cancels the window close.
  157. /// 3. JavaScript 'onbeforeunload' handler executes and shows the close
  158. /// confirmation dialog (which can be overridden via
  159. /// CefJSDialogHandler::OnBeforeUnloadDialog()).
  160. /// 4. User approves the close.
  161. /// 5. JavaScript 'onunload' handler executes.
  162. /// 6. Application's DoClose() handler is called. Application will:
  163. /// A. Set a flag to indicate that the next close attempt will be allowed.
  164. /// B. Return false.
  165. /// 7. CEF sends an close notification to the application's top-level window.
  166. /// 8. Application's top-level window receives the close notification and
  167. /// allows the window to close based on the flag from #6B.
  168. /// 9. Application's top-level window is destroyed.
  169. /// 10. Application's OnBeforeClose() handler is called and the browser object
  170. /// is destroyed.
  171. /// 11. Application exits by calling CefQuitMessageLoop() if no other browsers
  172. /// exist.
  173. /// </summary>
  174. protected virtual bool DoClose(CefBrowser browser)
  175. {
  176. return false;
  177. }
  178. private void on_before_close(cef_life_span_handler_t* self, cef_browser_t* browser)
  179. {
  180. CheckSelf(self);
  181. var m_browser = CefBrowser.FromNative(browser);
  182. OnBeforeClose(m_browser);
  183. }
  184. /// <summary>
  185. /// Called just before a browser is destroyed. Release all references to the
  186. /// browser object and do not attempt to execute any methods on the browser
  187. /// object (other than GetIdentifier or IsSame) after this callback returns.
  188. /// This callback will be the last notification that references |browser| on
  189. /// the UI thread. Any in-progress network requests associated with |browser|
  190. /// will be aborted when the browser is destroyed, and
  191. /// CefResourceRequestHandler callbacks related to those requests may still
  192. /// arrive on the IO thread after this method is called. See DoClose()
  193. /// documentation for additional usage information.
  194. /// </summary>
  195. protected virtual void OnBeforeClose(CefBrowser browser)
  196. {
  197. }
  198. }
  199. }