Merge pull request #12348 from electron/fix-browser-view-draggable-region

Update draggable regions when changing BrowserView
This commit is contained in:
John Kleinschmidt 2018-03-20 10:40:27 -04:00 committed by GitHub
commit 060b592fc8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 74 additions and 76 deletions

View file

@ -68,8 +68,8 @@ void BrowserView::Init(v8::Isolate* isolate,
web_contents_.Reset(isolate, web_contents.ToV8()); web_contents_.Reset(isolate, web_contents.ToV8());
api_web_contents_ = web_contents.get(); api_web_contents_ = web_contents.get();
view_.reset(NativeBrowserView::Create( view_.reset(
api_web_contents_->managed_web_contents()->GetView())); NativeBrowserView::Create(api_web_contents_->managed_web_contents()));
InitWith(isolate, wrapper); InitWith(isolate, wrapper);
} }

View file

@ -1057,6 +1057,10 @@ void BrowserWindow::SetBrowserView(v8::Local<v8::Value> value) {
window_->SetBrowserView(browser_view->view()); window_->SetBrowserView(browser_view->view());
browser_view->web_contents()->SetOwnerWindow(window_.get()); browser_view->web_contents()->SetOwnerWindow(window_.get());
browser_view_.Reset(isolate(), value); browser_view_.Reset(isolate(), value);
#if defined(OS_MACOSX)
UpdateDraggableRegions(nullptr, draggable_regions_);
#endif
} }
} }

View file

