Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: make draggable regions work when devtools is opened on macOS #26506

Merged
merged 2 commits into from Nov 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions shell/browser/api/electron_api_browser_window.h
Expand Up @@ -60,6 +60,9 @@ class BrowserWindow : public TopLevelWindow,
void OnRendererResponsive() override;
void OnDraggableRegionsUpdated(
const std::vector<mojom::DraggableRegionPtr>& regions) override;
#if defined(OS_MACOSX)
void OnDevToolsResized() override;
#endif

// NativeWindowObserver:
void RequestPreferredWidth(int* width) override;
Expand Down
24 changes: 5 additions & 19 deletions shell/browser/api/electron_api_browser_window_mac.mm
Expand Up @@ -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 {
Expand All @@ -54,6 +36,10 @@ - (NSView*)hitTest:(NSPoint)aPoint {
[contentView viewDidMoveToWindow];
}

void BrowserWindow::OnDevToolsResized() {
UpdateDraggableRegions(draggable_regions_);
}

void BrowserWindow::UpdateDraggableRegions(
const std::vector<mojom::DraggableRegionPtr>& regions) {
if (window_->has_frame())
Expand Down
5 changes: 5 additions & 0 deletions shell/browser/api/electron_api_web_contents.cc
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions shell/browser/api/electron_api_web_contents.h
Expand Up @@ -548,6 +548,7 @@ class WebContents : public gin_helper::TrackableObject<WebContents>,
void DevToolsFocused() override;
void DevToolsOpened() override;
void DevToolsClosed() override;
void DevToolsResized() override;

private:
ElectronBrowserContext* GetBrowserContext() const;
Expand Down
1 change: 1 addition & 0 deletions shell/browser/extended_web_contents_observer.h
Expand Up @@ -20,6 +20,7 @@ class ExtendedWebContentsObserver : public base::CheckedObserver {
virtual void OnRendererResponsive() {}
virtual void OnDraggableRegionsUpdated(
const std::vector<mojom::DraggableRegionPtr>& regions) {}
virtual void OnDevToolsResized() {}

protected:
~ExtendedWebContentsObserver() override {}
Expand Down
Expand Up @@ -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 <NSWindowDelegate> {
@private
electron::InspectableWebContentsViewMac* inspectableWebContentsView_;

base::scoped_nsobject<NSView> fake_view_;
base::scoped_nsobject<NSWindow> devtools_window_;
base::scoped_nsobject<ControlRegionView> devtools_mask_;
BOOL devtools_visible_;
BOOL devtools_docked_;
BOOL devtools_is_first_responder_;
Expand Down
55 changes: 54 additions & 1 deletion shell/browser/ui/cocoa/electron_inspectable_web_contents_view.mm
Expand Up @@ -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:
Expand Down Expand Up @@ -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];

Expand All @@ -71,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;
Expand All @@ -84,6 +107,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];
Expand All @@ -94,7 +123,9 @@ - (void)setDevToolsVisible:(BOOL)visible activate:(BOOL)activate {
} else {
gfx::ScopedCocoaDisableScreenUpdates disabler;
[devToolsView removeFromSuperview];
[devtools_mask_ removeFromSuperview];
[self adjustSubviews];
[self notifyDevToolsResized];
}
} else {
if (visible) {
Expand Down Expand Up @@ -182,7 +213,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;
Expand All @@ -191,6 +222,28 @@ - (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];

[self notifyDevToolsResized];
}

- (void)setTitle:(NSString*)title {
Expand Down
1 change: 1 addition & 0 deletions shell/browser/ui/inspectable_web_contents_view_delegate.h
Expand Up @@ -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();
Expand Down