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
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/native_browser_view.h"
|
||||
|
||||
#include "atom/browser/api/atom_api_web_contents.h"
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
#ifndef 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 "third_party/skia/include/core/SkColor.h"
|
||||
|
||||
|
@ -38,6 +41,10 @@ class NativeBrowserView {
|
|||
virtual void SetBounds(const gfx::Rect& bounds) = 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:
|
||||
explicit NativeBrowserView(
|
||||
brightray::InspectableWebContentsView* web_contents_view);
|
||||
|
|
|
@ -6,8 +6,11 @@
|
|||
#define ATOM_BROWSER_NATIVE_BROWSER_VIEW_MAC_H_
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#include <vector>
|
||||
|
||||
#include "atom/browser/native_browser_view.h"
|
||||
#include "atom/common/draggable_region.h"
|
||||
#include "base/mac/scoped_nsobject.h"
|
||||
|
||||
namespace atom {
|
||||
|
||||
|
@ -20,6 +23,8 @@ class NativeBrowserViewMac : public NativeBrowserView {
|
|||
void SetAutoResizeFlags(uint8_t flags) override;
|
||||
void SetBounds(const gfx::Rect& bounds) override;
|
||||
void SetBackgroundColor(SkColor color) override;
|
||||
void UpdateDraggableRegions(
|
||||
const std::vector<gfx::Rect>& system_drag_exclude_areas) override;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(NativeBrowserViewMac);
|
||||
|
|
|
@ -12,6 +12,101 @@
|
|||
const NSAutoresizingMaskOptions kDefaultAutoResizingMask =
|
||||
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 {
|
||||
|
||||
NativeBrowserViewMac::NativeBrowserViewMac(
|
||||
|
@ -51,6 +146,59 @@ void NativeBrowserViewMac::SetBackgroundColor(SkColor 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
|
||||
NativeBrowserView* NativeBrowserView::Create(
|
||||
brightray::InspectableWebContentsView* web_contents_view) {
|
||||
|
|
|
@ -154,7 +154,7 @@ class NativeWindowMac : public NativeWindow,
|
|||
void UninstallView();
|
||||
|
||||
// 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 RegisterInputEventObserver(content::RenderViewHost* host);
|
||||
|
|
|
@ -1767,6 +1767,10 @@ void NativeWindowMac::UpdateDraggableRegionViews(
|
|||
std::vector<gfx::Rect> 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<gfx::Rect>::const_iterator iter =
|
||||
|
|
Loading…
Add table
Reference in a new issue