Skip to content

Commit 51bced4

Browse files
trop[bot]zcbenz
andauthored
fix: make draggable regions work when devtools is opened on macOS (electron#26395)
* fix: make draggable region work when devtools is open * fix: update draggable regions when resizing Co-authored-by: Cheng Zhao <zcbenz@gmail.com>
1 parent b0fd7cf commit 51bced4

8 files changed

+78
-20
lines changed

shell/browser/api/electron_api_browser_window.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ class BrowserWindow : public BaseWindow,
6363
void OnActivateContents() override;
6464
void OnPageTitleUpdated(const base::string16& title,
6565
bool explicit_set) override;
66+
#if defined(OS_MAC)
67+
void OnDevToolsResized() override;
68+
#endif
6669

6770
// NativeWindowObserver:
6871
void RequestPreferredWidth(int* width) override;

shell/browser/api/electron_api_browser_window_mac.mm

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,9 @@
1212
#include "base/mac/scoped_nsobject.h"
1313
#include "shell/browser/native_browser_view.h"
1414
#include "shell/browser/native_window_mac.h"
15+
#include "shell/browser/ui/cocoa/electron_inspectable_web_contents_view.h"
1516
#include "shell/browser/ui/inspectable_web_contents_view.h"
1617

17-
@interface NSView (WebContentsView)
18-
- (void)setMouseDownCanMoveWindow:(BOOL)can_move;
19-
@end
20-
21-
@interface ControlRegionView : NSView
22-
@end
23-
24-
@implementation ControlRegionView
25-
26-
- (BOOL)mouseDownCanMoveWindow {
27-
return NO;
28-
}
29-
30-
- (NSView*)hitTest:(NSPoint)aPoint {
31-
return nil;
32-
}
33-
34-
@end
35-
3618
namespace electron {
3719

3820
namespace api {
@@ -54,6 +36,10 @@ - (NSView*)hitTest:(NSPoint)aPoint {
5436
[contentView viewDidMoveToWindow];
5537
}
5638

39+
void BrowserWindow::OnDevToolsResized() {
40+
UpdateDraggableRegions(draggable_regions_);
41+
}
42+
5743
void BrowserWindow::UpdateDraggableRegions(
5844
const std::vector<mojom::DraggableRegionPtr>& regions) {
5945
if (window_->has_frame())

shell/browser/api/electron_api_web_contents.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1471,6 +1471,11 @@ void WebContents::DevToolsClosed() {
14711471
Emit("devtools-closed");
14721472
}
14731473

1474+
void WebContents::DevToolsResized() {
1475+
for (ExtendedWebContentsObserver& observer : observers_)
1476+
observer.OnDevToolsResized();
1477+
}
1478+
14741479
bool WebContents::OnMessageReceived(const IPC::Message& message) {
14751480
bool handled = true;
14761481
IPC_BEGIN_MESSAGE_MAP(WebContents, message)

shell/browser/api/electron_api_web_contents.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@ class WebContents : public gin::Wrappable<WebContents>,
589589
void DevToolsFocused() override;
590590
void DevToolsOpened() override;
591591
void DevToolsClosed() override;
592+
void DevToolsResized() override;
592593

593594
private:
594595
ElectronBrowserContext* GetBrowserContext() const;

shell/browser/extended_web_contents_observer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class ExtendedWebContentsObserver : public base::CheckedObserver {
2525
virtual void OnActivateContents() {}
2626
virtual void OnPageTitleUpdated(const base::string16& title,
2727
bool explicit_set) {}
28+
virtual void OnDevToolsResized() {}
2829

2930
protected:
3031
~ExtendedWebContentsObserver() override {}

shell/browser/ui/cocoa/electron_inspectable_web_contents_view.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,20 @@ class InspectableWebContentsViewMac;
1717

1818
using electron::InspectableWebContentsViewMac;
1919

20+
@interface NSView (WebContentsView)
21+
- (void)setMouseDownCanMoveWindow:(BOOL)can_move;
22+
@end
23+
24+
@interface ControlRegionView : NSView
25+
@end
26+
2027
@interface ElectronInspectableWebContentsView : BaseView <NSWindowDelegate> {
2128
@private
2229
electron::InspectableWebContentsViewMac* inspectableWebContentsView_;
2330

2431
base::scoped_nsobject<NSView> fake_view_;
2532
base::scoped_nsobject<NSWindow> devtools_window_;
33+
base::scoped_nsobject<ControlRegionView> devtools_mask_;
2634
BOOL devtools_visible_;
2735
BOOL devtools_docked_;
2836
BOOL devtools_is_first_responder_;

shell/browser/ui/cocoa/electron_inspectable_web_contents_view.mm

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,18 @@
1111
#include "shell/browser/ui/inspectable_web_contents_view_mac.h"
1212
#include "ui/gfx/mac/scoped_cocoa_disable_screen_updates.h"
1313

14+
@implementation ControlRegionView
15+
16+
- (BOOL)mouseDownCanMoveWindow {
17+
return NO;
18+
}
19+
20+
- (NSView*)hitTest:(NSPoint)aPoint {
21+
return nil;
22+
}
23+
24+
@end
25+
1426
@implementation ElectronInspectableWebContentsView
1527

1628
- (instancetype)initWithInspectableWebContentsViewMac:
@@ -48,6 +60,9 @@ - (instancetype)initWithInspectableWebContentsViewMac:
4860
[self addSubview:contentsView];
4961
}
5062

63+
// This will float above devtools to exclude it from dragging.
64+
devtools_mask_.reset([[ControlRegionView alloc] initWithFrame:NSZeroRect]);
65+
5166
// See https://code.google.com/p/chromium/issues/detail?id=348490.
5267
[self setWantsLayer:YES];
5368

@@ -71,6 +86,14 @@ - (void)notifyDevToolsFocused {
7186
inspectableWebContentsView_->GetDelegate()->DevToolsFocused();
7287
}
7388

89+
- (void)notifyDevToolsResized {
90+
// When devtools is opened, resizing devtools would not trigger
91+
// UpdateDraggableRegions for WebContents, so we have to notify the window
92+
// to do an update of draggable regions.
93+
if (inspectableWebContentsView_->GetDelegate())
94+
inspectableWebContentsView_->GetDelegate()->DevToolsResized();
95+
}
96+
7497
- (void)setDevToolsVisible:(BOOL)visible activate:(BOOL)activate {
7598
if (visible == devtools_visible_)
7699
return;
@@ -84,6 +107,12 @@ - (void)setDevToolsVisible:(BOOL)visible activate:(BOOL)activate {
84107
devtools_visible_ = visible;
85108
if (devtools_docked_) {
86109
if (visible) {
110+
// The devToolsView is placed under the contentsView, so it has to be
111+
// draggable to make draggable region of contentsView work.
112+
[devToolsView setMouseDownCanMoveWindow:YES];
113+
// This view will exclude the actual devtools part from dragging.
114+
[self addSubview:devtools_mask_.get()];
115+
87116
// Place the devToolsView under contentsView, notice that we didn't set
88117
// sizes for them until the setContentsResizingStrategy message.
89118
[self addSubview:devToolsView positioned:NSWindowBelow relativeTo:nil];
@@ -94,7 +123,9 @@ - (void)setDevToolsVisible:(BOOL)visible activate:(BOOL)activate {
94123
} else {
95124
gfx::ScopedCocoaDisableScreenUpdates disabler;
96125
[devToolsView removeFromSuperview];
126+
[devtools_mask_ removeFromSuperview];
97127
[self adjustSubviews];
128+
[self notifyDevToolsResized];
98129
}
99130
} else {
100131
if (visible) {
@@ -182,7 +213,7 @@ - (void)adjustSubviews {
182213
NSView* devToolsView = [[self subviews] objectAtIndex:0];
183214
NSView* contentsView = [[self subviews] objectAtIndex:1];
184215

185-
DCHECK_EQ(2u, [[self subviews] count]);
216+
DCHECK_EQ(3u, [[self subviews] count]);
186217

187218
gfx::Rect new_devtools_bounds;
188219
gfx::Rect new_contents_bounds;
@@ -191,6 +222,28 @@ - (void)adjustSubviews {
191222
&new_devtools_bounds, &new_contents_bounds);
192223
[devToolsView setFrame:[self flipRectToNSRect:new_devtools_bounds]];
193224
[contentsView setFrame:[self flipRectToNSRect:new_contents_bounds]];
225+
226+
// Move mask to the devtools area to exclude it from dragging.
227+
NSRect cf = contentsView.frame;
228+
NSRect sb = [self bounds];
229+
NSRect devtools_frame;
230+
if (cf.size.height < sb.size.height) { // bottom docked
231+
devtools_frame.origin.x = 0;
232+
devtools_frame.origin.y = 0;
233+
devtools_frame.size.width = sb.size.width;
234+
devtools_frame.size.height = sb.size.height - cf.size.height;
235+
} else { // left or right docked
236+
if (cf.origin.x > 0) // left docked
237+
devtools_frame.origin.x = 0;
238+
else // right docked.
239+
devtools_frame.origin.x = cf.size.width;
240+
devtools_frame.origin.y = 0;
241+
devtools_frame.size.width = sb.size.width - cf.size.width;
242+
devtools_frame.size.height = sb.size.height;
243+
}
244+
[devtools_mask_ setFrame:devtools_frame];
245+
246+
[self notifyDevToolsResized];
194247
}
195248

196249
- (void)setTitle:(NSString*)title {

shell/browser/ui/inspectable_web_contents_view_delegate.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class InspectableWebContentsViewDelegate {
1919
virtual void DevToolsFocused() {}
2020
virtual void DevToolsOpened() {}
2121
virtual void DevToolsClosed() {}
22+
virtual void DevToolsResized() {}
2223

2324
// Returns the icon of devtools window.
2425
virtual gfx::ImageSkia GetDevToolsWindowIcon();

0 commit comments

Comments
 (0)