@ -80,30 +80,24 @@ void BrowserWindow::UpdateDraggableRegions(
// Draggable regions is implemented by having the whole web view draggable // Draggable regions is implemented by having the whole web view draggable
// (mouseDownCanMoveWindow) and overlaying regions that are not draggable. // (mouseDownCanMoveWindow) and overlaying regions that are not draggable.
draggable_regions_ = regions; draggable_regions_ = regions;
std::vector<gfx::Rect> system_drag_exclude_areas; std::vector<gfx::Rect> drag_exclude_rects;
if (regions.empty()) { if (regions.empty()) {
system_drag_exclude_areas.push_back( drag_exclude_rects.push_back(gfx::Rect(0, 0, webViewWidth, webViewHeight));
gfx::Rect(0, 0, webViewWidth, webViewHeight));
} else { } else {
system_drag_exclude_areas = CalculateNonDraggableRegions( drag_exclude_rects = CalculateNonDraggableRegions(
DraggableRegionsToSkRegion(regions), webViewWidth, webViewHeight); DraggableRegionsToSkRegion(regions), webViewWidth, webViewHeight);
} }
if (window_->browser_view()) if (window_->browser_view())
window_->browser_view()->UpdateDraggableRegions(system_drag_exclude_areas); window_->browser_view()->UpdateDraggableRegions(drag_exclude_rects);
// Create and add a ControlRegionView for each region that needs to be // Create and add a ControlRegionView for each region that needs to be
// excluded from the dragging. // excluded from the dragging.
for (std::vector<gfx::Rect>::const_iterator iter = for (const auto& rect : drag_exclude_rects) {
system_drag_exclude_areas.begin();
iter != system_drag_exclude_areas.end();
++iter) {
base::scoped_nsobject<NSView> controlRegion( base::scoped_nsobject<NSView> controlRegion(
[[ControlRegionView alloc] initWithFrame:NSZeroRect]); [[ControlRegionView alloc] initWithFrame:NSZeroRect]);
[controlRegion setFrame:NSMakeRect(iter->x(), [controlRegion setFrame:NSMakeRect(rect.x(), webViewHeight - rect.bottom(),
webViewHeight - iter->bottom(), rect.width(), rect.height())];
iter->width(),
iter->height())];
[webView addSubview:controlRegion]; [webView addSubview:controlRegion];
} }

View file

@ -7,14 +7,23 @@
#include "atom/browser/native_browser_view.h" #include "atom/browser/native_browser_view.h"
#include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/api/atom_api_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.h" #include "brightray/browser/inspectable_web_contents.h"
namespace atom { namespace atom {
NativeBrowserView::NativeBrowserView( NativeBrowserView::NativeBrowserView(
brightray::InspectableWebContentsView* web_contents_view) brightray::InspectableWebContents* inspectable_web_contents)
: web_contents_view_(web_contents_view) {} : inspectable_web_contents_(inspectable_web_contents) {}
NativeBrowserView::~NativeBrowserView() {} NativeBrowserView::~NativeBrowserView() {}
brightray::InspectableWebContentsView*
NativeBrowserView::GetInspectableWebContentsView() {
return inspectable_web_contents_->GetView();
}
content::WebContents* NativeBrowserView::GetWebContents() {
return inspectable_web_contents_->GetWebContents();
}
} // namespace atom } // namespace atom

View file

@ -9,9 +9,11 @@
#include "atom/common/draggable_region.h" #include "atom/common/draggable_region.h"
#include "base/macros.h" #include "base/macros.h"
#include "content/public/browser/web_contents.h"
#include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkColor.h"
namespace brightray { namespace brightray {
class InspectableWebContents;
class InspectableWebContentsView; class InspectableWebContentsView;
} }
@ -31,12 +33,15 @@ class NativeBrowserView {
virtual ~NativeBrowserView(); virtual ~NativeBrowserView();
static NativeBrowserView* Create( static NativeBrowserView* Create(
brightray::InspectableWebContentsView* web_contents_view); brightray::InspectableWebContents* inspectable_web_contents);
brightray::InspectableWebContentsView* GetInspectableWebContentsView() { brightray::InspectableWebContents* GetInspectableWebContents() {
return web_contents_view_; return inspectable_web_contents_;
} }
brightray::InspectableWebContentsView* GetInspectableWebContentsView();
content::WebContents* GetWebContents();
virtual void SetAutoResizeFlags(uint8_t flags) = 0; virtual void SetAutoResizeFlags(uint8_t flags) = 0;
virtual void SetBounds(const gfx::Rect& bounds) = 0; virtual void SetBounds(const gfx::Rect& bounds) = 0;
virtual void SetBackgroundColor(SkColor color) = 0; virtual void SetBackgroundColor(SkColor color) = 0;
@ -47,9 +52,9 @@ class NativeBrowserView {
protected: protected:
explicit NativeBrowserView( explicit NativeBrowserView(
brightray::InspectableWebContentsView* web_contents_view); brightray::InspectableWebContents* inspectable_web_contents);
brightray::InspectableWebContentsView* web_contents_view_; brightray::InspectableWebContents* inspectable_web_contents_;
private: private:
DISALLOW_COPY_AND_ASSIGN(NativeBrowserView); DISALLOW_COPY_AND_ASSIGN(NativeBrowserView);

View file

@ -17,12 +17,13 @@ namespace atom {
class NativeBrowserViewMac : public NativeBrowserView { class NativeBrowserViewMac : public NativeBrowserView {
public: public:
explicit NativeBrowserViewMac( explicit NativeBrowserViewMac(
brightray::InspectableWebContentsView* web_contents_view); brightray::InspectableWebContents* inspectable_web_contents);
~NativeBrowserViewMac() override; ~NativeBrowserViewMac() override;
void SetAutoResizeFlags(uint8_t flags) override; void SetAutoResizeFlags(uint8_t flags) override;
void SetBounds(const gfx::Rect& bounds) override; void SetBounds(const gfx::Rect& bounds) override;
void SetBackgroundColor(SkColor color) override; void SetBackgroundColor(SkColor color) override;
void UpdateDraggableRegions( void UpdateDraggableRegions(
const std::vector<gfx::Rect>& system_drag_exclude_areas) override; const std::vector<gfx::Rect>& system_drag_exclude_areas) override;

View file

@ -4,6 +4,7 @@
#include "atom/browser/native_browser_view_mac.h" #include "atom/browser/native_browser_view_mac.h"
#include "brightray/browser/inspectable_web_contents.h"
#include "brightray/browser/inspectable_web_contents_view.h" #include "brightray/browser/inspectable_web_contents_view.h"
#include "skia/ext/skia_utils_mac.h" #include "skia/ext/skia_utils_mac.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
@ -156,8 +157,8 @@ const NSAutoresizingMaskOptions kDefaultAutoResizingMask =
namespace atom { namespace atom {
NativeBrowserViewMac::NativeBrowserViewMac( NativeBrowserViewMac::NativeBrowserViewMac(
brightray::InspectableWebContentsView* web_contents_view) brightray::InspectableWebContents* inspectable_web_contents)
: NativeBrowserView(web_contents_view) { : NativeBrowserView(inspectable_web_contents) {
auto* view = GetInspectableWebContentsView()->GetNativeView(); auto* view = GetInspectableWebContentsView()->GetNativeView();
view.autoresizingMask = kDefaultAutoResizingMask; view.autoresizingMask = kDefaultAutoResizingMask;
} }
@ -193,62 +194,46 @@ void NativeBrowserViewMac::SetBackgroundColor(SkColor color) {
} }
void NativeBrowserViewMac::UpdateDraggableRegions( void NativeBrowserViewMac::UpdateDraggableRegions(
const std::vector<gfx::Rect>& system_drag_exclude_areas) { const std::vector<gfx::Rect>& drag_exclude_rects) {
NSView* webView = GetInspectableWebContentsView()->GetNativeView(); NSView* web_view = GetWebContents()->GetNativeView();
NSView* inspectable_view = GetInspectableWebContentsView()->GetNativeView();
NSView* window_content_view = inspectable_view.superview;
const auto window_content_view_height = NSHeight(window_content_view.bounds);
NSInteger superViewHeight = NSHeight([webView.superview bounds]); // Remove all DragRegionViews that were added last time. Note that we need
NSInteger webViewHeight = NSHeight([webView bounds]); // to copy the `subviews` array to avoid mutation during iteration.
NSInteger webViewWidth = NSWidth([webView bounds]); base::scoped_nsobject<NSArray> subviews([[web_view subviews] copy]);
NSInteger webViewX = NSMinX([webView frame]); for (NSView* subview in subviews.get()) {
NSInteger webViewY = 0; if ([subview isKindOfClass:[DragRegionView class]]) {
// Apple's NSViews have their coordinate system originate at the bottom left,
// meaning that we need to be a bit smarter when it comes to calculating our
// current top offset
if (webViewHeight > superViewHeight) {
webViewY = std::abs(webViewHeight - superViewHeight - (std::abs(NSMinY([webView frame]))));
} else {
webViewY = superViewHeight - NSMaxY([webView frame]);
}
// Remove all DraggableRegionViews 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<NSArray> subviews([[webView subviews] copy]);
for (NSView* subview in subviews.get())
if ([subview isKindOfClass:[DragRegionView class]])
[subview removeFromSuperview]; [subview removeFromSuperview];
}
}
// Create one giant NSView that is draggable. // Create one giant NSView that is draggable.
base::scoped_nsobject<NSView> dragRegion( base::scoped_nsobject<NSView> drag_region_view(
[[DragRegionView alloc] initWithFrame:NSZeroRect]); [[DragRegionView alloc] initWithFrame:web_view.bounds]);
[dragRegion setFrame:NSMakeRect(0, [web_view addSubview:drag_region_view];
0,
webViewWidth,
webViewHeight)];
// Then, on top of that, add "exclusion zones" // Then, on top of that, add "exclusion zones"
for (auto iter = system_drag_exclude_areas.begin(); for (const auto& rect : drag_exclude_rects) {
iter != system_drag_exclude_areas.end(); const auto window_content_view_exclude_rect =
++iter) { NSMakeRect(rect.x(), window_content_view_height - rect.bottom(),
base::scoped_nsobject<NSView> controlRegion( rect.width(), rect.height());
[[ExcludeDragRegionView alloc] initWithFrame:NSZeroRect]); const auto drag_region_view_exclude_rect =
[controlRegion setFrame:NSMakeRect(iter->x() - webViewX, [window_content_view convertRect:window_content_view_exclude_rect
webViewHeight - iter->bottom() + webViewY, toView:drag_region_view];
iter->width(),
iter->height())];
[dragRegion addSubview:controlRegion];
}
// Add the DragRegion to the WebView base::scoped_nsobject<NSView> exclude_drag_region_view(
[webView addSubview:dragRegion]; [[ExcludeDragRegionView alloc]
initWithFrame:drag_region_view_exclude_rect]);
[drag_region_view addSubview:exclude_drag_region_view];
}
} }
// static // static
NativeBrowserView* NativeBrowserView::Create( NativeBrowserView* NativeBrowserView::Create(
brightray::InspectableWebContentsView* web_contents_view) { brightray::InspectableWebContents* inspectable_web_contents) {
return new NativeBrowserViewMac(web_contents_view); return new NativeBrowserViewMac(inspectable_web_contents);
} }
} // namespace atom } // namespace atom

View file

@ -12,8 +12,8 @@
namespace atom { namespace atom {
NativeBrowserViewViews::NativeBrowserViewViews( NativeBrowserViewViews::NativeBrowserViewViews(
brightray::InspectableWebContentsView* web_contents_view) brightray::InspectableWebContents* inspectable_web_contents)
: NativeBrowserView(web_contents_view) {} : NativeBrowserView(inspectable_web_contents) {}
NativeBrowserViewViews::~NativeBrowserViewViews() {} NativeBrowserViewViews::~NativeBrowserViewViews() {}
@ -29,8 +29,8 @@ void NativeBrowserViewViews::SetBackgroundColor(SkColor color) {
// static // static
NativeBrowserView* NativeBrowserView::Create( NativeBrowserView* NativeBrowserView::Create(
brightray::InspectableWebContentsView* web_contents_view) { brightray::InspectableWebContents* inspectable_web_contents) {
return new NativeBrowserViewViews(web_contents_view); return new NativeBrowserViewViews(inspectable_web_contents);
} }
} // namespace atom } // namespace atom

View file

@ -12,7 +12,7 @@ namespace atom {
class NativeBrowserViewViews : public NativeBrowserView { class NativeBrowserViewViews : public NativeBrowserView {
public: public:
explicit NativeBrowserViewViews( explicit NativeBrowserViewViews(
brightray::InspectableWebContentsView* web_contents_view); brightray::InspectableWebContents* inspectable_web_contents);
~NativeBrowserViewViews() override; ~NativeBrowserViewViews() override;
uint8_t GetAutoResizeFlags() { return auto_resize_flags_; } uint8_t GetAutoResizeFlags() { return auto_resize_flags_; }