From 6b759f0da651a0fa82e6b7ace023ff97bdd124c3 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 5 Nov 2020 21:39:53 +0900 Subject: [PATCH 1/2] fix: make draggable region work when devtools is open --- .../api/electron_api_browser_window_mac.mm | 20 +-------- .../electron_inspectable_web_contents_view.h | 8 ++++ .../electron_inspectable_web_contents_view.mm | 44 ++++++++++++++++++- 3 files changed, 52 insertions(+), 20 deletions(-) diff --git a/shell/browser/api/electron_api_browser_window_mac.mm b/shell/browser/api/electron_api_browser_window_mac.mm index 4f043931ec7fe..d874bb3168da0 100644 --- a/shell/browser/api/electron_api_browser_window_mac.mm +++ b/shell/browser/api/electron_api_browser_window_mac.mm @@ -12,27 +12,9 @@ #include "base/mac/scoped_nsobject.h" #include "shell/browser/native_browser_view.h" #include "shell/browser/native_window_mac.h" +#include "shell/browser/ui/cocoa/electron_inspectable_web_contents_view.h" #include "shell/browser/ui/inspectable_web_contents_view.h" -@interface NSView (WebContentsView) -- (void)setMouseDownCanMoveWindow:(BOOL)can_move; -@end - -@interface ControlRegionView : NSView -@end - -@implementation ControlRegionView - -- (BOOL)mouseDownCanMoveWindow { - return NO; -} - -- (NSView*)hitTest:(NSPoint)aPoint { - return nil; -} - -@end - namespace electron { namespace api { diff --git a/shell/browser/ui/cocoa/electron_inspectable_web_contents_view.h b/shell/browser/ui/cocoa/electron_inspectable_web_contents_view.h index 691c25f639332..ba247812bb8b1 100644 --- a/shell/browser/ui/cocoa/electron_inspectable_web_contents_view.h +++ b/shell/browser/ui/cocoa/electron_inspectable_web_contents_view.h @@ -17,12 +17,20 @@ class InspectableWebContentsViewMac; using electron::InspectableWebContentsViewMac; +@interface NSView (WebContentsView) +- (void)setMouseDownCanMoveWindow:(BOOL)can_move; +@end + +@interface ControlRegionView : NSView +@end + @interface ElectronInspectableWebContentsView : BaseView { @private electron::InspectableWebContentsViewMac* inspectableWebContentsView_; base::scoped_nsobject fake_view_; base::scoped_nsobject devtools_window_; + base::scoped_nsobject devtools_mask_; BOOL devtools_visible_; BOOL devtools_docked_; BOOL devtools_is_first_responder_; diff --git a/shell/browser/ui/cocoa/electron_inspectable_web_contents_view.mm b/shell/browser/ui/cocoa/electron_inspectable_web_contents_view.mm index 0b25862211bd3..54997092d4f1e 100644 --- a/shell/browser/ui/cocoa/electron_inspectable_web_contents_view.mm +++ b/shell/browser/ui/cocoa/electron_inspectable_web_contents_view.mm @@ -11,6 +11,18 @@ #include "shell/browser/ui/inspectable_web_contents_view_mac.h" #include "ui/gfx/mac/scoped_cocoa_disable_screen_updates.h" +@implementation ControlRegionView + +- (BOOL)mouseDownCanMoveWindow { + return NO; +} + +- (NSView*)hitTest:(NSPoint)aPoint { + return nil; +} + +@end + @implementation ElectronInspectableWebContentsView - (instancetype)initWithInspectableWebContentsViewMac: @@ -48,6 +60,9 @@ - (instancetype)initWithInspectableWebContentsViewMac: [self addSubview:contentsView]; } + // This will float above devtools to exclude it from dragging. + devtools_mask_.reset([[ControlRegionView alloc] initWithFrame:NSZeroRect]); + // See https://code.google.com/p/chromium/issues/detail?id=348490. [self setWantsLayer:YES]; @@ -84,6 +99,12 @@ - (void)setDevToolsVisible:(BOOL)visible activate:(BOOL)activate { devtools_visible_ = visible; if (devtools_docked_) { if (visible) { + // The devToolsView is placed under the contentsView, so it has to be + // draggable to make draggable region of contentsView work. + [devToolsView setMouseDownCanMoveWindow:YES]; + // This view will exclude the actual devtools part from dragging. + [self addSubview:devtools_mask_.get()]; + // Place the devToolsView under contentsView, notice that we didn't set // sizes for them until the setContentsResizingStrategy message. [self addSubview:devToolsView positioned:NSWindowBelow relativeTo:nil]; @@ -94,6 +115,7 @@ - (void)setDevToolsVisible:(BOOL)visible activate:(BOOL)activate { } else { gfx::ScopedCocoaDisableScreenUpdates disabler; [devToolsView removeFromSuperview]; + [devtools_mask_ removeFromSuperview]; [self adjustSubviews]; } } else { @@ -182,7 +204,7 @@ - (void)adjustSubviews { NSView* devToolsView = [[self subviews] objectAtIndex:0]; NSView* contentsView = [[self subviews] objectAtIndex:1]; - DCHECK_EQ(2u, [[self subviews] count]); + DCHECK_EQ(3u, [[self subviews] count]); gfx::Rect new_devtools_bounds; gfx::Rect new_contents_bounds; @@ -191,6 +213,26 @@ - (void)adjustSubviews { &new_devtools_bounds, &new_contents_bounds); [devToolsView setFrame:[self flipRectToNSRect:new_devtools_bounds]]; [contentsView setFrame:[self flipRectToNSRect:new_contents_bounds]]; + + // Move mask to the devtools area to exclude it from dragging. + NSRect cf = contentsView.frame; + NSRect sb = [self bounds]; + NSRect devtools_frame; + if (cf.size.height < sb.size.height) { // bottom docked + devtools_frame.origin.x = 0; + devtools_frame.origin.y = 0; + devtools_frame.size.width = sb.size.width; + devtools_frame.size.height = sb.size.height - cf.size.height; + } else { // left or right docked + if (cf.origin.x > 0) // left docked + devtools_frame.origin.x = 0; + else // right docked. + devtools_frame.origin.x = cf.size.width; + devtools_frame.origin.y = 0; + devtools_frame.size.width = sb.size.width - cf.size.width; + devtools_frame.size.height = sb.size.height; + } + [devtools_mask_ setFrame:devtools_frame]; } - (void)setTitle:(NSString*)title { From 049e34ffe4fc22f4d91e2729caaee13063a37175 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 6 Nov 2020 14:06:42 +0900 Subject: [PATCH 2/2] fix: update draggable regions when resizing --- shell/browser/api/electron_api_browser_window.h | 3 +++ shell/browser/api/electron_api_browser_window_mac.mm | 4 ++++ shell/browser/api/electron_api_web_contents.cc | 5 +++++ shell/browser/api/electron_api_web_contents.h | 1 + shell/browser/extended_web_contents_observer.h | 1 + .../cocoa/electron_inspectable_web_contents_view.mm | 11 +++++++++++ .../ui/inspectable_web_contents_view_delegate.h | 1 + 7 files changed, 26 insertions(+) diff --git a/shell/browser/api/electron_api_browser_window.h b/shell/browser/api/electron_api_browser_window.h index 47af4175e3aa1..e08d334b9c096 100644 --- a/shell/browser/api/electron_api_browser_window.h +++ b/shell/browser/api/electron_api_browser_window.h @@ -60,6 +60,9 @@ class BrowserWindow : public TopLevelWindow, void OnRendererResponsive() override; void OnDraggableRegionsUpdated( const std::vector& regions) override; +#if defined(OS_MACOSX) + void OnDevToolsResized() override; +#endif // NativeWindowObserver: void RequestPreferredWidth(int* width) override; diff --git a/shell/browser/api/electron_api_browser_window_mac.mm b/shell/browser/api/electron_api_browser_window_mac.mm index d874bb3168da0..15eb63c3ae394 100644 --- a/shell/browser/api/electron_api_browser_window_mac.mm +++ b/shell/browser/api/electron_api_browser_window_mac.mm @@ -36,6 +36,10 @@ [contentView viewDidMoveToWindow]; } +void BrowserWindow::OnDevToolsResized() { + UpdateDraggableRegions(draggable_regions_); +} + void BrowserWindow::UpdateDraggableRegions( const std::vector& regions) { if (window_->has_frame()) diff --git a/shell/browser/api/electron_api_web_contents.cc b/shell/browser/api/electron_api_web_contents.cc index e10c573f10148..d3e9c2dc285b1 100644 --- a/shell/browser/api/electron_api_web_contents.cc +++ b/shell/browser/api/electron_api_web_contents.cc @@ -1448,6 +1448,11 @@ void WebContents::DevToolsClosed() { Emit("devtools-closed"); } +void WebContents::DevToolsResized() { + for (ExtendedWebContentsObserver& observer : observers_) + observer.OnDevToolsResized(); +} + bool WebContents::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(WebContents, message) diff --git a/shell/browser/api/electron_api_web_contents.h b/shell/browser/api/electron_api_web_contents.h index 2bf9845990476..fd5093a175011 100644 --- a/shell/browser/api/electron_api_web_contents.h +++ b/shell/browser/api/electron_api_web_contents.h @@ -548,6 +548,7 @@ class WebContents : public gin_helper::TrackableObject, void DevToolsFocused() override; void DevToolsOpened() override; void DevToolsClosed() override; + void DevToolsResized() override; private: ElectronBrowserContext* GetBrowserContext() const; diff --git a/shell/browser/extended_web_contents_observer.h b/shell/browser/extended_web_contents_observer.h index aaf24d117d0a0..ffd984011476e 100644 --- a/shell/browser/extended_web_contents_observer.h +++ b/shell/browser/extended_web_contents_observer.h @@ -20,6 +20,7 @@ class ExtendedWebContentsObserver : public base::CheckedObserver { virtual void OnRendererResponsive() {} virtual void OnDraggableRegionsUpdated( const std::vector& regions) {} + virtual void OnDevToolsResized() {} protected: ~ExtendedWebContentsObserver() override {} diff --git a/shell/browser/ui/cocoa/electron_inspectable_web_contents_view.mm b/shell/browser/ui/cocoa/electron_inspectable_web_contents_view.mm index 54997092d4f1e..4f932e7efcc8e 100644 --- a/shell/browser/ui/cocoa/electron_inspectable_web_contents_view.mm +++ b/shell/browser/ui/cocoa/electron_inspectable_web_contents_view.mm @@ -86,6 +86,14 @@ - (void)notifyDevToolsFocused { inspectableWebContentsView_->GetDelegate()->DevToolsFocused(); } +- (void)notifyDevToolsResized { + // When devtools is opened, resizing devtools would not trigger + // UpdateDraggableRegions for WebContents, so we have to notify the window + // to do an update of draggable regions. + if (inspectableWebContentsView_->GetDelegate()) + inspectableWebContentsView_->GetDelegate()->DevToolsResized(); +} + - (void)setDevToolsVisible:(BOOL)visible activate:(BOOL)activate { if (visible == devtools_visible_) return; @@ -117,6 +125,7 @@ - (void)setDevToolsVisible:(BOOL)visible activate:(BOOL)activate { [devToolsView removeFromSuperview]; [devtools_mask_ removeFromSuperview]; [self adjustSubviews]; + [self notifyDevToolsResized]; } } else { if (visible) { @@ -233,6 +242,8 @@ - (void)adjustSubviews { devtools_frame.size.height = sb.size.height; } [devtools_mask_ setFrame:devtools_frame]; + + [self notifyDevToolsResized]; } - (void)setTitle:(NSString*)title { diff --git a/shell/browser/ui/inspectable_web_contents_view_delegate.h b/shell/browser/ui/inspectable_web_contents_view_delegate.h index 73c4214d3874b..a93a17bce75aa 100644 --- a/shell/browser/ui/inspectable_web_contents_view_delegate.h +++ b/shell/browser/ui/inspectable_web_contents_view_delegate.h @@ -19,6 +19,7 @@ class InspectableWebContentsViewDelegate { virtual void DevToolsFocused() {} virtual void DevToolsOpened() {} virtual void DevToolsClosed() {} + virtual void DevToolsResized() {} // Returns the icon of devtools window. virtual gfx::ImageSkia GetDevToolsWindowIcon();