From 0d9a15791403daef3eac1d9258d050b1db33f17c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 22 Feb 2018 14:52:04 +0900 Subject: [PATCH 01/15] Turn api::Window into a WebContentsObserver --- atom/browser/api/atom_api_browser_window.cc | 5 +++-- atom/browser/api/atom_api_browser_window.h | 8 ++++---- atom/browser/native_window.cc | 4 ++-- atom/browser/native_window_observer.h | 4 ++-- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/atom/browser/api/atom_api_browser_window.cc b/atom/browser/api/atom_api_browser_window.cc index c1fc97476de1..c9efa644879a 100644 --- a/atom/browser/api/atom_api_browser_window.cc +++ b/atom/browser/api/atom_api_browser_window.cc @@ -129,6 +129,7 @@ void BrowserWindow::Init(v8::Isolate* isolate, mate::Handle web_contents) { web_contents_.Reset(isolate, web_contents.ToV8()); api_web_contents_ = web_contents.get(); + Observe(web_contents->web_contents()); // Keep a copy of the options for later use. mate::Dictionary(isolate, web_contents->GetWrapper()).Set( @@ -303,11 +304,11 @@ void BrowserWindow::OnWindowLeaveHtmlFullScreen() { Emit("leave-html-full-screen"); } -void BrowserWindow::OnRendererUnresponsive() { +void BrowserWindow::OnWindowUnresponsive() { Emit("unresponsive"); } -void BrowserWindow::OnRendererResponsive() { +void BrowserWindow::OnWindowResponsive() { Emit("responsive"); } diff --git a/atom/browser/api/atom_api_browser_window.h b/atom/browser/api/atom_api_browser_window.h index 50d77a24928e..c1a91d51e8d6 100644 --- a/atom/browser/api/atom_api_browser_window.h +++ b/atom/browser/api/atom_api_browser_window.h @@ -15,6 +15,7 @@ #include "atom/browser/native_window_observer.h" #include "atom/common/api/atom_api_native_image.h" #include "atom/common/key_weak_map.h" +#include "content/public/browser/web_contents_observer.h" #include "native_mate/handle.h" #include "native_mate/persistent_dictionary.h" #include "ui/gfx/image/image.h" @@ -36,9 +37,8 @@ class NativeWindow; namespace api { -class WebContents; - class BrowserWindow : public mate::TrackableObject, + public content::WebContentsObserver, public NativeWindowObserver { public: static mate::WrappableBase* New(mate::Arguments* args); @@ -87,8 +87,8 @@ class BrowserWindow : public mate::TrackableObject, void OnWindowLeaveFullScreen() override; void OnWindowEnterHtmlFullScreen() override; void OnWindowLeaveHtmlFullScreen() override; - void OnRendererUnresponsive() override; - void OnRendererResponsive() override; + void OnWindowUnresponsive() override; + void OnWindowResponsive() override; void OnExecuteWindowsCommand(const std::string& command_name) override; void OnTouchBarItemResult(const std::string& item_id, const base::DictionaryValue& details) override; diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 34778fb64347..a34c4648da00 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -489,7 +489,7 @@ void NativeWindow::RendererUnresponsive(content::WebContents* source) { void NativeWindow::RendererResponsive(content::WebContents* source) { window_unresposive_closure_.Cancel(); for (NativeWindowObserver& observer : observers_) - observer.OnRendererResponsive(); + observer.OnWindowResponsive(); } void NativeWindow::NotifyWindowClosed() { @@ -727,7 +727,7 @@ void NativeWindow::NotifyWindowUnresponsive() { if (!is_closed_ && !IsUnresponsiveEventSuppressed() && IsEnabled()) { for (NativeWindowObserver& observer : observers_) - observer.OnRendererUnresponsive(); + observer.OnWindowUnresponsive(); } } diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index 9aad030aa324..f21fbcc570fc 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -86,10 +86,10 @@ class NativeWindowObserver { #endif // Called when renderer is hung. - virtual void OnRendererUnresponsive() {} + virtual void OnWindowUnresponsive() {} // Called when renderer recovers. - virtual void OnRendererResponsive() {} + virtual void OnWindowResponsive() {} // Called on Windows when App Commands arrive (WM_APPCOMMAND) virtual void OnExecuteWindowsCommand(const std::string& command_name) {} From c256a43139e6bb32b33f2115d5e2ef2c69671efb Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 22 Feb 2018 14:59:39 +0900 Subject: [PATCH 02/15] Move ready-to-show to api::BrowserWindow --- atom/browser/api/atom_api_browser_window.cc | 25 ++++++++++++++++----- atom/browser/api/atom_api_browser_window.h | 12 +++++++++- atom/browser/native_window.cc | 21 ----------------- atom/browser/native_window.h | 4 ---- atom/browser/native_window_observer.h | 3 --- 5 files changed, 31 insertions(+), 34 deletions(-) diff --git a/atom/browser/api/atom_api_browser_window.cc b/atom/browser/api/atom_api_browser_window.cc index c9efa644879a..fd980a57c22c 100644 --- a/atom/browser/api/atom_api_browser_window.cc +++ b/atom/browser/api/atom_api_browser_window.cc @@ -77,7 +77,8 @@ v8::Local ToBuffer(v8::Isolate* isolate, void* val, int size) { BrowserWindow::BrowserWindow(v8::Isolate* isolate, v8::Local wrapper, - const mate::Dictionary& options) { + const mate::Dictionary& options) + : weak_factory_(this) { mate::Handle web_contents; // Use options.webPreferences in WebContents. @@ -176,6 +177,24 @@ BrowserWindow::~BrowserWindow() { base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, window_.release()); } +void BrowserWindow::DidFirstVisuallyNonEmptyPaint() { + if (window_->IsVisible()) + return; + + // When there is a non-empty first paint, resize the RenderWidget to force + // Chromium to draw. + const auto view = web_contents()->GetRenderWidgetHostView(); + view->Show(); + view->SetSize(window_->GetContentSize()); + + // Emit the ReadyToShow event in next tick in case of pending drawing work. + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::Bind([](base::WeakPtr self) { + self->Emit("ready-to-show"); + }, GetWeakPtr())); +} + void BrowserWindow::WillCloseWindow(bool* prevent_default) { *prevent_default = Emit("close"); } @@ -232,10 +251,6 @@ void BrowserWindow::OnWindowHide() { Emit("hide"); } -void BrowserWindow::OnReadyToShow() { - Emit("ready-to-show"); -} - void BrowserWindow::OnWindowMaximize() { Emit("maximize"); } diff --git a/atom/browser/api/atom_api_browser_window.h b/atom/browser/api/atom_api_browser_window.h index c1a91d51e8d6..e0d0569ae34a 100644 --- a/atom/browser/api/atom_api_browser_window.h +++ b/atom/browser/api/atom_api_browser_window.h @@ -15,6 +15,7 @@ #include "atom/browser/native_window_observer.h" #include "atom/common/api/atom_api_native_image.h" #include "atom/common/key_weak_map.h" +#include "base/memory/weak_ptr.h" #include "content/public/browser/web_contents_observer.h" #include "native_mate/handle.h" #include "native_mate/persistent_dictionary.h" @@ -60,6 +61,9 @@ class BrowserWindow : public mate::TrackableObject, const mate::Dictionary& options); ~BrowserWindow() override; + // content::WebContentsObserver: + void DidFirstVisuallyNonEmptyPaint() override; + // NativeWindowObserver: void WillCloseWindow(bool* prevent_default) override; void WillDestroyNativeObject() override; @@ -69,7 +73,6 @@ class BrowserWindow : public mate::TrackableObject, void OnWindowFocus() override; void OnWindowShow() override; void OnWindowHide() override; - void OnReadyToShow() override; void OnWindowMaximize() override; void OnWindowUnmaximize() override; void OnWindowMinimize() override; @@ -98,11 +101,16 @@ class BrowserWindow : public mate::TrackableObject, void OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) override; #endif + base::WeakPtr GetWeakPtr() { + return weak_factory_.GetWeakPtr(); + } + private: void Init(v8::Isolate* isolate, v8::Local wrapper, const mate::Dictionary& options, mate::Handle web_contents); + // APIs for NativeWindow. void Close(); void Focus(); @@ -250,6 +258,8 @@ class BrowserWindow : public mate::TrackableObject, std::unique_ptr window_; + base::WeakPtrFactory weak_factory_; + DISALLOW_COPY_AND_ASSIGN(BrowserWindow); }; diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index a34c4648da00..3e488d9ecd12 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -672,22 +672,6 @@ void NativeWindow::BeforeUnloadDialogCancelled() { window_unresposive_closure_.Cancel(); } -void NativeWindow::DidFirstVisuallyNonEmptyPaint() { - if (IsVisible()) - return; - - // When there is a non-empty first paint, resize the RenderWidget to force - // Chromium to draw. - const auto view = web_contents()->GetRenderWidgetHostView(); - view->Show(); - view->SetSize(GetContentSize()); - - // Emit the ReadyToShow event in next tick in case of pending drawing work. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::Bind(&NativeWindow::NotifyReadyToShow, GetWeakPtr())); -} - bool NativeWindow::OnMessageReceived(const IPC::Message& message, content::RenderFrameHost* rfh) { bool handled = true; @@ -731,9 +715,4 @@ void NativeWindow::NotifyWindowUnresponsive() { } } -void NativeWindow::NotifyReadyToShow() { - for (NativeWindowObserver& observer : observers_) - observer.OnReadyToShow(); -} - } // namespace atom diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index d1cfa7cc3529..9c1ccb2f4252 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -320,7 +320,6 @@ class NativeWindow : public base::SupportsUserData, // content::WebContentsObserver: void RenderViewCreated(content::RenderViewHost* render_view_host) override; void BeforeUnloadDialogCancelled() override; - void DidFirstVisuallyNonEmptyPaint() override; bool OnMessageReceived(const IPC::Message& message, content::RenderFrameHost* rfh) override; @@ -331,9 +330,6 @@ class NativeWindow : public base::SupportsUserData, // Dispatch unresponsive event to observers. void NotifyWindowUnresponsive(); - // Dispatch ReadyToShow event to observers. - void NotifyReadyToShow(); - // Whether window has standard frame. bool has_frame_; diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index f21fbcc570fc..43eef69ed8c3 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -55,9 +55,6 @@ class NativeWindowObserver { // Called when window is hidden. virtual void OnWindowHide() {} - // Called when window is ready to show. - virtual void OnReadyToShow() {} - // Called when window state changed. virtual void OnWindowMaximize() {} virtual void OnWindowUnmaximize() {} From 6650a063393104531b271bc7326debf068d85481 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 22 Feb 2018 15:04:32 +0900 Subject: [PATCH 03/15] Move RenderViewCreated logic to api::BrowserWindow --- atom/browser/api/atom_api_browser_window.cc | 14 ++++++++++++++ atom/browser/api/atom_api_browser_window.h | 1 + atom/browser/native_window.cc | 13 ------------- atom/browser/native_window.h | 1 - 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/atom/browser/api/atom_api_browser_window.cc b/atom/browser/api/atom_api_browser_window.cc index fd980a57c22c..6d2de434a0f4 100644 --- a/atom/browser/api/atom_api_browser_window.cc +++ b/atom/browser/api/atom_api_browser_window.cc @@ -20,7 +20,9 @@ #include "atom/common/options_switches.h" #include "base/command_line.h" #include "base/threading/thread_task_runner_handle.h" +#include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/public/browser/render_process_host.h" +#include "content/public/browser/render_view_host.h" #include "content/public/common/content_switches.h" #include "native_mate/constructor.h" #include "native_mate/dictionary.h" @@ -177,6 +179,18 @@ BrowserWindow::~BrowserWindow() { base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, window_.release()); } +void BrowserWindow::RenderViewCreated( + content::RenderViewHost* render_view_host) { + if (!window_->transparent()) + return; + + content::RenderWidgetHostImpl* impl = content::RenderWidgetHostImpl::FromID( + render_view_host->GetProcess()->GetID(), + render_view_host->GetRoutingID()); + if (impl) + impl->SetBackgroundOpaque(false); +} + void BrowserWindow::DidFirstVisuallyNonEmptyPaint() { if (window_->IsVisible()) return; diff --git a/atom/browser/api/atom_api_browser_window.h b/atom/browser/api/atom_api_browser_window.h index e0d0569ae34a..deb7d738b211 100644 --- a/atom/browser/api/atom_api_browser_window.h +++ b/atom/browser/api/atom_api_browser_window.h @@ -62,6 +62,7 @@ class BrowserWindow : public mate::TrackableObject, ~BrowserWindow() override; // content::WebContentsObserver: + void RenderViewCreated(content::RenderViewHost* render_view_host) override; void DidFirstVisuallyNonEmptyPaint() override; // NativeWindowObserver: diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 3e488d9ecd12..89f443c7fc1a 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -24,7 +24,6 @@ #include "brightray/browser/inspectable_web_contents.h" #include "brightray/browser/inspectable_web_contents_view.h" #include "components/prefs/pref_service.h" -#include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/plugin_service.h" #include "content/public/browser/render_process_host.h" @@ -653,18 +652,6 @@ std::unique_ptr NativeWindow::DraggableRegionsToSkRegion( return sk_region; } -void NativeWindow::RenderViewCreated( - content::RenderViewHost* render_view_host) { - if (!transparent_) - return; - - content::RenderWidgetHostImpl* impl = content::RenderWidgetHostImpl::FromID( - render_view_host->GetProcess()->GetID(), - render_view_host->GetRoutingID()); - if (impl) - impl->SetBackgroundOpaque(false); -} - void NativeWindow::BeforeUnloadDialogCancelled() { WindowList::WindowCloseCancelled(this); diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 9c1ccb2f4252..3f91fefd100a 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -318,7 +318,6 @@ class NativeWindow : public base::SupportsUserData, const std::vector& regions); // content::WebContentsObserver: - void RenderViewCreated(content::RenderViewHost* render_view_host) override; void BeforeUnloadDialogCancelled() override; bool OnMessageReceived(const IPC::Message& message, content::RenderFrameHost* rfh) override; From 384b03d49b7735abcc744cf84e9f51fc412e82c3 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 22 Feb 2018 15:09:38 +0900 Subject: [PATCH 04/15] UpdateDraggableRegionViews is redundant --- atom/browser/native_window_mac.h | 27 ++--- atom/browser/native_window_mac.mm | 177 ++++++++++++++---------------- 2 files changed, 94 insertions(+), 110 deletions(-) diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 60d8fc23f59a..9a9b230f8772 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -119,6 +119,12 @@ class NativeWindowMac : public NativeWindow, void RefreshTouchBarItem(const std::string& item_id) override; void SetEscapeTouchBarItem(const mate::PersistentDictionary& item) override; + gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds) const; + gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds) const; + void UpdateDraggableRegions( + content::RenderFrameHost* rfh, + const std::vector& regions) override; + // content::RenderWidgetHost::InputEventObserver: void OnInputEvent(const blink::WebInputEvent& event) override; @@ -126,11 +132,6 @@ class NativeWindowMac : public NativeWindow, void RenderViewHostChanged(content::RenderViewHost* old_host, content::RenderViewHost* new_host) override; - // Refresh the DraggableRegion views. - void UpdateDraggableRegionViews() { - UpdateDraggableRegionViews(draggable_regions_); - } - // Set the attribute of NSWindow while work around a bug of zoom button. void SetStyleMask(bool on, NSUInteger flag); void SetCollectionBehavior(bool on, NSUInteger flag); @@ -144,10 +145,11 @@ class NativeWindowMac : public NativeWindow, TitleBarStyle title_bar_style() const { return title_bar_style_; } bool zoom_to_page_width() const { return zoom_to_page_width_; } - bool fullscreen_window_title() const { return fullscreen_window_title_; } - bool simple_fullscreen() const { return always_simple_fullscreen_; } + const std::vector& draggable_regions() const { + return draggable_regions_; + } protected: // Return a vector of non-draggable regions that fill a window of size @@ -156,23 +158,12 @@ class NativeWindowMac : public NativeWindow, const std::vector& regions, int width, int height); private: - // NativeWindow: - gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds) const; - gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds) const; - void UpdateDraggableRegions( - content::RenderFrameHost* rfh, - const std::vector& regions) override; - void InternalSetParentWindow(NativeWindow* parent, bool attach); void ShowWindowButton(NSWindowButton button); void InstallView(); void UninstallView(); - // Install the drag view, which will cover the whole window and decides - // whether we can drag. - void UpdateDraggableRegionViews(const std::vector& regions); - void RegisterInputEventObserver(content::RenderViewHost* host); void UnregisterInputEventObserver(content::RenderViewHost* host); diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index ad1713e40124..42d775cca896 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -296,7 +296,7 @@ bool ScopedDisableResize::disable_resize_ = false; } - (void)windowDidResize:(NSNotification*)notification { - shell_->UpdateDraggableRegionViews(); + shell_->UpdateDraggableRegions(nullptr, shell_->draggable_regions()); shell_->NotifyWindowResize(); } @@ -1789,6 +1789,90 @@ void NativeWindowMac::SetEscapeTouchBarItem(const mate::PersistentDictionary& it [window_ setEscapeTouchBarItem:item]; } +gfx::Rect NativeWindowMac::ContentBoundsToWindowBounds( + const gfx::Rect& bounds) const { + if (has_frame()) { + gfx::Rect window_bounds( + [window_ frameRectForContentRect:bounds.ToCGRect()]); + int frame_height = window_bounds.height() - bounds.height(); + window_bounds.set_y(window_bounds.y() - frame_height); + return window_bounds; + } else { + return bounds; + } +} + +gfx::Rect NativeWindowMac::WindowBoundsToContentBounds( + const gfx::Rect& bounds) const { + if (has_frame()) { + gfx::Rect content_bounds( + [window_ contentRectForFrameRect:bounds.ToCGRect()]); + int frame_height = bounds.height() - content_bounds.height(); + content_bounds.set_y(content_bounds.y() + frame_height); + return content_bounds; + } else { + return bounds; + } +} + +void NativeWindowMac::UpdateDraggableRegions( + content::RenderFrameHost* rfh, + const std::vector& regions) { + if (has_frame()) + return; + + // All ControlRegionViews should be added as children of the WebContentsView, + // because WebContentsView will be removed and re-added when entering and + // leaving fullscreen mode. + NSView* webView = web_contents()->GetNativeView(); + NSInteger webViewWidth = NSWidth([webView bounds]); + NSInteger webViewHeight = NSHeight([webView bounds]); + + if ([webView respondsToSelector:@selector(setMouseDownCanMoveWindow:)]) { + [webView setMouseDownCanMoveWindow:YES]; + } + + // Remove all ControlRegionViews that are added last time. + // Note that [webView subviews] returns the view's mutable internal array and + // it should be copied to avoid mutating the original array while enumerating + // it. + base::scoped_nsobject subviews([[webView subviews] copy]); + for (NSView* subview in subviews.get()) + if ([subview isKindOfClass:[ControlRegionView class]]) + [subview removeFromSuperview]; + + // Draggable regions is implemented by having the whole web view draggable + // (mouseDownCanMoveWindow) and overlaying regions that are not draggable. + draggable_regions_ = regions; + std::vector system_drag_exclude_areas = + CalculateNonDraggableRegions(regions, webViewWidth, webViewHeight); + + if (browser_view_) + browser_view_->UpdateDraggableRegions(system_drag_exclude_areas); + + // Create and add a ControlRegionView for each region that needs to be + // excluded from the dragging. + for (std::vector::const_iterator iter = + system_drag_exclude_areas.begin(); + iter != system_drag_exclude_areas.end(); + ++iter) { + base::scoped_nsobject controlRegion( + [[ControlRegionView alloc] initWithFrame:NSZeroRect]); + [controlRegion setFrame:NSMakeRect(iter->x(), + webViewHeight - iter->bottom(), + iter->width(), + iter->height())]; + [webView addSubview:controlRegion]; + } + + // AppKit will not update its cache of mouseDownCanMoveWindow unless something + // changes. Previously we tried adding an NSView and removing it, but for some + // reason it required reposting the mouse-down event, and didn't always work. + // Calling the below seems to be an effective solution. + [window_ setMovableByWindowBackground:NO]; + [window_ setMovableByWindowBackground:YES]; +} + void NativeWindowMac::OnInputEvent(const blink::WebInputEvent& event) { switch (event.GetType()) { case blink::WebInputEvent::kGestureScrollBegin: @@ -1825,40 +1909,6 @@ std::vector NativeWindowMac::CalculateNonDraggableRegions( return result; } -gfx::Rect NativeWindowMac::ContentBoundsToWindowBounds( - const gfx::Rect& bounds) const { - if (has_frame()) { - gfx::Rect window_bounds( - [window_ frameRectForContentRect:bounds.ToCGRect()]); - int frame_height = window_bounds.height() - bounds.height(); - window_bounds.set_y(window_bounds.y() - frame_height); - return window_bounds; - } else { - return bounds; - } -} - -gfx::Rect NativeWindowMac::WindowBoundsToContentBounds( - const gfx::Rect& bounds) const { - if (has_frame()) { - gfx::Rect content_bounds( - [window_ contentRectForFrameRect:bounds.ToCGRect()]); - int frame_height = bounds.height() - content_bounds.height(); - content_bounds.set_y(content_bounds.y() + frame_height); - return content_bounds; - } else { - return bounds; - } -} - -void NativeWindowMac::UpdateDraggableRegions( - content::RenderFrameHost* rfh, - const std::vector& regions) { - NativeWindow::UpdateDraggableRegions(rfh, regions); - draggable_regions_ = regions; - UpdateDraggableRegionViews(regions); -} - void NativeWindowMac::InternalSetParentWindow(NativeWindow* parent, bool attach) { if (is_modal()) return; @@ -1944,63 +1994,6 @@ void NativeWindowMac::UninstallView() { [view removeFromSuperview]; } -void NativeWindowMac::UpdateDraggableRegionViews( - const std::vector& regions) { - if (has_frame()) - return; - - // All ControlRegionViews should be added as children of the WebContentsView, - // because WebContentsView will be removed and re-added when entering and - // leaving fullscreen mode. - NSView* webView = web_contents()->GetNativeView(); - NSInteger webViewWidth = NSWidth([webView bounds]); - NSInteger webViewHeight = NSHeight([webView bounds]); - - if ([webView respondsToSelector:@selector(setMouseDownCanMoveWindow:)]) { - [webView setMouseDownCanMoveWindow:YES]; - } - - // Remove all ControlRegionViews that are added last time. - // Note that [webView subviews] returns the view's mutable internal array and - // it should be copied to avoid mutating the original array while enumerating - // it. - base::scoped_nsobject subviews([[webView subviews] copy]); - for (NSView* subview in subviews.get()) - if ([subview isKindOfClass:[ControlRegionView class]]) - [subview removeFromSuperview]; - - // Draggable regions is implemented by having the whole web view draggable - // (mouseDownCanMoveWindow) and overlaying regions that are not draggable. - std::vector system_drag_exclude_areas = - CalculateNonDraggableRegions(regions, webViewWidth, webViewHeight); - - if (browser_view_) { - browser_view_->UpdateDraggableRegions(system_drag_exclude_areas); - } - - // Create and add a ControlRegionView for each region that needs to be - // excluded from the dragging. - for (std::vector::const_iterator iter = - system_drag_exclude_areas.begin(); - iter != system_drag_exclude_areas.end(); - ++iter) { - base::scoped_nsobject controlRegion( - [[ControlRegionView alloc] initWithFrame:NSZeroRect]); - [controlRegion setFrame:NSMakeRect(iter->x(), - webViewHeight - iter->bottom(), - iter->width(), - iter->height())]; - [webView addSubview:controlRegion]; - } - - // AppKit will not update its cache of mouseDownCanMoveWindow unless something - // changes. Previously we tried adding an NSView and removing it, but for some - // reason it required reposting the mouse-down event, and didn't always work. - // Calling the below seems to be an effective solution. - [window_ setMovableByWindowBackground:NO]; - [window_ setMovableByWindowBackground:YES]; -} - void NativeWindowMac::SetStyleMask(bool on, NSUInteger flag) { // Changing the styleMask of a frameless windows causes it to change size so // we explicitly disable resizing while setting it. From c2aa312e0cbcaab72b3b2f4dbd6b487c23968aec Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 22 Feb 2018 15:10:33 +0900 Subject: [PATCH 05/15] Check weak ptr before using it --- atom/browser/api/atom_api_browser_window.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/atom/browser/api/atom_api_browser_window.cc b/atom/browser/api/atom_api_browser_window.cc index 6d2de434a0f4..7e67f3424ca2 100644 --- a/atom/browser/api/atom_api_browser_window.cc +++ b/atom/browser/api/atom_api_browser_window.cc @@ -205,7 +205,8 @@ void BrowserWindow::DidFirstVisuallyNonEmptyPaint() { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::Bind([](base::WeakPtr self) { - self->Emit("ready-to-show"); + if (self) + self->Emit("ready-to-show"); }, GetWeakPtr())); } From 44e7282b4b63ebdb0c0967159b7badefd5f65131 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 22 Feb 2018 15:16:24 +0900 Subject: [PATCH 06/15] The UpdateDraggableRegions does not share implementations --- atom/browser/native_window.cc | 9 --- atom/browser/native_window.h | 27 +++---- atom/browser/native_window_views.cc | 107 +++++++++++++++------------- atom/browser/native_window_views.h | 13 +++- 4 files changed, 80 insertions(+), 76 deletions(-) diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 89f443c7fc1a..59c2ef0addfb 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -671,15 +671,6 @@ bool NativeWindow::OnMessageReceived(const IPC::Message& message, return handled; } -void NativeWindow::UpdateDraggableRegions( - content::RenderFrameHost* rfh, - const std::vector& regions) { - // Draggable region is not supported for non-frameless window. - if (has_frame_) - return; - draggable_region_ = DraggableRegionsToSkRegion(regions); -} - void NativeWindow::ScheduleUnresponsiveEvent(int ms) { if (!window_unresposive_closure_.IsCancelled()) return; diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 3f91fefd100a..88a76c774aee 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -216,6 +216,17 @@ class NativeWindow : public base::SupportsUserData, const std::string& display_name); virtual void CloseFilePreview(); + // Converts between content bounds and window bounds. + virtual gfx::Rect ContentBoundsToWindowBounds( + const gfx::Rect& bounds) const = 0; + virtual gfx::Rect WindowBoundsToContentBounds( + const gfx::Rect& bounds) const = 0; + + // Called when the window needs to update its draggable region. + virtual void UpdateDraggableRegions( + content::RenderFrameHost* rfh, + const std::vector& regions) = 0; + base::WeakPtr GetWeakPtr() { return weak_factory_.GetWeakPtr(); } @@ -287,7 +298,6 @@ class NativeWindow : public base::SupportsUserData, void set_has_frame(bool has_frame) { has_frame_ = has_frame; } bool transparent() const { return transparent_; } - SkRegion* draggable_region() const { return draggable_region_.get(); } bool enable_larger_than_screen() const { return enable_larger_than_screen_; } void set_is_offscreen_dummy(bool is_dummy) { is_osr_dummy_ = is_dummy; } @@ -306,17 +316,6 @@ class NativeWindow : public base::SupportsUserData, std::unique_ptr DraggableRegionsToSkRegion( const std::vector& regions); - // Converts between content bounds and window bounds. - virtual gfx::Rect ContentBoundsToWindowBounds( - const gfx::Rect& bounds) const = 0; - virtual gfx::Rect WindowBoundsToContentBounds( - const gfx::Rect& bounds) const = 0; - - // Called when the window needs to update its draggable region. - virtual void UpdateDraggableRegions( - content::RenderFrameHost* rfh, - const std::vector& regions); - // content::WebContentsObserver: void BeforeUnloadDialogCancelled() override; bool OnMessageReceived(const IPC::Message& message, @@ -335,10 +334,6 @@ class NativeWindow : public base::SupportsUserData, // Whether window is transparent. bool transparent_; - // For custom drag, the whole window is non-draggable and the draggable region - // has to been explicitly provided. - std::unique_ptr draggable_region_; // used in custom drag. - // Minimum and maximum size, stored as content size. extensions::SizeConstraints size_constraints_; diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 008109970ec8..fa71d5a35aea 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -1072,6 +1072,64 @@ gfx::AcceleratedWidget NativeWindowViews::GetAcceleratedWidget() const { return GetNativeWindow()->GetHost()->GetAcceleratedWidget(); } +gfx::Rect NativeWindowViews::ContentBoundsToWindowBounds( + const gfx::Rect& bounds) const { + if (!has_frame()) + return bounds; + + gfx::Rect window_bounds(bounds); +#if defined(OS_WIN) + HWND hwnd = GetAcceleratedWidget(); + gfx::Rect dpi_bounds = display::win::ScreenWin::DIPToScreenRect(hwnd, bounds); + window_bounds = display::win::ScreenWin::ScreenToDIPRect( + hwnd, + window_->non_client_view()->GetWindowBoundsForClientBounds(dpi_bounds)); +#endif + + if (menu_bar_ && menu_bar_visible_) { + window_bounds.set_y(window_bounds.y() - kMenuBarHeight); + window_bounds.set_height(window_bounds.height() + kMenuBarHeight); + } + return window_bounds; +} + +gfx::Rect NativeWindowViews::WindowBoundsToContentBounds( + const gfx::Rect& bounds) const { + if (!has_frame()) + return bounds; + + gfx::Rect content_bounds(bounds); +#if defined(OS_WIN) + HWND hwnd = GetAcceleratedWidget(); + content_bounds.set_size( + display::win::ScreenWin::DIPToScreenSize(hwnd, content_bounds.size())); + RECT rect; + SetRectEmpty(&rect); + DWORD style = ::GetWindowLong(hwnd, GWL_STYLE); + DWORD ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE); + AdjustWindowRectEx(&rect, style, FALSE, ex_style); + content_bounds.set_width(content_bounds.width() - (rect.right - rect.left)); + content_bounds.set_height(content_bounds.height() - (rect.bottom - rect.top)); + content_bounds.set_size( + display::win::ScreenWin::ScreenToDIPSize(hwnd, content_bounds.size())); +#endif + + if (menu_bar_ && menu_bar_visible_) { + content_bounds.set_y(content_bounds.y() + kMenuBarHeight); + content_bounds.set_height(content_bounds.height() - kMenuBarHeight); + } + return content_bounds; +} + +void NativeWindowViews::UpdateDraggableRegions( + content::RenderFrameHost* rfh, + const std::vector& regions) { + // Draggable region is not supported for non-frameless window. + if (has_frame()) + return; + draggable_region_ = DraggableRegionsToSkRegion(regions); +} + #if defined(OS_WIN) void NativeWindowViews::SetIcon(HICON window_icon, HICON app_icon) { // We are responsible for storing the images. @@ -1270,55 +1328,6 @@ void NativeWindowViews::OnWidgetMove() { NotifyWindowMove(); } -gfx::Rect NativeWindowViews::ContentBoundsToWindowBounds( - const gfx::Rect& bounds) const { - if (!has_frame()) - return bounds; - - gfx::Rect window_bounds(bounds); -#if defined(OS_WIN) - HWND hwnd = GetAcceleratedWidget(); - gfx::Rect dpi_bounds = display::win::ScreenWin::DIPToScreenRect(hwnd, bounds); - window_bounds = display::win::ScreenWin::ScreenToDIPRect( - hwnd, - window_->non_client_view()->GetWindowBoundsForClientBounds(dpi_bounds)); -#endif - - if (menu_bar_ && menu_bar_visible_) { - window_bounds.set_y(window_bounds.y() - kMenuBarHeight); - window_bounds.set_height(window_bounds.height() + kMenuBarHeight); - } - return window_bounds; -} - -gfx::Rect NativeWindowViews::WindowBoundsToContentBounds( - const gfx::Rect& bounds) const { - if (!has_frame()) - return bounds; - - gfx::Rect content_bounds(bounds); -#if defined(OS_WIN) - HWND hwnd = GetAcceleratedWidget(); - content_bounds.set_size( - display::win::ScreenWin::DIPToScreenSize(hwnd, content_bounds.size())); - RECT rect; - SetRectEmpty(&rect); - DWORD style = ::GetWindowLong(hwnd, GWL_STYLE); - DWORD ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE); - AdjustWindowRectEx(&rect, style, FALSE, ex_style); - content_bounds.set_width(content_bounds.width() - (rect.right - rect.left)); - content_bounds.set_height(content_bounds.height() - (rect.bottom - rect.top)); - content_bounds.set_size( - display::win::ScreenWin::ScreenToDIPSize(hwnd, content_bounds.size())); -#endif - - if (menu_bar_ && menu_bar_visible_) { - content_bounds.set_y(content_bounds.y() + kMenuBarHeight); - content_bounds.set_height(content_bounds.height() - kMenuBarHeight); - } - return content_bounds; -} - void NativeWindowViews::HandleKeyboardEvent( content::WebContents*, const content::NativeWebKeyboardEvent& event) { diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 2d24b50deffb..7c81b7aa7462 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -126,6 +126,12 @@ class NativeWindowViews : public NativeWindow, gfx::AcceleratedWidget GetAcceleratedWidget() const override; + gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds) const override; + gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds) const override; + void UpdateDraggableRegions( + content::RenderFrameHost* rfh, + const std::vector& regions) override; + #if defined(OS_WIN) void SetIcon(HICON small_icon, HICON app_icon); #elif defined(USE_X11) @@ -135,6 +141,7 @@ class NativeWindowViews : public NativeWindow, void SetEnabled(bool enable) override; views::Widget* widget() const { return window_.get(); } + SkRegion* draggable_region() const { return draggable_region_.get(); } #if defined(OS_WIN) TaskbarHost& taskbar_host() { return taskbar_host_; } @@ -183,8 +190,6 @@ class NativeWindowViews : public NativeWindow, #endif // NativeWindow: - gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds) const override; - gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds) const override; void HandleKeyboardEvent( content::WebContents*, const content::NativeWebKeyboardEvent& event) override; @@ -289,6 +294,10 @@ class NativeWindowViews : public NativeWindow, // Map from accelerator to menu item's command id. accelerator_util::AcceleratorTable accelerator_table_; + // For custom drag, the whole window is non-draggable and the draggable region + // has to been explicitly provided. + std::unique_ptr draggable_region_; // used in custom drag. + // How many times the Disable has been called. int disable_count_; From bffb31c337028357b5e3986f17e059779ecbc7c9 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 22 Feb 2018 15:26:04 +0900 Subject: [PATCH 07/15] Remove OnMessageReceived from NativeWindow --- atom/browser/api/atom_api_browser_window.cc | 18 ++++++++++++++++++ atom/browser/api/atom_api_browser_window.h | 7 +++++++ atom/browser/native_window.cc | 14 +------------- atom/browser/native_window.h | 3 --- atom/browser/native_window_mac.h | 1 - atom/browser/native_window_mac.mm | 3 +-- atom/browser/native_window_views.cc | 1 - atom/browser/native_window_views.h | 1 - 8 files changed, 27 insertions(+), 21 deletions(-) diff --git a/atom/browser/api/atom_api_browser_window.cc b/atom/browser/api/atom_api_browser_window.cc index 7e67f3424ca2..d3c2559c8230 100644 --- a/atom/browser/api/atom_api_browser_window.cc +++ b/atom/browser/api/atom_api_browser_window.cc @@ -10,6 +10,7 @@ #include "atom/browser/browser.h" #include "atom/browser/native_window.h" #include "atom/browser/web_contents_preferences.h" +#include "atom/common/api/api_messages.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/native_mate_converters/gfx_converter.h" @@ -210,6 +211,17 @@ void BrowserWindow::DidFirstVisuallyNonEmptyPaint() { }, GetWeakPtr())); } +bool BrowserWindow::OnMessageReceived(const IPC::Message& message, + content::RenderFrameHost* rfh) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(BrowserWindow, message, rfh) + IPC_MESSAGE_HANDLER(AtomFrameHostMsg_UpdateDraggableRegions, + UpdateDraggableRegions) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + void BrowserWindow::WillCloseWindow(bool* prevent_default) { *prevent_default = Emit("close"); } @@ -1039,6 +1051,12 @@ void BrowserWindow::RemoveFromParentChildWindows() { parent->child_windows_.Remove(ID()); } +void BrowserWindow::UpdateDraggableRegions( + content::RenderFrameHost* rfh, + const std::vector& regions) { + window_->UpdateDraggableRegions(regions); +} + // static void BrowserWindow::BuildPrototype(v8::Isolate* isolate, v8::Local prototype) { diff --git a/atom/browser/api/atom_api_browser_window.h b/atom/browser/api/atom_api_browser_window.h index deb7d738b211..ba23277636b8 100644 --- a/atom/browser/api/atom_api_browser_window.h +++ b/atom/browser/api/atom_api_browser_window.h @@ -64,6 +64,8 @@ class BrowserWindow : public mate::TrackableObject, // content::WebContentsObserver: void RenderViewCreated(content::RenderViewHost* render_view_host) override; void DidFirstVisuallyNonEmptyPaint() override; + bool OnMessageReceived(const IPC::Message& message, + content::RenderFrameHost* rfh) override; // NativeWindowObserver: void WillCloseWindow(bool* prevent_default) override; @@ -244,6 +246,11 @@ class BrowserWindow : public mate::TrackableObject, // Remove this window from parent window's |child_windows_|. void RemoveFromParentChildWindows(); + // Called when the window needs to update its draggable region. + void UpdateDraggableRegions( + content::RenderFrameHost* rfh, + const std::vector& regions); + #if defined(OS_WIN) typedef std::map MessageCallbackMap; MessageCallbackMap messages_callback_map_; diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 59c2ef0addfb..90bf766777ba 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -13,7 +13,7 @@ #include "atom/browser/browser.h" #include "atom/browser/unresponsive_suppressor.h" #include "atom/browser/window_list.h" -#include "atom/common/api/api_messages.h" +#include "atom/common/draggable_region.h" #include "atom/common/native_mate_converters/file_path_converter.h" #include "atom/common/options_switches.h" #include "base/files/file_util.h" @@ -659,18 +659,6 @@ void NativeWindow::BeforeUnloadDialogCancelled() { window_unresposive_closure_.Cancel(); } -bool NativeWindow::OnMessageReceived(const IPC::Message& message, - content::RenderFrameHost* rfh) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(NativeWindow, message, rfh) - IPC_MESSAGE_HANDLER(AtomFrameHostMsg_UpdateDraggableRegions, - UpdateDraggableRegions) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - - return handled; -} - void NativeWindow::ScheduleUnresponsiveEvent(int ms) { if (!window_unresposive_closure_.IsCancelled()) return; diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 88a76c774aee..858b259b57ce 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -224,7 +224,6 @@ class NativeWindow : public base::SupportsUserData, // Called when the window needs to update its draggable region. virtual void UpdateDraggableRegions( - content::RenderFrameHost* rfh, const std::vector& regions) = 0; base::WeakPtr GetWeakPtr() { @@ -318,8 +317,6 @@ class NativeWindow : public base::SupportsUserData, // content::WebContentsObserver: void BeforeUnloadDialogCancelled() override; - bool OnMessageReceived(const IPC::Message& message, - content::RenderFrameHost* rfh) override; private: // Schedule a notification unresponsive event. diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 9a9b230f8772..64a816086b2c 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -122,7 +122,6 @@ class NativeWindowMac : public NativeWindow, gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds) const; gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds) const; void UpdateDraggableRegions( - content::RenderFrameHost* rfh, const std::vector& regions) override; // content::RenderWidgetHost::InputEventObserver: diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index 42d775cca896..bcafcbefe04f 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -296,7 +296,7 @@ bool ScopedDisableResize::disable_resize_ = false; } - (void)windowDidResize:(NSNotification*)notification { - shell_->UpdateDraggableRegions(nullptr, shell_->draggable_regions()); + shell_->UpdateDraggableRegions(shell_->draggable_regions()); shell_->NotifyWindowResize(); } @@ -1816,7 +1816,6 @@ gfx::Rect NativeWindowMac::WindowBoundsToContentBounds( } void NativeWindowMac::UpdateDraggableRegions( - content::RenderFrameHost* rfh, const std::vector& regions) { if (has_frame()) return; diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index fa71d5a35aea..11c5efc7575c 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -1122,7 +1122,6 @@ gfx::Rect NativeWindowViews::WindowBoundsToContentBounds( } void NativeWindowViews::UpdateDraggableRegions( - content::RenderFrameHost* rfh, const std::vector& regions) { // Draggable region is not supported for non-frameless window. if (has_frame()) diff --git a/atom/browser/native_window_views.h b/atom/browser/native_window_views.h index 7c81b7aa7462..73e91a92277a 100644 --- a/atom/browser/native_window_views.h +++ b/atom/browser/native_window_views.h @@ -129,7 +129,6 @@ class NativeWindowViews : public NativeWindow, gfx::Rect ContentBoundsToWindowBounds(const gfx::Rect& bounds) const override; gfx::Rect WindowBoundsToContentBounds(const gfx::Rect& bounds) const override; void UpdateDraggableRegions( - content::RenderFrameHost* rfh, const std::vector& regions) override; #if defined(OS_WIN) From a3124e887363d92f9c3a6c8f3438312f91ecb75e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 22 Feb 2018 15:48:53 +0900 Subject: [PATCH 08/15] Use observer to provide OnRendererUnresponsive --- atom/browser/api/atom_api_web_contents.cc | 2 -- atom/browser/api/atom_api_web_contents.h | 7 +++++++ atom/browser/native_window.cc | 22 +++++++++++----------- atom/browser/native_window.h | 2 +- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index f44bb96ad0c5..591418d6ce28 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -636,8 +636,6 @@ void WebContents::RendererUnresponsive( content::WebContents* source, const content::WebContentsUnresponsiveState& unresponsive_state) { Emit("unresponsive"); - if ((type_ == BROWSER_WINDOW || type_ == OFF_SCREEN) && owner_window()) - owner_window()->RendererUnresponsive(source); } void WebContents::RendererResponsive(content::WebContents* source) { diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 16f23210557c..620f1045bb09 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -49,6 +49,13 @@ class WebViewGuestDelegate; namespace api { +// Certain events are only in WebContentsDelegate, provide our own Observer to +// dispatch those events. +class ExtendedWebContentsObserver { + virtual void OnRendererResponsive() {} +}; + +// Wrapper around the content::WebContents. class WebContents : public mate::TrackableObject, public CommonWebContentsDelegate, public content::WebContentsObserver { diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 90bf766777ba..5407fd4f537b 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -474,17 +474,6 @@ void NativeWindow::CloseContents(content::WebContents* source) { window_unresposive_closure_.Cancel(); } -void NativeWindow::RendererUnresponsive(content::WebContents* source) { - // Schedule the unresponsive shortly later, since we may receive the - // responsive event soon. This could happen after the whole application had - // blocked for a while. - // Also notice that when closing this event would be ignored because we have - // explicitly started a close timeout counter. This is on purpose because we - // don't want the unresponsive event to be sent too early when user is closing - // the window. - ScheduleUnresponsiveEvent(50); -} - void NativeWindow::RendererResponsive(content::WebContents* source) { window_unresposive_closure_.Cancel(); for (NativeWindowObserver& observer : observers_) @@ -659,6 +648,17 @@ void NativeWindow::BeforeUnloadDialogCancelled() { window_unresposive_closure_.Cancel(); } +void NativeWindow::OnRendererUnresponsive(content::RenderWidgetHost*) { + // Schedule the unresponsive shortly later, since we may receive the + // responsive event soon. This could happen after the whole application had + // blocked for a while. + // Also notice that when closing this event would be ignored because we have + // explicitly started a close timeout counter. This is on purpose because we + // don't want the unresponsive event to be sent too early when user is closing + // the window. + ScheduleUnresponsiveEvent(50); +} + void NativeWindow::ScheduleUnresponsiveEvent(int ms) { if (!window_unresposive_closure_.IsCancelled()) return; diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 858b259b57ce..9ec55440aa78 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -235,7 +235,6 @@ class NativeWindow : public base::SupportsUserData, // Methods called by the WebContents. virtual void CloseContents(content::WebContents* source); - virtual void RendererUnresponsive(content::WebContents* source); virtual void RendererResponsive(content::WebContents* source); virtual void HandleKeyboardEvent( content::WebContents*, @@ -317,6 +316,7 @@ class NativeWindow : public base::SupportsUserData, // content::WebContentsObserver: void BeforeUnloadDialogCancelled() override; + void OnRendererUnresponsive(content::RenderWidgetHost*) override; private: // Schedule a notification unresponsive event. From a25b49a127d08849835b6781092843f2fc145d87 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 22 Feb 2018 15:57:03 +0900 Subject: [PATCH 09/15] Add ExtendedWebContentsObserver --- atom/browser/api/atom_api_browser_window.cc | 6 ++++++ atom/browser/api/atom_api_browser_window.h | 9 +++++---- atom/browser/api/atom_api_web_contents.cc | 2 ++ atom/browser/api/atom_api_web_contents.h | 12 ++++++++++++ 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/atom/browser/api/atom_api_browser_window.cc b/atom/browser/api/atom_api_browser_window.cc index d3c2559c8230..1d4c0de1cb7a 100644 --- a/atom/browser/api/atom_api_browser_window.cc +++ b/atom/browser/api/atom_api_browser_window.cc @@ -134,6 +134,7 @@ void BrowserWindow::Init(v8::Isolate* isolate, web_contents_.Reset(isolate, web_contents.ToV8()); api_web_contents_ = web_contents.get(); Observe(web_contents->web_contents()); + api_web_contents_->AddObserver(this); // Keep a copy of the options for later use. mate::Dictionary(isolate, web_contents->GetWrapper()).Set( @@ -175,6 +176,8 @@ BrowserWindow::~BrowserWindow() { if (!window_->IsClosed()) window_->CloseContents(nullptr); + api_web_contents_->RemoveObserver(this); + // Destroy the native window in next tick because the native code might be // iterating all windows. base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, window_.release()); @@ -222,6 +225,9 @@ bool BrowserWindow::OnMessageReceived(const IPC::Message& message, return handled; } +void BrowserWindow::OnRendererResponsive() { +} + void BrowserWindow::WillCloseWindow(bool* prevent_default) { *prevent_default = Emit("close"); } diff --git a/atom/browser/api/atom_api_browser_window.h b/atom/browser/api/atom_api_browser_window.h index ba23277636b8..bf9a4021bfaa 100644 --- a/atom/browser/api/atom_api_browser_window.h +++ b/atom/browser/api/atom_api_browser_window.h @@ -10,16 +10,13 @@ #include #include -#include "atom/browser/api/trackable_object.h" +#include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/native_window.h" #include "atom/browser/native_window_observer.h" #include "atom/common/api/atom_api_native_image.h" #include "atom/common/key_weak_map.h" #include "base/memory/weak_ptr.h" -#include "content/public/browser/web_contents_observer.h" -#include "native_mate/handle.h" #include "native_mate/persistent_dictionary.h" -#include "ui/gfx/image/image.h" class GURL; @@ -40,6 +37,7 @@ namespace api { class BrowserWindow : public mate::TrackableObject, public content::WebContentsObserver, + public ExtendedWebContentsObserver, public NativeWindowObserver { public: static mate::WrappableBase* New(mate::Arguments* args); @@ -67,6 +65,9 @@ class BrowserWindow : public mate::TrackableObject, bool OnMessageReceived(const IPC::Message& message, content::RenderFrameHost* rfh) override; + // ExtendedWebContentsObserver: + void OnRendererResponsive() override; + // NativeWindowObserver: void WillCloseWindow(bool* prevent_default) override; void WillDestroyNativeObject() override; diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 591418d6ce28..c4a4a611393b 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -642,6 +642,8 @@ void WebContents::RendererResponsive(content::WebContents* source) { Emit("responsive"); if ((type_ == BROWSER_WINDOW || type_ == OFF_SCREEN) && owner_window()) owner_window()->RendererResponsive(source); + for (ExtendedWebContentsObserver& observer : observers_) + observer.OnRendererResponsive(); } bool WebContents::HandleContextMenu(const content::ContextMenuParams& params) { diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index 620f1045bb09..dabb2dec71fc 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -13,6 +13,7 @@ #include "atom/browser/api/trackable_object.h" #include "atom/browser/common_web_contents_delegate.h" #include "atom/browser/ui/autofill_popup.h" +#include "base/observer_list.h" #include "content/common/cursors/webcursor.h" #include "content/public/browser/keyboard_event_processing_result.h" #include "content/public/browser/web_contents.h" @@ -52,6 +53,7 @@ namespace api { // Certain events are only in WebContentsDelegate, provide our own Observer to // dispatch those events. class ExtendedWebContentsObserver { + public: virtual void OnRendererResponsive() {} }; @@ -238,6 +240,13 @@ class WebContents : public mate::TrackableObject, WebContentsZoomController* GetZoomController() { return zoom_controller_; } + void AddObserver(ExtendedWebContentsObserver* obs) { + observers_.AddObserver(obs); + } + void RemoveObserver(ExtendedWebContentsObserver* obs) { + observers_.RemoveObserver(obs); + } + protected: WebContents(v8::Isolate* isolate, content::WebContents* web_contents, @@ -428,6 +437,9 @@ class WebContents : public mate::TrackableObject, // Whether to enable devtools. bool enable_devtools_; + // Observers of this WebContents. + base::ObserverList observers_; + DISALLOW_COPY_AND_ASSIGN(WebContents); }; From 66fab65a1a40c41f6d7b819df2a2d72c856d456f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 22 Feb 2018 16:15:21 +0900 Subject: [PATCH 10/15] Add NativeWindowObserver::OnCloseButtonClicked --- atom/browser/api/atom_api_browser_window.cc | 8 ++++++ atom/browser/api/atom_api_browser_window.h | 1 + atom/browser/native_window.cc | 27 +++++++++++++++------ atom/browser/native_window.h | 1 + atom/browser/native_window_mac.mm | 5 +--- atom/browser/native_window_observer.h | 3 +++ atom/browser/native_window_views.cc | 3 ++- 7 files changed, 35 insertions(+), 13 deletions(-) diff --git a/atom/browser/api/atom_api_browser_window.cc b/atom/browser/api/atom_api_browser_window.cc index 1d4c0de1cb7a..626bb632f07c 100644 --- a/atom/browser/api/atom_api_browser_window.cc +++ b/atom/browser/api/atom_api_browser_window.cc @@ -243,6 +243,14 @@ void BrowserWindow::WillDestroyNativeObject() { } } +void BrowserWindow::OnCloseButtonClicked(bool* prevent_default) { + // When user tries to close the window by clicking the close button, we do + // not close the window immediately, instead we try to close the web page + // first, and when the web page is closed the window will also be closed. + *prevent_default = true; + window_->RequestToClosePage(); +} + void BrowserWindow::OnWindowClosed() { api_web_contents_->DestroyWebContents(true /* async */); diff --git a/atom/browser/api/atom_api_browser_window.h b/atom/browser/api/atom_api_browser_window.h index bf9a4021bfaa..4f75546e8260 100644 --- a/atom/browser/api/atom_api_browser_window.h +++ b/atom/browser/api/atom_api_browser_window.h @@ -71,6 +71,7 @@ class BrowserWindow : public mate::TrackableObject, // NativeWindowObserver: void WillCloseWindow(bool* prevent_default) override; void WillDestroyNativeObject() override; + void OnCloseButtonClicked(bool* prevent_default) override; void OnWindowClosed() override; void OnWindowEndSession() override; void OnWindowBlur() override; diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 5407fd4f537b..899716181503 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -427,14 +427,6 @@ void NativeWindow::CloseFilePreview() { } void NativeWindow::RequestToClosePage() { - bool prevent_default = false; - for (NativeWindowObserver& observer : observers_) - observer.WillCloseWindow(&prevent_default); - if (prevent_default) { - WindowList::WindowCloseCancelled(this); - return; - } - // Assume the window is not responding if it doesn't cancel the close and is // not closed in 5s, in this way we can quickly show the unresponsive // dialog when the window is busy executing some script withouth waiting for @@ -480,6 +472,25 @@ void NativeWindow::RendererResponsive(content::WebContents* source) { observer.OnWindowResponsive(); } +void NativeWindow::NotifyWindowCloseButtonClicked() { + // First ask the observers whether we want to close. + bool prevent_default = false; + for (NativeWindowObserver& observer : observers_) + observer.WillCloseWindow(&prevent_default); + if (prevent_default) { + WindowList::WindowCloseCancelled(this); + return; + } + + // Then ask the observers how should we close the window. + for (NativeWindowObserver& observer : observers_) + observer.OnCloseButtonClicked(&prevent_default); + if (prevent_default) + return; + + CloseImmediately(); +} + void NativeWindow::NotifyWindowClosed() { if (is_closed_) return; diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 9ec55440aa78..8f667647446b 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -249,6 +249,7 @@ class NativeWindow : public base::SupportsUserData, // Public API used by platform-dependent delegates and observers to send UI // related notifications. + void NotifyWindowCloseButtonClicked(); void NotifyWindowClosed(); void NotifyWindowEndSession(); void NotifyWindowBlur(); diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index bcafcbefe04f..ed51d7219edb 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -415,10 +415,7 @@ bool ScopedDisableResize::disable_resize_ = false; } - (BOOL)windowShouldClose:(id)window { - // When user tries to close the window by clicking the close button, we do - // not close the window immediately, instead we try to close the web page - // first, and when the web page is closed the window will also be closed. - shell_->RequestToClosePage(); + shell_->NotifyWindowCloseButtonClicked(); return NO; } diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index 43eef69ed8c3..c57c819b8693 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -37,6 +37,9 @@ class NativeWindowObserver { // Called before the native window object is going to be destroyed. virtual void WillDestroyNativeObject() {} + // Called when closed button is clicked. + virtual void OnCloseButtonClicked(bool* prevent_default) {} + // Called when the window is closed. virtual void OnWindowClosed() {} diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 11c5efc7575c..895f1b07f79a 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -124,7 +124,8 @@ class NativeWindowClientView : public views::ClientView { virtual ~NativeWindowClientView() {} bool CanClose() override { - static_cast(contents_view())->RequestToClosePage(); + static_cast(contents_view())-> + NotifyWindowCloseButtonClicked(); return false; } From aa3eafcea1118a8382ed18b0f4d1c6c771ed2a86 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 22 Feb 2018 16:52:08 +0900 Subject: [PATCH 11/15] Move closing logic to api::BrowserWindow Closing a BrowserWindow is essentially closing a WebContents, the logic should not be in NativeWindow. --- atom/browser/api/atom_api_browser_window.cc | 96 +++++++++++++++++---- atom/browser/api/atom_api_browser_window.h | 17 +++- atom/browser/api/atom_api_web_contents.cc | 14 +-- atom/browser/api/atom_api_web_contents.h | 1 + atom/browser/native_window.cc | 87 ------------------- atom/browser/native_window.h | 20 ----- atom/browser/native_window_observer.h | 9 -- atom/browser/window_list.cc | 2 +- 8 files changed, 103 insertions(+), 143 deletions(-) diff --git a/atom/browser/api/atom_api_browser_window.cc b/atom/browser/api/atom_api_browser_window.cc index 626bb632f07c..caaaf8bfe156 100644 --- a/atom/browser/api/atom_api_browser_window.cc +++ b/atom/browser/api/atom_api_browser_window.cc @@ -9,7 +9,9 @@ #include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/browser.h" #include "atom/browser/native_window.h" +#include "atom/browser/unresponsive_suppressor.h" #include "atom/browser/web_contents_preferences.h" +#include "atom/browser/window_list.h" #include "atom/common/api/api_messages.h" #include "atom/common/native_mate_converters/callback.h" #include "atom/common/native_mate_converters/file_path_converter.h" @@ -174,7 +176,7 @@ void BrowserWindow::Init(v8::Isolate* isolate, BrowserWindow::~BrowserWindow() { if (!window_->IsClosed()) - window_->CloseContents(nullptr); + window_->CloseImmediately(); api_web_contents_->RemoveObserver(this); @@ -214,6 +216,23 @@ void BrowserWindow::DidFirstVisuallyNonEmptyPaint() { }, GetWeakPtr())); } +void BrowserWindow::BeforeUnloadDialogCancelled() { + WindowList::WindowCloseCancelled(window_.get()); + // Cancel unresponsive event when window close is cancelled. + window_unresposive_closure_.Cancel(); +} + +void BrowserWindow::OnRendererUnresponsive(content::RenderWidgetHost*) { + // Schedule the unresponsive shortly later, since we may receive the + // responsive event soon. This could happen after the whole application had + // blocked for a while. + // Also notice that when closing this event would be ignored because we have + // explicitly started a close timeout counter. This is on purpose because we + // don't want the unresponsive event to be sent too early when user is closing + // the window. + ScheduleUnresponsiveEvent(50); +} + bool BrowserWindow::OnMessageReceived(const IPC::Message& message, content::RenderFrameHost* rfh) { bool handled = true; @@ -225,14 +244,11 @@ bool BrowserWindow::OnMessageReceived(const IPC::Message& message, return handled; } -void BrowserWindow::OnRendererResponsive() { -} +void BrowserWindow::OnCloseContents() { + if (!web_contents()) + return; + Observe(nullptr); -void BrowserWindow::WillCloseWindow(bool* prevent_default) { - *prevent_default = Emit("close"); -} - -void BrowserWindow::WillDestroyNativeObject() { // Close all child windows before closing current window. v8::Locker locker(isolate()); v8::HandleScope handle_scope(isolate()); @@ -241,6 +257,25 @@ void BrowserWindow::WillDestroyNativeObject() { if (mate::ConvertFromV8(isolate(), value, &child) && !child.IsEmpty()) child->window_->CloseImmediately(); } + + // When the web contents is gone, close the window immediately, but the + // memory will not be freed until you call delete. + // In this way, it would be safe to manage windows via smart pointers. If you + // want to free memory when the window is closed, you can do deleting by + // overriding the OnWindowClosed method in the observer. + window_->CloseImmediately(); + + // Do not sent "unresponsive" event after window is closed. + window_unresposive_closure_.Cancel(); +} + +void BrowserWindow::OnRendererResponsive() { + window_unresposive_closure_.Cancel(); + Emit("responsive"); +} + +void BrowserWindow::WillCloseWindow(bool* prevent_default) { + *prevent_default = Emit("close"); } void BrowserWindow::OnCloseButtonClicked(bool* prevent_default) { @@ -248,7 +283,22 @@ void BrowserWindow::OnCloseButtonClicked(bool* prevent_default) { // not close the window immediately, instead we try to close the web page // first, and when the web page is closed the window will also be closed. *prevent_default = true; - window_->RequestToClosePage(); + + // Assume the window is not responding if it doesn't cancel the close and is + // not closed in 5s, in this way we can quickly show the unresponsive + // dialog when the window is busy executing some script withouth waiting for + // the unresponsive timeout. + if (window_unresposive_closure_.IsCancelled()) + ScheduleUnresponsiveEvent(5000); + + if (!web_contents()) + // Already closed by renderer + return; + + if (web_contents()->NeedToFireBeforeUnload()) + web_contents()->DispatchBeforeUnload(); + else + web_contents()->Close(); } void BrowserWindow::OnWindowClosed() { @@ -360,14 +410,6 @@ void BrowserWindow::OnWindowLeaveHtmlFullScreen() { Emit("leave-html-full-screen"); } -void BrowserWindow::OnWindowUnresponsive() { - Emit("unresponsive"); -} - -void BrowserWindow::OnWindowResponsive() { - Emit("responsive"); -} - void BrowserWindow::OnExecuteWindowsCommand(const std::string& command_name) { Emit("app-command", command_name); } @@ -1071,6 +1113,26 @@ void BrowserWindow::UpdateDraggableRegions( window_->UpdateDraggableRegions(regions); } +void BrowserWindow::ScheduleUnresponsiveEvent(int ms) { + if (!window_unresposive_closure_.IsCancelled()) + return; + + window_unresposive_closure_.Reset( + base::Bind(&BrowserWindow::NotifyWindowUnresponsive, GetWeakPtr())); + base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( + FROM_HERE, + window_unresposive_closure_.callback(), + base::TimeDelta::FromMilliseconds(ms)); +} + +void BrowserWindow::NotifyWindowUnresponsive() { + window_unresposive_closure_.Cancel(); + if (!window_->IsClosed() && window_->IsEnabled() && + !IsUnresponsiveEventSuppressed()) { + Emit("unresponsive"); + } +} + // static void BrowserWindow::BuildPrototype(v8::Isolate* isolate, v8::Local prototype) { diff --git a/atom/browser/api/atom_api_browser_window.h b/atom/browser/api/atom_api_browser_window.h index 4f75546e8260..6c4335079ca6 100644 --- a/atom/browser/api/atom_api_browser_window.h +++ b/atom/browser/api/atom_api_browser_window.h @@ -15,6 +15,7 @@ #include "atom/browser/native_window_observer.h" #include "atom/common/api/atom_api_native_image.h" #include "atom/common/key_weak_map.h" +#include "base/cancelable_callback.h" #include "base/memory/weak_ptr.h" #include "native_mate/persistent_dictionary.h" @@ -62,15 +63,17 @@ class BrowserWindow : public mate::TrackableObject, // content::WebContentsObserver: void RenderViewCreated(content::RenderViewHost* render_view_host) override; void DidFirstVisuallyNonEmptyPaint() override; + void BeforeUnloadDialogCancelled() override; + void OnRendererUnresponsive(content::RenderWidgetHost*) override; bool OnMessageReceived(const IPC::Message& message, content::RenderFrameHost* rfh) override; // ExtendedWebContentsObserver: + void OnCloseContents() override; void OnRendererResponsive() override; // NativeWindowObserver: void WillCloseWindow(bool* prevent_default) override; - void WillDestroyNativeObject() override; void OnCloseButtonClicked(bool* prevent_default) override; void OnWindowClosed() override; void OnWindowEndSession() override; @@ -95,8 +98,6 @@ class BrowserWindow : public mate::TrackableObject, void OnWindowLeaveFullScreen() override; void OnWindowEnterHtmlFullScreen() override; void OnWindowLeaveHtmlFullScreen() override; - void OnWindowUnresponsive() override; - void OnWindowResponsive() override; void OnExecuteWindowsCommand(const std::string& command_name) override; void OnTouchBarItemResult(const std::string& item_id, const base::DictionaryValue& details) override; @@ -253,11 +254,21 @@ class BrowserWindow : public mate::TrackableObject, content::RenderFrameHost* rfh, const std::vector& regions); + // Schedule a notification unresponsive event. + void ScheduleUnresponsiveEvent(int ms); + + // Dispatch unresponsive event to observers. + void NotifyWindowUnresponsive(); + #if defined(OS_WIN) typedef std::map MessageCallbackMap; MessageCallbackMap messages_callback_map_; #endif + // Closure that would be called when window is unresponsive when closing, + // it should be cancelled when we can prove that the window is responsive. + base::CancelableClosure window_unresposive_closure_; + v8::Global browser_view_; v8::Global web_contents_; v8::Global menu_; diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index c4a4a611393b..127a05ab9149 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -446,6 +446,8 @@ void WebContents::InitWithSessionAndOptions(v8::Isolate* isolate, WebContents::~WebContents() { // The destroy() is called. if (managed_web_contents()) { + managed_web_contents()->GetView()->SetDelegate(nullptr); + // For webview we need to tell content module to do some cleanup work before // destroying it. if (type_ == WEB_VIEW) @@ -457,7 +459,8 @@ WebContents::~WebContents() { DestroyWebContents(false /* async */); } else { if (type_ == BROWSER_WINDOW && owner_window()) { - owner_window()->CloseContents(nullptr); + for (ExtendedWebContentsObserver& observer : observers_) + observer.OnCloseContents(); } else { DestroyWebContents(true /* async */); } @@ -565,9 +568,10 @@ void WebContents::MoveContents(content::WebContents* source, void WebContents::CloseContents(content::WebContents* source) { Emit("close"); - - if ((type_ == BROWSER_WINDOW || type_ == OFF_SCREEN) && owner_window()) - owner_window()->CloseContents(source); + if (managed_web_contents()) + managed_web_contents()->GetView()->SetDelegate(nullptr); + for (ExtendedWebContentsObserver& observer : observers_) + observer.OnCloseContents(); } void WebContents::ActivateContents(content::WebContents* source) { @@ -640,8 +644,6 @@ void WebContents::RendererUnresponsive( void WebContents::RendererResponsive(content::WebContents* source) { Emit("responsive"); - if ((type_ == BROWSER_WINDOW || type_ == OFF_SCREEN) && owner_window()) - owner_window()->RendererResponsive(source); for (ExtendedWebContentsObserver& observer : observers_) observer.OnRendererResponsive(); } diff --git a/atom/browser/api/atom_api_web_contents.h b/atom/browser/api/atom_api_web_contents.h index dabb2dec71fc..5d0f9ea3df06 100644 --- a/atom/browser/api/atom_api_web_contents.h +++ b/atom/browser/api/atom_api_web_contents.h @@ -54,6 +54,7 @@ namespace api { // dispatch those events. class ExtendedWebContentsObserver { public: + virtual void OnCloseContents() {} virtual void OnRendererResponsive() {} }; diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 899716181503..157a5bdd9702 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -11,7 +11,6 @@ #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_main_parts.h" #include "atom/browser/browser.h" -#include "atom/browser/unresponsive_suppressor.h" #include "atom/browser/window_list.h" #include "atom/common/draggable_region.h" #include "atom/common/native_mate_converters/file_path_converter.h" @@ -426,52 +425,6 @@ void NativeWindow::PreviewFile(const std::string& path, void NativeWindow::CloseFilePreview() { } -void NativeWindow::RequestToClosePage() { - // Assume the window is not responding if it doesn't cancel the close and is - // not closed in 5s, in this way we can quickly show the unresponsive - // dialog when the window is busy executing some script withouth waiting for - // the unresponsive timeout. - if (window_unresposive_closure_.IsCancelled()) - ScheduleUnresponsiveEvent(5000); - - if (!web_contents()) - // Already closed by renderer - return; - - if (web_contents()->NeedToFireBeforeUnload()) - web_contents()->DispatchBeforeUnload(); - else - web_contents()->Close(); -} - -void NativeWindow::CloseContents(content::WebContents* source) { - if (!inspectable_web_contents_) - return; - - inspectable_web_contents_->GetView()->SetDelegate(nullptr); - inspectable_web_contents_ = nullptr; - Observe(nullptr); - - for (NativeWindowObserver& observer : observers_) - observer.WillDestroyNativeObject(); - - // When the web contents is gone, close the window immediately, but the - // memory will not be freed until you call delete. - // In this way, it would be safe to manage windows via smart pointers. If you - // want to free memory when the window is closed, you can do deleting by - // overriding the OnWindowClosed method in the observer. - CloseImmediately(); - - // Do not sent "unresponsive" event after window is closed. - window_unresposive_closure_.Cancel(); -} - -void NativeWindow::RendererResponsive(content::WebContents* source) { - window_unresposive_closure_.Cancel(); - for (NativeWindowObserver& observer : observers_) - observer.OnWindowResponsive(); -} - void NativeWindow::NotifyWindowCloseButtonClicked() { // First ask the observers whether we want to close. bool prevent_default = false; @@ -652,44 +605,4 @@ std::unique_ptr NativeWindow::DraggableRegionsToSkRegion( return sk_region; } -void NativeWindow::BeforeUnloadDialogCancelled() { - WindowList::WindowCloseCancelled(this); - - // Cancel unresponsive event when window close is cancelled. - window_unresposive_closure_.Cancel(); -} - -void NativeWindow::OnRendererUnresponsive(content::RenderWidgetHost*) { - // Schedule the unresponsive shortly later, since we may receive the - // responsive event soon. This could happen after the whole application had - // blocked for a while. - // Also notice that when closing this event would be ignored because we have - // explicitly started a close timeout counter. This is on purpose because we - // don't want the unresponsive event to be sent too early when user is closing - // the window. - ScheduleUnresponsiveEvent(50); -} - -void NativeWindow::ScheduleUnresponsiveEvent(int ms) { - if (!window_unresposive_closure_.IsCancelled()) - return; - - window_unresposive_closure_.Reset( - base::Bind(&NativeWindow::NotifyWindowUnresponsive, - weak_factory_.GetWeakPtr())); - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, - window_unresposive_closure_.callback(), - base::TimeDelta::FromMilliseconds(ms)); -} - -void NativeWindow::NotifyWindowUnresponsive() { - window_unresposive_closure_.Cancel(); - - if (!is_closed_ && !IsUnresponsiveEventSuppressed() && IsEnabled()) { - for (NativeWindowObserver& observer : observers_) - observer.OnWindowUnresponsive(); - } -} - } // namespace atom diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 8f667647446b..5a34e7dd9b86 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -13,7 +13,6 @@ #include "atom/browser/native_window_observer.h" #include "atom/browser/ui/accelerator_util.h" #include "atom/browser/ui/atom_menu_model.h" -#include "base/cancelable_callback.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/supports_user_data.h" @@ -230,12 +229,7 @@ class NativeWindow : public base::SupportsUserData, return weak_factory_.GetWeakPtr(); } - // Requests the WebContents to close, can be cancelled by the page. - virtual void RequestToClosePage(); - // Methods called by the WebContents. - virtual void CloseContents(content::WebContents* source); - virtual void RendererResponsive(content::WebContents* source); virtual void HandleKeyboardEvent( content::WebContents*, const content::NativeWebKeyboardEvent& event) {} @@ -315,17 +309,7 @@ class NativeWindow : public base::SupportsUserData, std::unique_ptr DraggableRegionsToSkRegion( const std::vector& regions); - // content::WebContentsObserver: - void BeforeUnloadDialogCancelled() override; - void OnRendererUnresponsive(content::RenderWidgetHost*) override; - private: - // Schedule a notification unresponsive event. - void ScheduleUnresponsiveEvent(int ms); - - // Dispatch unresponsive event to observers. - void NotifyWindowUnresponsive(); - // Whether window has standard frame. bool has_frame_; @@ -341,10 +325,6 @@ class NativeWindow : public base::SupportsUserData, // The windows has been closed. bool is_closed_; - // Closure that would be called when window is unresponsive when closing, - // it should be cancelled when we can prove that the window is responsive. - base::CancelableClosure window_unresposive_closure_; - // Used to display sheets at the appropriate horizontal and vertical offsets // on macOS. double sheet_offset_x_; diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index c57c819b8693..d3c34cbe2212 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -34,9 +34,6 @@ class NativeWindowObserver { // Called when the window is gonna closed. virtual void WillCloseWindow(bool* prevent_default) {} - // Called before the native window object is going to be destroyed. - virtual void WillDestroyNativeObject() {} - // Called when closed button is clicked. virtual void OnCloseButtonClicked(bool* prevent_default) {} @@ -85,12 +82,6 @@ class NativeWindowObserver { virtual void OnWindowMessage(UINT message, WPARAM w_param, LPARAM l_param) {} #endif - // Called when renderer is hung. - virtual void OnWindowUnresponsive() {} - - // Called when renderer recovers. - virtual void OnWindowResponsive() {} - // Called on Windows when App Commands arrive (WM_APPCOMMAND) virtual void OnExecuteWindowsCommand(const std::string& command_name) {} }; diff --git a/atom/browser/window_list.cc b/atom/browser/window_list.cc index 2ab0b24cf50b..baef11f65611 100644 --- a/atom/browser/window_list.cc +++ b/atom/browser/window_list.cc @@ -93,7 +93,7 @@ void WindowList::CloseAllWindows() { void WindowList::DestroyAllWindows() { WindowVector windows = GetInstance()->windows_; for (const auto& window : windows) - window->CloseContents(nullptr); // e.g. Destroy() + window->CloseImmediately(); // e.g. Destroy() } WindowList::WindowList() { From c611eb061db4dadaac8d9e68a207ed0bf08d2524 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 22 Feb 2018 17:07:08 +0900 Subject: [PATCH 12/15] Move InputEventObserver to api::BrowserWindow --- atom/browser/api/atom_api_browser_window.cc | 28 ++++++++++++++--- atom/browser/api/atom_api_browser_window.h | 8 ++++- atom/browser/native_window.cc | 5 --- atom/browser/native_window.h | 1 - atom/browser/native_window_mac.h | 14 +-------- atom/browser/native_window_mac.mm | 34 --------------------- atom/browser/native_window_observer.h | 1 - 7 files changed, 32 insertions(+), 59 deletions(-) diff --git a/atom/browser/api/atom_api_browser_window.cc b/atom/browser/api/atom_api_browser_window.cc index caaaf8bfe156..0554a9b97aa6 100644 --- a/atom/browser/api/atom_api_browser_window.cc +++ b/atom/browser/api/atom_api_browser_window.cc @@ -172,6 +172,10 @@ void BrowserWindow::Init(v8::Isolate* isolate, // window's JS wrapper gets initialized. if (!parent.IsEmpty()) parent->child_windows_.Set(isolate, ID(), wrapper); + + auto* host = web_contents->web_contents()->GetRenderViewHost(); + if (host) + host->GetWidget()->AddInputEventObserver(this); } BrowserWindow::~BrowserWindow() { @@ -185,6 +189,26 @@ BrowserWindow::~BrowserWindow() { base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, window_.release()); } +void BrowserWindow::OnInputEvent(const blink::WebInputEvent& event) { + switch (event.GetType()) { + case blink::WebInputEvent::kGestureScrollBegin: + case blink::WebInputEvent::kGestureScrollUpdate: + case blink::WebInputEvent::kGestureScrollEnd: + Emit("scroll-touch-edge"); + break; + default: + break; + } +} + +void BrowserWindow::RenderViewHostChanged(content::RenderViewHost* old_host, + content::RenderViewHost* new_host) { + if (old_host) + old_host->GetWidget()->RemoveInputEventObserver(this); + if (new_host) + new_host->GetWidget()->AddInputEventObserver(this); +} + void BrowserWindow::RenderViewCreated( content::RenderViewHost* render_view_host) { if (!window_->transparent()) @@ -386,10 +410,6 @@ void BrowserWindow::OnWindowScrollTouchEnd() { Emit("scroll-touch-end"); } -void BrowserWindow::OnWindowScrollTouchEdge() { - Emit("scroll-touch-edge"); -} - void BrowserWindow::OnWindowSwipe(const std::string& direction) { Emit("swipe", direction); } diff --git a/atom/browser/api/atom_api_browser_window.h b/atom/browser/api/atom_api_browser_window.h index 6c4335079ca6..f5ba1c587c28 100644 --- a/atom/browser/api/atom_api_browser_window.h +++ b/atom/browser/api/atom_api_browser_window.h @@ -17,6 +17,7 @@ #include "atom/common/key_weak_map.h" #include "base/cancelable_callback.h" #include "base/memory/weak_ptr.h" +#include "content/public/browser/render_widget_host.h" #include "native_mate/persistent_dictionary.h" class GURL; @@ -37,6 +38,7 @@ class NativeWindow; namespace api { class BrowserWindow : public mate::TrackableObject, + public content::RenderWidgetHost::InputEventObserver, public content::WebContentsObserver, public ExtendedWebContentsObserver, public NativeWindowObserver { @@ -60,7 +62,12 @@ class BrowserWindow : public mate::TrackableObject, const mate::Dictionary& options); ~BrowserWindow() override; + // content::RenderWidgetHost::InputEventObserver: + void OnInputEvent(const blink::WebInputEvent& event) override; + // content::WebContentsObserver: + void RenderViewHostChanged(content::RenderViewHost* old_host, + content::RenderViewHost* new_host) override; void RenderViewCreated(content::RenderViewHost* render_view_host) override; void DidFirstVisuallyNonEmptyPaint() override; void BeforeUnloadDialogCancelled() override; @@ -90,7 +97,6 @@ class BrowserWindow : public mate::TrackableObject, void OnWindowMoved() override; void OnWindowScrollTouchBegin() override; void OnWindowScrollTouchEnd() override; - void OnWindowScrollTouchEdge() override; void OnWindowSwipe(const std::string& direction) override; void OnWindowSheetBegin() override; void OnWindowSheetEnd() override; diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index 157a5bdd9702..ea11b91ee69d 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -530,11 +530,6 @@ void NativeWindow::NotifyWindowScrollTouchEnd() { observer.OnWindowScrollTouchEnd(); } -void NativeWindow::NotifyWindowScrollTouchEdge() { - for (NativeWindowObserver& observer : observers_) - observer.OnWindowScrollTouchEdge(); -} - void NativeWindow::NotifyWindowSwipe(const std::string& direction) { for (NativeWindowObserver& observer : observers_) observer.OnWindowSwipe(direction); diff --git a/atom/browser/native_window.h b/atom/browser/native_window.h index 5a34e7dd9b86..5661f6237d17 100644 --- a/atom/browser/native_window.h +++ b/atom/browser/native_window.h @@ -259,7 +259,6 @@ class NativeWindow : public base::SupportsUserData, void NotifyWindowMoved(); void NotifyWindowScrollTouchBegin(); void NotifyWindowScrollTouchEnd(); - void NotifyWindowScrollTouchEdge(); void NotifyWindowSwipe(const std::string& direction); void NotifyWindowSheetBegin(); void NotifyWindowSheetEnd(); diff --git a/atom/browser/native_window_mac.h b/atom/browser/native_window_mac.h index 64a816086b2c..a54e24b4668c 100644 --- a/atom/browser/native_window_mac.h +++ b/atom/browser/native_window_mac.h @@ -12,7 +12,6 @@ #include "atom/browser/native_window.h" #include "base/mac/scoped_nsobject.h" -#include "content/public/browser/render_widget_host.h" @class AtomNSWindow; @class AtomNSWindowDelegate; @@ -20,8 +19,7 @@ namespace atom { -class NativeWindowMac : public NativeWindow, - public content::RenderWidgetHost::InputEventObserver { +class NativeWindowMac : public NativeWindow { public: NativeWindowMac(brightray::InspectableWebContents* inspectable_web_contents, const mate::Dictionary& options, @@ -124,13 +122,6 @@ class NativeWindowMac : public NativeWindow, void UpdateDraggableRegions( const std::vector& regions) override; - // content::RenderWidgetHost::InputEventObserver: - void OnInputEvent(const blink::WebInputEvent& event) override; - - // content::WebContentsObserver: - void RenderViewHostChanged(content::RenderViewHost* old_host, - content::RenderViewHost* new_host) override; - // Set the attribute of NSWindow while work around a bug of zoom button. void SetStyleMask(bool on, NSUInteger flag); void SetCollectionBehavior(bool on, NSUInteger flag); @@ -163,9 +154,6 @@ class NativeWindowMac : public NativeWindow, void InstallView(); void UninstallView(); - void RegisterInputEventObserver(content::RenderViewHost* host); - void UnregisterInputEventObserver(content::RenderViewHost* host); - void SetRenderWidgetHostOpaque(bool opaque); base::scoped_nsobject window_; diff --git a/atom/browser/native_window_mac.mm b/atom/browser/native_window_mac.mm index ed51d7219edb..72dd45728f15 100644 --- a/atom/browser/native_window_mac.mm +++ b/atom/browser/native_window_mac.mm @@ -1038,9 +1038,6 @@ NativeWindowMac::NativeWindowMac( // Set maximizable state last to ensure zoom button does not get reset // by calls to other APIs. SetMaximizable(maximizable); - - RegisterInputEventObserver( - web_contents->GetWebContents()->GetRenderViewHost()); } NativeWindowMac::~NativeWindowMac() { @@ -1869,25 +1866,6 @@ void NativeWindowMac::UpdateDraggableRegions( [window_ setMovableByWindowBackground:YES]; } -void NativeWindowMac::OnInputEvent(const blink::WebInputEvent& event) { - switch (event.GetType()) { - case blink::WebInputEvent::kGestureScrollBegin: - case blink::WebInputEvent::kGestureScrollUpdate: - case blink::WebInputEvent::kGestureScrollEnd: - this->NotifyWindowScrollTouchEdge(); - break; - default: - break; - } -} - -void NativeWindowMac::RenderViewHostChanged( - content::RenderViewHost* old_host, - content::RenderViewHost* new_host) { - UnregisterInputEventObserver(old_host); - RegisterInputEventObserver(new_host); -} - std::vector NativeWindowMac::CalculateNonDraggableRegions( const std::vector& regions, int width, int height) { std::vector result; @@ -2016,18 +1994,6 @@ void NativeWindowMac::SetCollectionBehavior(bool on, NSUInteger flag) { SetMaximizable(was_maximizable); } -void NativeWindowMac::RegisterInputEventObserver( - content::RenderViewHost* host) { - if (host) - host->GetWidget()->AddInputEventObserver(this); -} - -void NativeWindowMac::UnregisterInputEventObserver( - content::RenderViewHost* host) { - if (host) - host->GetWidget()->RemoveInputEventObserver(this); -} - // static NativeWindow* NativeWindow::Create( brightray::InspectableWebContents* inspectable_web_contents, diff --git a/atom/browser/native_window_observer.h b/atom/browser/native_window_observer.h index d3c34cbe2212..27f5cb92f8a3 100644 --- a/atom/browser/native_window_observer.h +++ b/atom/browser/native_window_observer.h @@ -65,7 +65,6 @@ class NativeWindowObserver { virtual void OnWindowMoved() {} virtual void OnWindowScrollTouchBegin() {} virtual void OnWindowScrollTouchEnd() {} - virtual void OnWindowScrollTouchEdge() {} virtual void OnWindowSwipe(const std::string& direction) {} virtual void OnWindowSheetBegin() {} virtual void OnWindowSheetEnd() {} From c87fc2426def75727f8fca611f4f27df96a26988 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 22 Feb 2018 17:54:38 +0900 Subject: [PATCH 13/15] Handle transparent WebContents in api::BrowserWindow --- atom/browser/api/atom_api_browser_window.cc | 5 +++++ atom/browser/native_window.cc | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/atom/browser/api/atom_api_browser_window.cc b/atom/browser/api/atom_api_browser_window.cc index 0554a9b97aa6..6a0aa821efb3 100644 --- a/atom/browser/api/atom_api_browser_window.cc +++ b/atom/browser/api/atom_api_browser_window.cc @@ -30,6 +30,7 @@ #include "native_mate/constructor.h" #include "native_mate/dictionary.h" #include "ui/gfx/geometry/rect.h" +#include "ui/gl/gpu_switching_manager.h" #if defined(TOOLKIT_VIEWS) #include "atom/browser/native_window_views.h" @@ -155,6 +156,10 @@ void BrowserWindow::Init(v8::Isolate* isolate, web_contents->SetOwnerWindow(window_.get()); window_->set_is_offscreen_dummy(api_web_contents_->IsOffScreen()); + // Tell the content module to initialize renderer widget with transparent + // mode. + ui::GpuSwitchingManager::SetTransparent(window_->transparent()); + #if defined(TOOLKIT_VIEWS) // Sets the window icon. mate::Handle icon; diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index ea11b91ee69d..c3d6a4283a0f 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -38,7 +38,6 @@ #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size_conversions.h" -#include "ui/gl/gpu_switching_manager.h" #if defined(OS_LINUX) || defined(OS_WIN) #include "content/public/common/renderer_preferences.h" @@ -87,10 +86,6 @@ NativeWindow::NativeWindow( prefs->subpixel_rendering = params.subpixel_rendering; #endif - // Tell the content module to initialize renderer widget with transparent - // mode. - ui::GpuSwitchingManager::SetTransparent(transparent_); - WindowList::AddWindow(this); } From 816a96c2cc578f2bfafe7d8ab3f1ba12f82df77c Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 22 Feb 2018 17:56:48 +0900 Subject: [PATCH 14/15] Update font settings in api::WebContents --- atom/browser/api/atom_api_web_contents.cc | 18 ++++++++++++++++++ atom/browser/native_window.cc | 19 ------------------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/atom/browser/api/atom_api_web_contents.cc b/atom/browser/api/atom_api_web_contents.cc index 127a05ab9149..86851826bb4a 100644 --- a/atom/browser/api/atom_api_web_contents.cc +++ b/atom/browser/api/atom_api_web_contents.cc @@ -89,6 +89,11 @@ #include "ui/aura/window.h" #endif +#if defined(OS_LINUX) || defined(OS_WIN) +#include "content/public/common/renderer_preferences.h" +#include "ui/gfx/font_render_params.h" +#endif + #include "atom/common/node_includes.h" namespace { @@ -412,6 +417,19 @@ void WebContents::InitWithSessionAndOptions(v8::Isolate* isolate, managed_web_contents()->GetView()->SetDelegate(this); +#if defined(OS_LINUX) || defined(OS_WIN) + // Update font settings. + auto* prefs = web_contents->GetMutableRendererPrefs(); + CR_DEFINE_STATIC_LOCAL(const gfx::FontRenderParams, params, + (gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), nullptr))); + prefs->should_antialias_text = params.antialiasing; + prefs->use_subpixel_positioning = params.subpixel_positioning; + prefs->hinting = params.hinting; + prefs->use_autohinter = params.autohinter; + prefs->use_bitmaps = params.use_bitmaps; + prefs->subpixel_rendering = params.subpixel_rendering; +#endif + // Save the preferences in C++. new WebContentsPreferences(web_contents, options); diff --git a/atom/browser/native_window.cc b/atom/browser/native_window.cc index c3d6a4283a0f..a96b65424a90 100644 --- a/atom/browser/native_window.cc +++ b/atom/browser/native_window.cc @@ -39,11 +39,6 @@ #include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size_conversions.h" -#if defined(OS_LINUX) || defined(OS_WIN) -#include "content/public/common/renderer_preferences.h" -#include "ui/gfx/font_render_params.h" -#endif - DEFINE_WEB_CONTENTS_USER_DATA_KEY(atom::NativeWindowRelay); namespace atom { @@ -72,20 +67,6 @@ NativeWindow::NativeWindow( if (parent) options.Get("modal", &is_modal_); -#if defined(OS_LINUX) || defined(OS_WIN) - auto* prefs = web_contents()->GetMutableRendererPrefs(); - - // Update font settings. - CR_DEFINE_STATIC_LOCAL(const gfx::FontRenderParams, params, - (gfx::GetFontRenderParams(gfx::FontRenderParamsQuery(), nullptr))); - prefs->should_antialias_text = params.antialiasing; - prefs->use_subpixel_positioning = params.subpixel_positioning; - prefs->hinting = params.hinting; - prefs->use_autohinter = params.autohinter; - prefs->use_bitmaps = params.use_bitmaps; - prefs->subpixel_rendering = params.subpixel_rendering; -#endif - WindowList::AddWindow(this); } From 3be92f550ce1ad7b34bf4dd4e1180deef173a6af Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 23 Feb 2018 09:15:13 +0900 Subject: [PATCH 15/15] Better clarity and fix typo --- atom/browser/api/atom_api_browser_window.cc | 18 +++++++++--------- atom/browser/api/atom_api_browser_window.h | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/atom/browser/api/atom_api_browser_window.cc b/atom/browser/api/atom_api_browser_window.cc index 6a0aa821efb3..08e953539a98 100644 --- a/atom/browser/api/atom_api_browser_window.cc +++ b/atom/browser/api/atom_api_browser_window.cc @@ -136,8 +136,8 @@ void BrowserWindow::Init(v8::Isolate* isolate, mate::Handle web_contents) { web_contents_.Reset(isolate, web_contents.ToV8()); api_web_contents_ = web_contents.get(); - Observe(web_contents->web_contents()); api_web_contents_->AddObserver(this); + Observe(api_web_contents_->web_contents()); // Keep a copy of the options for later use. mate::Dictionary(isolate, web_contents->GetWrapper()).Set( @@ -248,7 +248,7 @@ void BrowserWindow::DidFirstVisuallyNonEmptyPaint() { void BrowserWindow::BeforeUnloadDialogCancelled() { WindowList::WindowCloseCancelled(window_.get()); // Cancel unresponsive event when window close is cancelled. - window_unresposive_closure_.Cancel(); + window_unresponsive_closure_.Cancel(); } void BrowserWindow::OnRendererUnresponsive(content::RenderWidgetHost*) { @@ -295,11 +295,11 @@ void BrowserWindow::OnCloseContents() { window_->CloseImmediately(); // Do not sent "unresponsive" event after window is closed. - window_unresposive_closure_.Cancel(); + window_unresponsive_closure_.Cancel(); } void BrowserWindow::OnRendererResponsive() { - window_unresposive_closure_.Cancel(); + window_unresponsive_closure_.Cancel(); Emit("responsive"); } @@ -317,7 +317,7 @@ void BrowserWindow::OnCloseButtonClicked(bool* prevent_default) { // not closed in 5s, in this way we can quickly show the unresponsive // dialog when the window is busy executing some script withouth waiting for // the unresponsive timeout. - if (window_unresposive_closure_.IsCancelled()) + if (window_unresponsive_closure_.IsCancelled()) ScheduleUnresponsiveEvent(5000); if (!web_contents()) @@ -1139,19 +1139,19 @@ void BrowserWindow::UpdateDraggableRegions( } void BrowserWindow::ScheduleUnresponsiveEvent(int ms) { - if (!window_unresposive_closure_.IsCancelled()) + if (!window_unresponsive_closure_.IsCancelled()) return; - window_unresposive_closure_.Reset( + window_unresponsive_closure_.Reset( base::Bind(&BrowserWindow::NotifyWindowUnresponsive, GetWeakPtr())); base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( FROM_HERE, - window_unresposive_closure_.callback(), + window_unresponsive_closure_.callback(), base::TimeDelta::FromMilliseconds(ms)); } void BrowserWindow::NotifyWindowUnresponsive() { - window_unresposive_closure_.Cancel(); + window_unresponsive_closure_.Cancel(); if (!window_->IsClosed() && window_->IsEnabled() && !IsUnresponsiveEventSuppressed()) { Emit("unresponsive"); diff --git a/atom/browser/api/atom_api_browser_window.h b/atom/browser/api/atom_api_browser_window.h index f5ba1c587c28..65f3a10f7ad9 100644 --- a/atom/browser/api/atom_api_browser_window.h +++ b/atom/browser/api/atom_api_browser_window.h @@ -273,7 +273,7 @@ class BrowserWindow : public mate::TrackableObject, // Closure that would be called when window is unresponsive when closing, // it should be cancelled when we can prove that the window is responsive. - base::CancelableClosure window_unresposive_closure_; + base::CancelableClosure window_unresponsive_closure_; v8::Global browser_view_; v8::Global web_contents_;