fix: make draggable regions work when devtools is opened on macOS (#26361)
* fix: make draggable region work when devtools is open * fix: update draggable regions when resizing
This commit is contained in:
parent
f21a21f172
commit
02a8c0a640
8 changed files with 78 additions and 20 deletions
|
@ -63,6 +63,9 @@ class BrowserWindow : public BaseWindow,
|
||||||
void OnActivateContents() override;
|
void OnActivateContents() override;
|
||||||
void OnPageTitleUpdated(const base::string16& title,
|
void OnPageTitleUpdated(const base::string16& title,
|
||||||
bool explicit_set) override;
|
bool explicit_set) override;
|
||||||
|
#if defined(OS_MAC)
|
||||||
|
void OnDevToolsResized() override;
|
||||||
|
#endif
|
||||||
|
|
||||||
// NativeWindowObserver:
|
// NativeWindowObserver:
|
||||||
void RequestPreferredWidth(int* width) override;
|
void RequestPreferredWidth(int* width) override;
|
||||||
|
|
|
@ -12,27 +12,9 @@
|
||||||
#include "base/mac/scoped_nsobject.h"
|
#include "base/mac/scoped_nsobject.h"
|
||||||
#include "shell/browser/native_browser_view.h"
|
#include "shell/browser/native_browser_view.h"
|
||||||
#include "shell/browser/native_window_mac.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"
|
#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 electron {
|
||||||
|
|
||||||
namespace api {
|
namespace api {
|
||||||
|
@ -54,6 +36,10 @@ void BrowserWindow::OverrideNSWindowContentView(InspectableWebContents* iwc) {
|
||||||
[contentView viewDidMoveToWindow];
|
[contentView viewDidMoveToWindow];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BrowserWindow::OnDevToolsResized() {
|
||||||
|
UpdateDraggableRegions(draggable_regions_);
|
||||||
|
}
|
||||||
|
|
||||||
void BrowserWindow::UpdateDraggableRegions(
|
void BrowserWindow::UpdateDraggableRegions(
|
||||||
const std::vector<mojom::DraggableRegionPtr>& regions) {
|
const std::vector<mojom::DraggableRegionPtr>& regions) {
|
||||||
if (window_->has_frame())
|
if (window_->has_frame())
|
||||||
|
|
|
@ -1481,6 +1481,11 @@ void WebContents::DevToolsClosed() {
|
||||||
Emit("devtools-closed");
|
Emit("devtools-closed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebContents::DevToolsResized() {
|
||||||
|
for (ExtendedWebContentsObserver& observer : observers_)
|
||||||
|
observer.OnDevToolsResized();
|
||||||
|
}
|
||||||
|
|
||||||
bool WebContents::OnMessageReceived(const IPC::Message& message) {
|
bool WebContents::OnMessageReceived(const IPC::Message& message) {
|
||||||
bool handled = true;
|
bool handled = true;
|
||||||
IPC_BEGIN_MESSAGE_MAP(WebContents, message)
|
IPC_BEGIN_MESSAGE_MAP(WebContents, message)
|
||||||
|
|
|
@ -590,6 +590,7 @@ class WebContents : public gin::Wrappable<WebContents>,
|
||||||
void DevToolsFocused() override;
|
void DevToolsFocused() override;
|
||||||
void DevToolsOpened() override;
|
void DevToolsOpened() override;
|
||||||
void DevToolsClosed() override;
|
void DevToolsClosed() override;
|
||||||
|
void DevToolsResized() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ElectronBrowserContext* GetBrowserContext() const;
|
ElectronBrowserContext* GetBrowserContext() const;
|
||||||
|
|
|
@ -25,6 +25,7 @@ class ExtendedWebContentsObserver : public base::CheckedObserver {
|
||||||
virtual void OnActivateContents() {}
|
virtual void OnActivateContents() {}
|
||||||
virtual void OnPageTitleUpdated(const base::string16& title,
|
virtual void OnPageTitleUpdated(const base::string16& title,
|
||||||
bool explicit_set) {}
|
bool explicit_set) {}
|
||||||
|
virtual void OnDevToolsResized() {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~ExtendedWebContentsObserver() override {}
|
~ExtendedWebContentsObserver() override {}
|
||||||
|
|
|
@ -17,12 +17,20 @@ class InspectableWebContentsViewMac;
|
||||||
|
|
||||||
using electron::InspectableWebContentsViewMac;
|
using electron::InspectableWebContentsViewMac;
|
||||||
|
|
||||||
|
@interface NSView (WebContentsView)
|
||||||
|
- (void)setMouseDownCanMoveWindow:(BOOL)can_move;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface ControlRegionView : NSView
|
||||||
|
@end
|
||||||
|
|
||||||
@interface ElectronInspectableWebContentsView : BaseView <NSWindowDelegate> {
|
@interface ElectronInspectableWebContentsView : BaseView <NSWindowDelegate> {
|
||||||
@private
|
@private
|
||||||
electron::InspectableWebContentsViewMac* inspectableWebContentsView_;
|
electron::InspectableWebContentsViewMac* inspectableWebContentsView_;
|
||||||
|
|
||||||
base::scoped_nsobject<NSView> fake_view_;
|
base::scoped_nsobject<NSView> fake_view_;
|
||||||
base::scoped_nsobject<NSWindow> devtools_window_;
|
base::scoped_nsobject<NSWindow> devtools_window_;
|
||||||
|
base::scoped_nsobject<ControlRegionView> devtools_mask_;
|
||||||
BOOL devtools_visible_;
|
BOOL devtools_visible_;
|
||||||
BOOL devtools_docked_;
|
BOOL devtools_docked_;
|
||||||
BOOL devtools_is_first_responder_;
|
BOOL devtools_is_first_responder_;
|
||||||
|
|
|
@ -11,6 +11,18 @@
|
||||||
#include "shell/browser/ui/inspectable_web_contents_view_mac.h"
|
#include "shell/browser/ui/inspectable_web_contents_view_mac.h"
|
||||||
#include "ui/gfx/mac/scoped_cocoa_disable_screen_updates.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
|
@implementation ElectronInspectableWebContentsView
|
||||||
|
|
||||||
- (instancetype)initWithInspectableWebContentsViewMac:
|
- (instancetype)initWithInspectableWebContentsViewMac:
|
||||||
|
@ -48,6 +60,9 @@
|
||||||
[self addSubview:contentsView];
|
[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.
|
// See https://code.google.com/p/chromium/issues/detail?id=348490.
|
||||||
[self setWantsLayer:YES];
|
[self setWantsLayer:YES];
|
||||||
|
|
||||||
|
@ -71,6 +86,14 @@
|
||||||
inspectableWebContentsView_->GetDelegate()->DevToolsFocused();
|
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 {
|
- (void)setDevToolsVisible:(BOOL)visible activate:(BOOL)activate {
|
||||||
if (visible == devtools_visible_)
|
if (visible == devtools_visible_)
|
||||||
return;
|
return;
|
||||||
|
@ -84,6 +107,12 @@
|
||||||
devtools_visible_ = visible;
|
devtools_visible_ = visible;
|
||||||
if (devtools_docked_) {
|
if (devtools_docked_) {
|
||||||
if (visible) {
|
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
|
// Place the devToolsView under contentsView, notice that we didn't set
|
||||||
// sizes for them until the setContentsResizingStrategy message.
|
// sizes for them until the setContentsResizingStrategy message.
|
||||||
[self addSubview:devToolsView positioned:NSWindowBelow relativeTo:nil];
|
[self addSubview:devToolsView positioned:NSWindowBelow relativeTo:nil];
|
||||||
|
@ -94,7 +123,9 @@
|
||||||
} else {
|
} else {
|
||||||
gfx::ScopedCocoaDisableScreenUpdates disabler;
|
gfx::ScopedCocoaDisableScreenUpdates disabler;
|
||||||
[devToolsView removeFromSuperview];
|
[devToolsView removeFromSuperview];
|
||||||
|
[devtools_mask_ removeFromSuperview];
|
||||||
[self adjustSubviews];
|
[self adjustSubviews];
|
||||||
|
[self notifyDevToolsResized];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
|
@ -182,7 +213,7 @@
|
||||||
NSView* devToolsView = [[self subviews] objectAtIndex:0];
|
NSView* devToolsView = [[self subviews] objectAtIndex:0];
|
||||||
NSView* contentsView = [[self subviews] objectAtIndex:1];
|
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_devtools_bounds;
|
||||||
gfx::Rect new_contents_bounds;
|
gfx::Rect new_contents_bounds;
|
||||||
|
@ -191,6 +222,28 @@
|
||||||
&new_devtools_bounds, &new_contents_bounds);
|
&new_devtools_bounds, &new_contents_bounds);
|
||||||
[devToolsView setFrame:[self flipRectToNSRect:new_devtools_bounds]];
|
[devToolsView setFrame:[self flipRectToNSRect:new_devtools_bounds]];
|
||||||
[contentsView setFrame:[self flipRectToNSRect:new_contents_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 {
|
- (void)setTitle:(NSString*)title {
|
||||||
|
|
|
@ -19,6 +19,7 @@ class InspectableWebContentsViewDelegate {
|
||||||
virtual void DevToolsFocused() {}
|
virtual void DevToolsFocused() {}
|
||||||
virtual void DevToolsOpened() {}
|
virtual void DevToolsOpened() {}
|
||||||
virtual void DevToolsClosed() {}
|
virtual void DevToolsClosed() {}
|
||||||
|
virtual void DevToolsResized() {}
|
||||||
|
|
||||||
// Returns the icon of devtools window.
|
// Returns the icon of devtools window.
|
||||||
virtual gfx::ImageSkia GetDevToolsWindowIcon();
|
virtual gfx::ImageSkia GetDevToolsWindowIcon();
|
||||||
|
|
Loading…
Reference in a new issue