Merge pull request #10232 from electron/drag-browser-view
Add -webkit-app-region support to BrowserView
This commit is contained in:
commit
7ecac42214
6 changed files with 167 additions and 1 deletions
|
@ -2,6 +2,8 @@
|
||||||
// Use of this source code is governed by the MIT license that can be
|
// Use of this source code is governed by the MIT license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#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"
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
#ifndef ATOM_BROWSER_NATIVE_BROWSER_VIEW_H_
|
#ifndef ATOM_BROWSER_NATIVE_BROWSER_VIEW_H_
|
||||||
#define ATOM_BROWSER_NATIVE_BROWSER_VIEW_H_
|
#define ATOM_BROWSER_NATIVE_BROWSER_VIEW_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "atom/common/draggable_region.h"
|
||||||
#include "base/macros.h"
|
#include "base/macros.h"
|
||||||
#include "third_party/skia/include/core/SkColor.h"
|
#include "third_party/skia/include/core/SkColor.h"
|
||||||
|
|
||||||
|
@ -38,6 +41,10 @@ class NativeBrowserView {
|
||||||
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;
|
||||||
|
|
||||||
|
// Called when the window needs to update its draggable region.
|
||||||
|
virtual void UpdateDraggableRegions(
|
||||||
|
const std::vector<gfx::Rect>& system_drag_exclude_areas) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit NativeBrowserView(
|
explicit NativeBrowserView(
|
||||||
brightray::InspectableWebContentsView* web_contents_view);
|
brightray::InspectableWebContentsView* web_contents_view);
|
||||||
|
|
|
@ -6,8 +6,11 @@
|
||||||
#define ATOM_BROWSER_NATIVE_BROWSER_VIEW_MAC_H_
|
#define ATOM_BROWSER_NATIVE_BROWSER_VIEW_MAC_H_
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "atom/browser/native_browser_view.h"
|
#include "atom/browser/native_browser_view.h"
|
||||||
|
#include "atom/common/draggable_region.h"
|
||||||
|
#include "base/mac/scoped_nsobject.h"
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
|
@ -20,6 +23,8 @@ class NativeBrowserViewMac : public NativeBrowserView {
|
||||||
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(
|
||||||
|
const std::vector<gfx::Rect>& system_drag_exclude_areas) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_COPY_AND_ASSIGN(NativeBrowserViewMac);
|
DISALLOW_COPY_AND_ASSIGN(NativeBrowserViewMac);
|
||||||
|
|
|
@ -12,6 +12,101 @@
|
||||||
const NSAutoresizingMaskOptions kDefaultAutoResizingMask =
|
const NSAutoresizingMaskOptions kDefaultAutoResizingMask =
|
||||||
NSViewMaxXMargin | NSViewMinYMargin;
|
NSViewMaxXMargin | NSViewMinYMargin;
|
||||||
|
|
||||||
|
@interface DragRegionView : NSView
|
||||||
|
|
||||||
|
@property (assign) NSPoint initialLocation;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface NSWindow ()
|
||||||
|
- (void)performWindowDragWithEvent:(NSEvent *)event;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation DragRegionView
|
||||||
|
|
||||||
|
- (BOOL)mouseDownCanMoveWindow
|
||||||
|
{
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSView *)hitTest:(NSPoint)aPoint
|
||||||
|
{
|
||||||
|
// Pass-through events that don't hit one of the exclusion zones
|
||||||
|
for (NSView *exlusion_zones in [self subviews]) {
|
||||||
|
if ([exlusion_zones hitTest:aPoint])
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mouseDown:(NSEvent *)event
|
||||||
|
{
|
||||||
|
if ([self.window respondsToSelector:@selector(performWindowDragWithEvent)]) {
|
||||||
|
[self.window performWindowDragWithEvent:event];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.initialLocation = [event locationInWindow];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mouseDragged:(NSEvent *)theEvent
|
||||||
|
{
|
||||||
|
if ([self.window respondsToSelector:@selector(performWindowDragWithEvent)]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSPoint currentLocation = [NSEvent mouseLocation];
|
||||||
|
NSPoint newOrigin;
|
||||||
|
|
||||||
|
NSRect screenFrame = [[NSScreen mainScreen] frame];
|
||||||
|
NSRect windowFrame = [self.window frame];
|
||||||
|
|
||||||
|
newOrigin.x = currentLocation.x - self.initialLocation.x;
|
||||||
|
newOrigin.y = currentLocation.y - self.initialLocation.y;
|
||||||
|
|
||||||
|
// Don't let window get dragged up under the menu bar
|
||||||
|
if ((newOrigin.y + windowFrame.size.height) > (screenFrame.origin.y + screenFrame.size.height)) {
|
||||||
|
newOrigin.y = screenFrame.origin.y + (screenFrame.size.height - windowFrame.size.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move the window to the new location
|
||||||
|
[self.window setFrameOrigin:newOrigin];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debugging tips:
|
||||||
|
// Uncomment the following four lines to color DragRegionView bright red
|
||||||
|
// #ifdef DEBUG_DRAG_REGIONS
|
||||||
|
// - (void)drawRect:(NSRect)aRect
|
||||||
|
// {
|
||||||
|
// [[NSColor redColor] set];
|
||||||
|
// NSRectFill([self bounds]);
|
||||||
|
// }
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface ExcludeDragRegionView : NSView
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation ExcludeDragRegionView
|
||||||
|
|
||||||
|
- (BOOL)mouseDownCanMoveWindow {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debugging tips:
|
||||||
|
// Uncomment the following four lines to color ExcludeDragRegionView bright red
|
||||||
|
// #ifdef DEBUG_DRAG_REGIONS
|
||||||
|
// - (void)drawRect:(NSRect)aRect
|
||||||
|
// {
|
||||||
|
// [[NSColor greenColor] set];
|
||||||
|
// NSRectFill([self bounds]);
|
||||||
|
// }
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
|
||||||
NativeBrowserViewMac::NativeBrowserViewMac(
|
NativeBrowserViewMac::NativeBrowserViewMac(
|
||||||
|
@ -51,6 +146,59 @@ void NativeBrowserViewMac::SetBackgroundColor(SkColor color) {
|
||||||
view.layer.backgroundColor = skia::CGColorCreateFromSkColor(color);
|
view.layer.backgroundColor = skia::CGColorCreateFromSkColor(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NativeBrowserViewMac::UpdateDraggableRegions(
|
||||||
|
const std::vector<gfx::Rect>& system_drag_exclude_areas) {
|
||||||
|
NSView* webView = GetInspectableWebContentsView()->GetNativeView();
|
||||||
|
|
||||||
|
NSInteger superViewHeight = NSHeight([webView.superview bounds]);
|
||||||
|
NSInteger webViewHeight = NSHeight([webView bounds]);
|
||||||
|
NSInteger webViewWidth = NSWidth([webView bounds]);
|
||||||
|
NSInteger webViewX = NSMinX([webView frame]);
|
||||||
|
NSInteger webViewY = 0;
|
||||||
|
|
||||||
|
// 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];
|
||||||
|
|
||||||
|
// Create one giant NSView that is draggable.
|
||||||
|
base::scoped_nsobject<NSView> dragRegion(
|
||||||
|
[[DragRegionView alloc] initWithFrame:NSZeroRect]);
|
||||||
|
[dragRegion setFrame:NSMakeRect(0,
|
||||||
|
0,
|
||||||
|
webViewWidth,
|
||||||
|
webViewHeight)];
|
||||||
|
|
||||||
|
// Then, on top of that, add "exclusion zones"
|
||||||
|
for (auto iter = system_drag_exclude_areas.begin();
|
||||||
|
iter != system_drag_exclude_areas.end();
|
||||||
|
++iter) {
|
||||||
|
base::scoped_nsobject<NSView> controlRegion(
|
||||||
|
[[ExcludeDragRegionView alloc] initWithFrame:NSZeroRect]);
|
||||||
|
[controlRegion setFrame:NSMakeRect(iter->x() - webViewX,
|
||||||
|
webViewHeight - iter->bottom() + webViewY,
|
||||||
|
iter->width(),
|
||||||
|
iter->height())];
|
||||||
|
[dragRegion addSubview:controlRegion];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the DragRegion to the WebView
|
||||||
|
[webView addSubview:dragRegion];
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
NativeBrowserView* NativeBrowserView::Create(
|
NativeBrowserView* NativeBrowserView::Create(
|
||||||
brightray::InspectableWebContentsView* web_contents_view) {
|
brightray::InspectableWebContentsView* web_contents_view) {
|
||||||
|
|
|
@ -154,7 +154,7 @@ class NativeWindowMac : public NativeWindow,
|
||||||
void UninstallView();
|
void UninstallView();
|
||||||
|
|
||||||
// Install the drag view, which will cover the whole window and decides
|
// Install the drag view, which will cover the whole window and decides
|
||||||
// whehter we can drag.
|
// whether we can drag.
|
||||||
void UpdateDraggableRegionViews(const std::vector<DraggableRegion>& regions);
|
void UpdateDraggableRegionViews(const std::vector<DraggableRegion>& regions);
|
||||||
|
|
||||||
void RegisterInputEventObserver(content::RenderViewHost* host);
|
void RegisterInputEventObserver(content::RenderViewHost* host);
|
||||||
|
|
|
@ -1767,6 +1767,10 @@ void NativeWindowMac::UpdateDraggableRegionViews(
|
||||||
std::vector<gfx::Rect> system_drag_exclude_areas =
|
std::vector<gfx::Rect> system_drag_exclude_areas =
|
||||||
CalculateNonDraggableRegions(regions, webViewWidth, webViewHeight);
|
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
|
// 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 (std::vector<gfx::Rect>::const_iterator iter =
|
||||||
|
|
Loading…
Add table
Reference in a new issue